Latitude Longitude to XY – Converting Latitude and Longitude to XY Coordinates

coordinate systemgeometryjavascriptmapping

I am doing a JavaScript application that requires the movement of a certain element in a real world map, in frames.

For each frame, I have the following positions in latitude and longitude for the element, for example for frame 0:
– Latitude: 49.011213
– Longitude: 8.422885

For frame 1:
– Latitude: 49.01121
– Longitude: 8.422887

Frame (Frame 0) needs to be point (0,0) and I want the following ones to be converted to XY coordinates as well.

Basically, I need a JavaScript script that receives the latitude and longitude of a frame and returns the position (x,y) for that frame (in relation to frame 0 with position (0,0)).

I've tried the following but it doesn't work:

function convertSphericalToCartesian(latitude, longitude)
{
    // Convert from Degrees to Radians
    let latRad = latitude * (Math.PI)/180; 
    let lonRad = longitude * (Math.PI)/180;

    let earthRadius = 6367; // Radius in km
    let posX = earthRadius * Math.cos(latRad) * Math.cos(lonRad);
    let posY = earthRadius * Math.cos(latRad) * Math.sin(lonRad);
    return {x: posX, y: posY};
}

Do you know a better formula for this?

Best Answer

You need the bearing, which is the angle from point 1 point 2 on the surface of the globe. You can get that from turf.js, a powerful GIS calculation library.

Then you need a distance formula, to get the distance on the surface of the globe between the two points. Again, turf.js has a distance function.

Once you have the bearing and the distance, you've basically turned this into a 2D cartesian coordinates problem. Now you need to pick your units of x and y. What is a unit of x / y? 1 meter? 1 km? Lets say we that 1 unit of x or y is equal to 1 meter. If you find that point 2 is 35m away from point 1, with a bearing of 90 degrees, you know that the xy coordinates of point 2 would be (0,35), assuming `(0,0) for point 1. If point 2 is 1.4km away from point 1, with a bearing of 32 degrees, point 2's xy coords can be calculated with some simple trig: ( 1400 * cos(32) , 1400 * sin(32) ).

So a js function might look like this:

function getCoordsOfNextPoint( firstPoint, nextPoint, prevXY = {x: 0, y: 0} ) {

  const bearing = turf.bearing(firstPoint, nextPoint);
  const distance = turf.distance(firstPoint, nextPoint, {units: 'kilometers'});

  const xy = {
    x:  prevXY.x + distance * 1000 * Math.cos(bearing * Math.PI / 180),
    y:  prevXY.y + distance * 1000 * Math.sin(bearing * Math.PI / 180)
  }

  return xy

}

const myFirstPoint = [-75.343, 39.984]
const mySecondPoint = [-75.534, 39.123]
const secondPointXYCoords = getCoordsOfNextPoint(myFirstPoint, mySecondPoint)

You may want to tweak the units or parameters. Also watch out for the conventions on the units of what the bearing function returns, that can trip you up. (I know its tripped me up in the past). Turf is super powerful, definitely worth looking into.

Edit: stringing points together

To get from point 0 to point 1, you won't need the extra parameter prevXY. But every point after that will take the point returned by the function used for the 2 points before it. For example:

// Assuming x0y0 = { x: 0, y: 0}

const x1y1 = secondPointXYCoords = getCoordsOfNextPoint(myFirstPoint, mySecondPoint)
const x2y2 = secondPointXYCoords = getCoordsOfNextPoint(myFirstPoint, mySecondPoint, x1y1)
const x3y3 = vsecondPointXYCoords = getCoordsOfNextPoint(myFirstPoint, mySecondPoint, x2y2)

And you could write a loop to read your latlng points from an array and write to another array of xy points, which will basically translate your latlng points to xy points.

Hopefully that gets your started.