Converting latitude and longitude coordinates to map x and y values

Published May 19th, 2009

I’m currently working on a project to convert an existing Flash map, which uses location data that’s been manually entered and maintained, to use data that comes from a database and uses latitude and longitude values. The original data is stored in an XML file so updating it dynamically is not a problem but as you’ll know if you’ve ever tried it, plotting latitude and longitude values on a map isn’t as simple as it might sound.

Briefly, the problem arises from the fact that the world is a sphere and representing it in two dimensions is not a straightforward task. There are various ‘projections’ to choose from, each of which uses a different method for mapping points — you can find out more in this Wikipedia article. The most common choice is the Mercator projection, where lines of latitude are spaced equally, and fortunately for me it’s the type of map used in the project I’m working on.

So, being somewhat mathematically inept, I decided that Google would save me from a day’s head-scratching. That turned out not to be the case, as I tried a good half-dozen different suggestions before finally stumbling across one that actually produced accurate results. To save others from the same fate I decided to reproduce here the code I ended up with, which is based heavily on code found in this newsgroup post. My implementation is PHP, but it shouldn’t be hard to convert it to another platform (see the original thread for a Javascript implementation). Apologies for the rubbish formatting, WordPress isn’t great at handling code:

function LongitudeToX( $lat, $lon, $map_zoom, $scale_value, $x_offset = 0 )
{
  $offset=16777216;
  $radius=$offset / pi();
  return ( ( ($offset+$radius*$lon*pi()/180)>>$map_zoom ) * $scale_value ) + $x_offset;
}
function LatitudeToY( $lat, $lon, $map_zoom, $scale_value, $y_offset = 0 )
{
  $offset=16777216;
  $radius=$offset / pi();
  return ( ( ($offset-$radius*log((1+sin($lat*pi()/180))/(1-sin($lat*pi()/180)))/2)>>$map_zoom ) * $scale_value ) + $y_offset;
}

A few notes about using these functions:

  • From what I can tell, the above code is based on Google Maps and the $map_zoom relates in some way to the ‘zoom level’ of the map. I set it at 15 and it seemed to work OK.
  • Because the dimensions of your own map might not exactly match the assumed dimensions of the map used in the calculation, the $scale_value parameter allows you to adjust the output to fit more precisely. I had to specify two decimal places of scaling to get an exact fit.
  • Finally, the calculation assumes that the ‘origin point’ of the map (x=0, y=0) will be at the top, left-hand corner. This isn’t the case on the map I’m working on (the origin is at the centre) so I included $x_offset and $y_offset parameters so that I could adjust the output values accordingly.

In order to find the best values for the above parameters, I manually placed three widely-spaced temporary markers on the Flash map marking points whose latitude and longitude I already knew. Then I had the code render these points and adjusted the various parameters until the position of the generated points exactly matched the manually-placed markers.

I hope this code helps someone avoid wasting the sort of time I did yesterday!

Get a Trackback link

5 Comments

  1. A Hospitalist on November 3, 2009

    Yes it did save someone else some time! Thanks. We are doing a hospital mapping project to track down hospitalist openings and all the city data is only available in Long and Lat.

  2. Baron Ruhstoff (12s Army unite!) on December 15, 2009

    Hey, thanks for this. I’ve been doing a bit of mapwork lately and can think of a bunch of ways it will be helpful!

  3. Ela on July 8, 2010

    Hi,

    Thanks for the code that you provided, actually am trying many methods including yours unfortunately i couldn’t able to reach what really i have to do.

    In your code how you define these values $map_zoom, $scale_value, $x_offset. I mean based on what measurement you are assigning values to these. Please help me I need to develop a mapping tool using the same Mercator projection, for INDIA alone. When am checking it for world map its working but in what way i can specify $map_zoom, $scale_value, $x_offset to use this code in India alone. Please help me in this problem.

    Thanks in advance.

  4. Ela on July 8, 2010

    Hi again,
    For example i am calling the functions
    echo $x = LongitudeToX(9.3875333333333,77.902,1,1);
    echo $y = LatitudeToY(9.3875333333333,77.902,1,1);
    and am getting these results.
    12019104
    7949146
    Mt image width is just 800 width and 400 height. India map alone. how this value can be fit into the x and y on the image. Please help me

  5. Ela on July 8, 2010

    Hi,

    I need your help… Whats the image width and height and all. I dont know how to place the x and y value that is got from your formula. Can you help me out of it?

Leave a comment

Comment Policy: First time comments are moderated. Please be patient.

OpenID

Anonymous