[Math] Latitude/Longitude XY conversion

coordinate systems

I'm currently working on a programming application trying to render OpenStreetMap data. I have a whole load of map data with the (lat,lon) coordinates for each point. I also have a grid/screen, or otherwise canvas if you're familiar with HTML5. The canvas can be any size, and it has integer height and width values.

My application sets a centre (lat,lon) position, and needs to render all the map data around it. Therefore I will have an (lat,lon) coordinate correspond exactly to a (x,y) coordinate – the (x,y) coordinate being (width / 2, height / 2).

My problem is calculating the (x,y) coordinates for the other (lat,lon) coordinates, taking into account the curvature of the earth. Obviously a scale is required so I'm working off a value of degrees per pixel.

My working algorithm at the moment is:

var lat = 51.5074; // London
var lon = 0.1278;
var dpp = 0.00009;
var center_x = canvas.width() / 2;
var center_y = canvas.height() / 2;
function get_xy(pos_lat, pos_lon) {
return {
x : center_x + ((pos_lon - lon) / dpp),
y : center_y - ((pos_lat - lat) / dpp)
};
};

This works but does not take into account the curvature and so everything is slightly skewed along the latitude lines.

Also please note, the (0,0) x/y position is top left.

Could somebody suggest a more complete equation or algorithm to use?

Thanks in advance!

Best Answer

As has already been noted in comments, the real solution to your problem is to research map projections, choose an appropriate projection, and use that projection to convert latitude and longitude to points on your display. However, for small areas of the earth's surface, a simple "flat earth" approximation might be sufficient.

The major problem with your code is that the length of a degree of latitude is not the same as the length of a degree of longitude, except at the equator. If you move one degree north, you move the same distance regardless of your location: 1/360th of the length of a great circle. But if you move one degree west, you have moved a shorter distance depending on your latitude, because you are moving on a "small circle" instead of a great circle. If you are near the north pole then the radius of this small circle is much less than the radius of a great circle. The only exception is if you are at the equator, and then the "small circle" is actually a great circle. So how to compensate?

If your latitude is $\phi$, where $\phi = 0^\circ$ at the equator and $\phi = 90^\circ$ at the north pole, then the radius of the small circle through your location is $R \cos \phi$, where $R$ is the radius of the earth. The radius of a great circle is $R$. If you move one degree north then you have moved a distance of $2 \pi R / 360$, whereas if you move one degree west you have moved a distance of $(2 \pi R \cos \phi)/360$. In your code, a pixel corresponds to some measure of distance, so "degrees per pixel" is inversely proportional to distance; but the distance per degree is different in the X and Y directions, as explained above. So to compensate, you should divide the degrees per pixel in the X direction by $\cos \phi$. Note that the cosine function in most programming languages requires an angle in radians, so you may need to convert degrees to radians before computing the cosine.

Related Question