Static Google Maps coordinate projection
4 months ago
Static Google Maps coordinate projection
Do you want to project coordinates to the screen when using the Google Maps Static API?
Google Maps already provide customizing of static maps to an extent and in most cases, I would say what's available is more than enough. For example, you can render: different map types, markers (also with custom icons!), and even paths!
However, there are cases where you might still want/need to use the Static API:
- You want to conceal the coordinates.
- You want nothing but simplicity.
Maybe the Static Maps API has all you actually need but all you want to do is anchor a button or interactable label at a specific coordinate.
Click anywhere on the map to open the coordinate.
So, if you do want to project a world coordinate to a screen coordinate, there's three steps we have to take:
- Calculating coordinates to world coordinates
- Calculating world coordinates to pixel coordinates
- Calculating and applying the pixel coordinates
First we need to translate our latitude and longitude coordinates into world coordinates according to the Mercator projection.
The Mercator projection is what Google uses to translate all coordinates input into the API to world coordinates.
Before we can apply our coordinates, they need to be scaled to our zoom level - which is what pixel coordinates are.
With all calculations at hand, we need to apply them for our scenario!
This is great for when we want to anchor an overlaying element on our map, but what about calculating coordinates from a mouse click?
Then we have to reverse the entire process, starting with reversing the pixel coordinates to world coordinates to coordinates.
Calculating the pixel coordinates
Given that on a regular request we can only input a search string or a coordinate - as the center of the map, the zoom level, and the canvas size; we have to use these 3 properties to make a calculation that aligns with the API's.
If you're working with search inputs, you should do the geocoding yourself, so that you're only working with coordinates with the Static Maps API. This is to ensure both the API and you are working with the same center.
This is the request example I'll be working with in this article:
It's a 250x250 map of Vänersborg, Sweden at zoom level 15.
Google provides fantastic transparent documentation on how their coordinates are calculated and I'll be using this as a reference going forwards.
Understanding the viewport
Not to be confused with the visible viewport definition.
Before we can start, it's important that we understand how the viewport of the map works with dependency to the size parameter.
For example, this is a hypothetical example of a 100x100 map:
And this is the same hypothetical map but sized 200x100:
As you can tell, the map expands by the size, anchored by the center.
This is because the map projection that Google Maps uses for translating coordinates to world coordinates is the Mercator projection.
With the Mercator projection, Google Maps then uses tile sizes relative to the zoom level to expand the map centered by our coordinates by the size.
We can calculate what tile size Google uses at what zoom level by multiplying the zoom level by 256:
Calculating coordinates to world coordinates
We need to convert our coordinates to world coordinates using the Mercator projection ourselves, this is so that we can use the Mercator world coordinates to get our pixel coordinates.
Using the Mercator projection, we can input our coordinates and get the world coordinates based on our zoom level's tile size:
Calculating world coordinates to pixel coordinates
Now that we have our world coordinates, we have to take the zoom level into account. Using the expression given to us in the Google Maps documentation:
We can apply this to our world coordinates through an expontential function:
Calculating and applying the pixel coordinates
With the pixel coordinates at hand, we can subtract them with the center pixel coordinates and then add our map's half size:
With all 3 sections combined, this would be the full code:
Reversing screen coordinates to coordinates
If we want to do the opposit - translate a pixel on the map to coordinates, we have to go through the same process as above, but in the reversed order.
This is useful if for example, you only want to capture a latitude and longitude click on your static map.
Reverting screen coordinates to pixel coordinates
First we need to revert our click event's offset with our map's half width and height, which would give us the relative pixel coordinates.
Going forwards, we'll assume the screen coordinates we want to reverse is coming from a mouse event:
Now that we have the relative pixel coordinate - based on the pixel coordinates of the center of our map, we need to calculate our map's center pixel coordinates again.
If we now add our relative pixel coordinates to the center pixel coordinates, we now have an absolute pixel coordinate of our click event:
We can use the exact same code as before to get the center pixel coordinates and now use our 2 new functions:
Calculating screen coordinates to world coordinates
Reusing the formula given to us in the Google Maps documentation, we can use it again but this time to divide our pixel coordinates with the scale:
Calculating world coordinates to coordinates
Now that we have the world coordinates of our click, we need to reverse the Mercator world coordinate projection to get the actual coordinates.
With all the pieces put together, this is how you'd calculate the screen coordinates to coordinates: