Kathandrax
Kathandrax

Reputation: 1054

Leaflet: misalignment of tiles and negative y coordinates

I am trying to generate a custom non-geographical map with Leaflet using my own tiles.

For the moment I created 10x10 dummy tiles of size 256x256px each with a random solid color using imagemagick. They are placed in public/map-tiles/1/map_x_y.png where x takes values from 0 to 9 (resp. y).

Since this is a non-geographical map, I paid attention to change crs to L.CRS.Simple (see http://leafletjs.com/examples/crs-simple/crs-simple.html):

var map = L.map('map', {
  minZoom: 1,
  maxZoom: 1,
  center: [0, 0],
  crs: L.CRS.Simple
}).setView([0, 0], 1);

L.tileLayer('/map-tiles/{z}/map_{x}_{y}.png', {
    bounds: [[0, 0], [2560, 2560]],
    tms: true
}).addTo(map);

However this produces tiles slightly shifted and thus misaligned:

misaligned tiles

Also, tiles with negative y coordinates are fetched, which results in 404d requests, as seen in the console.

What can be the cause of this behavior?

EDIT 1: as IvanSanchez pointed out, the misalignment was caused by the missing leaflet.css stylesheet.

I still have the problem with negative coordinates. As suggested, I added bounds (see updated code above). Observations:

EDIT 2: after several tests it looks like the negative tiles are indeed the product of the y-axis handling (http://leafletjs.com/examples/wms/wms.html). The origin is top left, y going downward. I expected the tiles below the origin to be fetched, not above.

What I tried in order to keep my convention with x and y both increasing (that is x increases to the right, y increases downward, tiles with positive coordinate components are fetched from 0 to 9):

Upvotes: 2

Views: 3592

Answers (2)

Kathandrax
Kathandrax

Reputation: 1054

The problem boils down to two aspects:

  • misalignment: the leaflet.css stylesheet was missing and simply needed to be linked to in the HTML of the page.
  • negative tiles fetched: for Leaflet the y-axis goes downward. I expected tiles to be fetched from left to right, top to bottom with an origin set to the top left corner. Instead, negative y's were fetched. Since my tiles' names are map_x_y.png where x and y take values in {0:9}, this resulted in 404d requests. Setting negative bounds fixed the issue with bounds: [[0,0],[-1230,1230]] (notice the minus sign). 1230 corresponds to the number of tiles at zoom 0 times the size in pixel of one tile.

Upvotes: -1

IvanSanchez
IvanSanchez

Reputation: 19069

In a map with L.CRS.Simple, all TileLayers have infinite bounds by default.

If you want a TileLayer to request tiles only in a given area, read the Leaflet API documentation, specifically a TileLayer option named bounds (inherited from GridLayer options). Let me quote:

bounds
type LatLngBounds
default undefined
If set, tiles will only be loaded inside the set LatLngBounds.

You also mention:

Weirdly enough, it tries to fetch tiles with negative coordinates [...]

That's not weird, it's behaviour as designed. There is nothing inherently wrong (nor weird) with negative coordinates, and negative tile coordinates are valid and documented in some tile standards


So if you have 10x10 tiles of 256px in size ranging from [0, 0] to [10, 10], you might want something like

L.tileLayer('/map-tiles/map_{x}_{y}.png', {
  bounds: [[0, 0], [2560, 2560]]
}).addTo(map);

If the center of your data is the [0, 0] point and your tiles span from [-5, -5] to [5, 5] you might instead want something like

L.tileLayer('/map-tiles/map_{x}_{y}.png', {
  bounds: [[-1280, -1280], [1280, 1280]]
}).addTo(map);

Upvotes: 4

Related Questions