17
votes

I have the Lat/Long value of New York City, NY; 40.7560540,-73.9869510 and a flat image of the earth, 1000px × 446px.

I would like to be able to convert, using Javascript, the Lat/Long to an X,Y coordinate where the point would reflect the location.

So the X,Y coordinate form the Top-Left corner of the image would be; 289, 111

Things to note:

  1. don't worry about issues of what projection to use, make your own assumption or go with what you know might work
  2. X,Y can be form any corner of the image
  3. Bonus points for the same solution in PHP (but I really need the JS)
3
There's a good Javascript library, PROJ4JS, that allows you to do transformations between different projections.andri
"Don't worry about ... what projection to use" how then do we know what the X Y co-ord mapping will be? I could have just said X is Lat, Y is Long and that probably would have satisfied you since apparently the result doesn't need to mean anything or relate to a real world projection.1owk3y

3 Answers

8
votes

A basic conversion function in js would be:

MAP_WIDTH = 1000;
MAP_HEIGHT = 446;

function convert(lat, lon){
    var y = ((-1 * lat) + 90) * (MAP_HEIGHT / 180);
    var x = (lon + 180) * (MAP_WIDTH / 360);
    return {x:x,y:y};
}

This will return the number of pixels from upper left. This function assumes the following:

  1. That your image is properly aligned with the upper left corner (0,0) aligning with 90* North by 180* West.
  2. That your coords are signed with N being -, S being +, W being - and E being +
18
votes

The projection you use is going to change everything, but this will work assuming a Mercator projection:

<html>
<head>
<script language="Javascript">
var dot_size = 3;
var longitude_shift = 55;   // number of pixels your map's prime meridian is off-center.
var x_pos = 54;
var y_pos = 19;
var map_width = 430;
var map_height = 332;
var half_dot = Math.floor(dot_size / 2);
function draw_point(x, y) {
    dot = '<div style="position:absolute;width:' + dot_size + 'px;height:' + dot_size + 'px;top:' + y + 'px;left:' + x + 'px;background:#00ff00"></div>';
    document.body.innerHTML += dot;
}
function plot_point(lat, lng) {
    // Mercator projection

    // longitude: just scale and shift
    x = (map_width * (180 + lng) / 360) % map_width + longitude_shift;

    // latitude: using the Mercator projection
    lat = lat * Math.PI / 180;  // convert from degrees to radians
    y = Math.log(Math.tan((lat/2) + (Math.PI/4)));  // do the Mercator projection (w/ equator of 2pi units)
    y = (map_height / 2) - (map_width * y / (2 * Math.PI)) + y_pos;   // fit it to our map

    x -= x_pos;
    y -= y_pos;

    draw_point(x - half_dot, y - half_dot);
}
</script>
</head>
<body onload="plot_point(40.756, -73.986)">
    <!-- image found at http://www.math.ubc.ca/~israel/m103/mercator.png -->
    <img src="mercator.png" style="position:absolute;top:0px;left:0px">
</body>
</html>
0
votes

If you have a picture of the whole earth, the projection does always matter. But maybe I just don't understand your question.