Reputation: 241
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>
Upvotes: 2
Views: 2352
Reputation: 241
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!
Upvotes: 0
Reputation: 127
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));
Upvotes: 2