# Deriving Geographical Coordinates from Map Projections

## Oct 28, 2023

Given a flat projection of a world map, and an x/y coordinate on that projection, how can we derive the latitude/longitude on the globe?

I wanted to create a simple Minecraft plugin which would allow players on an Earth map to get an accurate lat/long for their position in the real world.

There are many different ways to project a spherical map onto a flat plane, but this inevitably results in some degree of distortion. The projection used for the Earth map is close to a Mercator projection. You can compare this projection with other projections at map-projections.net, you will notice significant differences around Greenland and the islands in northern Canada especially.

Due to this distortion, the relationship between x/y and lat/long is not linear - a user walking 100 blocks north in the Minecraft map through Africa will cover more latitude than a 100 block walk in Greenland, because the projection of Greenland is stretched more than the projection of Africa.

With some simple maths and some time spent gathering data, we can account for this distortion and still map x/y to lat/long accurately. To start with, we must create a series of anchor points encompassing the area we care about. In this example, let's look at how we can do this within Ireland.

The next step is to gather the real-world lat/long coordinates for each of these anchor points. Doing this will give us a relationship between the x/y coordinate of the anchor point, and the (approximate) lat/long of that anchor point in the real world.

Then, we must create a set of triangles using these points. I use the Locationtech JTS Topology Suite to do this automatically from the set of points.

The last step is to take the x/y position (the position of our player) and find the containing triangle for that point. We can then find the barycentric coordinates within that triangle and interpolate using the position within the triangle, and the latitude/longitude attached to the three anchor points which make up the triangle.

In simpler terms, we find the position within the triangle, then we combine the lat/long of the three anchor points based on how far the point is from each of those anchors. The closer we are to an anchor point, the more weighting is applied to the lat/long from that anchor. In the example above, you can see that we are very close to `(54.45, -5.48)` and less close to `(53.43, -10.14)` and `(52.19, -6.35)`, so the combination of these three lat/long pairs will be weighted accordingly to give us the approximate lat/long of the blue point.

You can also see, from this small example, a few points of note:

• The area we care about should be completely surrounded by anchors - the southwest corner of Ireland is not currently covered by an anchor point. It's very possible that a player standing here will be within a triangle made up of `(52.42, -9.92)`, `(51.48, -9.78)`, and some third point on the east coast of America. Interpolating within a triangle of such size is difficult and will likely return a lat/long within the Atlantic Ocean.
• Anchors should also be placed inland, and not only around the coast. This is less important with small landmasses, or landmasses with simple coastal geography, but large areas should have a number of anchor points set inland in order to give accurate results.
• A higher concentration of anchor points will generally lead to more accurate results, as the triangles will be smaller.

Overall, for a 30,000x15,000 block Minecraft Earth map I used around 500 anchor points. This gives a "good enough" result but there are still a number of areas which aren't covered appropriately and simply tell the player "I don't know where you are". As you can imagine, it's quite time intensive to place 500 points with matching lat/long coordinates, so improving this dataset will be a slow process over time.

## Like my blog? Try my game!

Creature Chess is a lofi chess battler

It's free, you can play it from your browser, and a game takes 10 minutes

Play Creature Chess

Find my other work on Github @jameskmonger