2

I have a list of stores described by their coordinates (latitude, longitude) and I need to parse them on my custom world map as markers (with css absolute positioning). Google map and other libraries (jVector map and similar) are not a solution. I've found some formulas to convert the lat/lon to pixel left/right values to be used for the markers, but the conversion seems not accurate.

You can see a demo clicking here. The red bullet should be Rome, and the green one should be Rio de Janeiro as example. Both are not where they should be, and the "wrong offset" is not always the same from marker to marker (in other words: adding a translateX(-XXpx) won't fix all of them).

There is clearly something I'm missing, and I'm quite sure that I should setup the map image in some way that I don't know and don't understand. Does anyone can help?

Thanks in advance, here's the relevant code of the demo:

<div id="map" style="width: 800px;margin:100px;auto;position:relative;background-color:#dedede;">
    <img src="map.svg" style="width:100%;">
</div>
<script>
    var map = document.getElementById('map');
    var stores = [
        {
            "name": "Rome",
            "n": 10,
            "lat": 41.9097306,
            "lng": 12.2558141,
            "fill": "red"
        },
        {
            "name": "Rio di Janeiro",
            "n": 5,
            "lat": -22.9138851,
            "lng": -43.7261746,
            "fill": "green"
        }
    ];
    stores.forEach(element => {
        var pos = coordToPixel(element.lat,element.lng);
        var marker = document.createElement('div');
        marker.className = 'marker';
        marker.style.left = pos.x+'px';
        marker.style.top = pos.y+'px';
        marker.style.backgroundColor = element.fill;
        map.appendChild(marker);
    });
    function coordToPixel(lat,lng)
    {
        var MAP_WIDTH = 800,
            MAP_HEIGHT = 444
            ;
        var x = ((lng+180)*MAP_WIDTH/360),
            y = ((90-lat)*MAP_HEIGHT/180)
            ;
        return {x,y}
    }
</script>
btb84
  • 241
  • 1
  • 3
  • 11
  • Have you considered that the actual latitudes and longitudes may be wrong. Because I found different latitudes and longitudes of Rome and Rio. Have a look on google. They are different but I don’t think it would cause it to be that far off. – Lloyd Nicholson Dec 20 '18 at 10:32
  • Thanks Lloyd, but lat long seems correct: I took the google map one, here's the link for Rome, you can see lat ang long in the url: https://www.google.com/maps/place/Roma+RM/@41.9097306,12.2558141,10z/data=!3m1!4b1!4m5!3m4!1s0x132f6196f9928ebb:0xb90f770693656e38!8m2!3d41.9027835!4d12.4963655 – btb84 Dec 20 '18 at 10:38
  • I'm not sure but if I'd should bet a penny I'd say that the map should be "drawn" starting from a particular latitude/longitude and ending on a particular latitude/longitude to keep the right proportion accurate. But I can't find anything helping – btb84 Dec 20 '18 at 10:40
  • 1
    I would suggest using another Mercator image such as this one https://www.google.com/search?q=spherical+mercator+map&tbm=isch&chips=q:web+mercator+map,g_1:high+resolution&rlz=1CDGOYI_enZA823ZA823&prmd=ivsn&hl=en-GB&ved=2ahUKEwjghqPzp67fAhVE5xQKHauyDsAQ4lZ6BAgBEBc&biw=375&bih=551#imgrc=GjNqydzHBsyr8M&imgdii=SxCDiTjHy906gM – Lloyd Nicholson Dec 20 '18 at 11:38
  • 1
    thanks Lloyd, I picked up one of those and it works. And, most important thing, I know what to say to the graphic guy who will be re-drawing the map, thanks again! – btb84 Dec 20 '18 at 12:07
  • you’re welcome. An interesting question and a simple answer but just took some time haha. – Lloyd Nicholson Dec 20 '18 at 12:10

2 Answers2

2

Your points are inaccurate because your formula does not take into account that the earth is not a flat plane.

Assuming you are using the mercador projection (looks like it to me).

pseudo code from a detailed answer

latitude    = 41.9097306;
longitude   = 12.2558141;

mapWidth    = 800;
mapHeight   = 444;

// get x value
x = (longitude+180)*(mapWidth/360)

// convert from degrees to radians
latRad = latitude*PI/180;

// get y value
mercN = ln(tan((PI/4)+(latRad/2)));
y     = (mapHeight/2)-(mapWidth*mercN/(2*PI));
tandrieu
  • 129
  • 1
  • 4
  • Thanks tandrieu, the formula you posted is one of many other I've tried. Now I've updated the demo link with that formula, markers moved a little bit but they still are wrong. – btb84 Dec 20 '18 at 11:11
  • Could that issue be addressed to the map image? I see that Mercator project maps are centered differently and also got different proportions – btb84 Dec 20 '18 at 11:14
  • If your image is not a valid mercator projection, that is most probably the issue. You should try with a valid one or find what is your map "projection" and change the formula accordingly – tandrieu Dec 20 '18 at 11:39
0

So, just for anyone struggling with this issue, the problem was that I just was ignoring how the map image should be sized and drawn. Using a valid mercator projection map fixed everything, here are some examples

thanks guys for helping me understanding that!

btb84
  • 241
  • 1
  • 3
  • 11