How are the bounds calculated in the Leaflet CRS.Simple tutorial?

Tags: ,



In the example in Leaflet (for non geographic image), they set “bounds”. I am trying to understand how they computed the values

var bounds = [[-26.5,-25], [1021.5,1023]]; 

The origin is bottom-left and y increases upwards / x towards the right. How did negative numbers turn up here? Also, after experimentation, I see that the actual pixel coordinates change if you specify different coordinates for bounds. I have a custom png map which I would like to use but I am unable to proceed due to this.

Answer

Oh, you mean this image:

Ur-Quan masters map

If you open the full file (available at https://github.com/Leaflet/Leaflet/blob/v1.4.0/docs/examples/crs-simple/uqm_map_full.png ) with an image editor, you’ll see that it measures 2315×2315 pixels. Now, the pixel that represents the (0,0) coordinate is not at a corner of the image, but rather 56 pixels away from the lower-left corner of the image:

GIMP view of lower-left corner

Similarly, the (1000, 1000) coordinate is about 48 pixels from the top-right corner of the image:

GIMP view of upper-right corner

Therefore, if we measure pixel coordinates of the grid corners:

Game coordinate (0, 0) → Pixel coordinate (59, 56)
Game coordinate (1000, 1000) → Pixel coordinate (2264, 2267)

The problem here is finding the bounds (measured in game coordinates) of the image. Or, in other words:

Pixel coordinate (0, 0) → Game coordinate (?, ?)
Pixel coordinate (2315, 2315) → Game coordinate (?, ?)

We know that the pixel-to-game-coordinate ratio is constant, we know the image size and the distance to the coordinates grid, so we can infer stuff:

1000 horizontal game units = image width - left margin - right margin

or

1000 horizontal game units = 2315px - 56px - 48px = 2213px

therefore the pixel/game unit ratio is

2213px / 1000 game units = 2.213 px/unit

therefore the left margin is…

~59px = ~59px / (2.213px/unit) ~= 26.66 game units

…therefore the left edge of the image is at ~ -26.66 game units. Idem for the right margin…

~51px = ~51px / (2.213px/unit) = ~23.04 game units

…therefore the right edge of the image is at ~1023.04 game units

Repeating that for the top and bottom margins we can fill up all the numbers:

Pixel coordinate (0, 0) → Game coordinate (-26.66, -25)
Pixel coordinate (2315, 2315) → Game coordinate (1023.04, 1025)

Why don’t these numbers match the ones in the example exactly? Because I might have used a different pixel for measurement when I wrote that Leaflet tutorial. Still, the error is negligible.

Let me remark a sentence from that tutorial:

One common mistake when using CRS.Simple is assuming that the map units equal image pixels. In this case, the map covers 1000×1000 units, but the image is 2315×2315 pixels big. Different cases will call for one pixel = one map unit, or 64 pixels = one map unit, or anything. Think in map units in a grid, and then add your layers (L.ImageOverlays, L.Markers and so on) accordingly.

If you have your own game map (or anything else), you should ask yourself: Where is the (0,0) coordinate? What are the coordinates of the image edges in the units I’m gonna use?



Source: stackoverflow