Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 829
semantic_c0d3r Avatar asked Feb 21 '19 21:02

semantic_c0d3r


1 Answers

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 2315x2315 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 1000x1000 units, but the image is 2315x2315 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?

like image 73
IvanSanchez Avatar answered Sep 20 '22 16:09

IvanSanchez