Brett Stubbs Brett Stubbs - 27 days ago 14
Javascript Question

Leaflet getBounds() returning longitudes greater than 180

I suggested an issue and the author closed it on Github, but I am still left with no conclusion. Longitudes range from -180 to 180. But sometimes, Leaflet returns longitudes like 474.2578215 from getBounds(), which then of course nothing gets returned in my database.

I was told: It's intended behavior. That happens when you zoom too far out and/or drag the map to another copies of the world, and getBounds longitudes are not wrapped by default. You can use LatLng wrap method to get what you want though — e.g. bounds.getSouthWest().wrap().

Ok. So I added the wrap method in there, and the correct data is returned, but now no markers will show up on the map. This is probably due to the marker locations not being within that high number range (what leaflet thinks is the coordinates of the boundaries...)

I'm not sure that zooming or dragging is the cause of the issue. The problem persists when refreshing the page, where the user does no zooming or dragging events have occurred. I have the zoom limited in the init with: minZoom: 6, maxZoom: 13.

I should also note, that this code (unchanged) used to work just fine. Here is my code:

$(document).ready(function(){ initmap(); });

var map;
var plotlist;
var plotlayers=[];

function initmap(){
// set up the map
map = new L.Map('map');

//get our map
var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var osmAttrib='&copy; <a href = "http://www.openstreetmap.org/copyright"> OpenStreetMap </a> contributors';
var osm = new L.TileLayer(osmUrl, {minZoom: 6, maxZoom: 13,
attribution: osmAttrib});

map.setView(new L.LatLng(<?=$slat;?>, <?=$slng;?>),9);
map.attributionControl.setPrefix('');
map.addLayer(osm);
getGameMarkers();
map.on('moveend', onMapMove);
}

function onMapMove(e){
getGameMarkers();
}

function getGameMarkers(){
var center = map.getCenter();
var zoo = map.getZoom();
var bounds = map.getBounds();
console.log(bounds);

var min = bounds.getSouthWest().wrap();
var max = bounds.getNorthEast().wrap();

$.ajax({type: "GET", url: "./ajax/markers.php", dataType: "json", data: "clat="+center.lat+"&clng="+center.lng+"&zoom="+zoo+"&minlat="+min.lat+"&minlng="+min.lng+"&maxlat="+max.lat+"&maxlng="+max.lng+cookiestr,
success: function(data){
if (data.showmap == 1) {
plotlist = data.map_data;
removeMarkers();
for (i=0;i<plotlist.length;i++) {
var iconic = String(plotlist[i].icon);
var plotmark = new L.marker([plotlist[i].lat,plotlist[i].lng], {icon: L.icon({iconUrl: iconic, iconSize: [32, 32]}) }).bindPopup(plotlist[i].html);
map.addLayer(plotmark);
plotlayers.push(plotmark);
}

$("#content").html(data.html);
}else {
$("#map_content").show();
$("#map_content").html(data.main_content);
$("#content").html(data.side_content);
}
}
});
}


The wrap() functions give the correct coordinates, and the DB returns the correct plots. But for some reason, they don't display. Here are the plots returned (the map_data portion):

map_data: [{lat:36.672825, lng:-76.541748, icon:./img/avicon3.png,…},…]
0: {lat:36.672825, lng:-76.541748, icon:./img/avicon3.png,…}
1: {lat:36.901314, lng:-76.041870, icon:./img/avicon2.png,…}
2: {lat:37.101192, lng:-76.264343, icon:./img/avicon3.png,…}
3: {lat:37.300274, lng:-75.673828, icon:./img/avicon3.png,…}
4: {lat:37.348328, lng:-76.830139, icon:./img/avicon3.png,…}
5: {lat:37.2481003, lng:-76.1194000, icon:./img/bicon3.png,…}
6: {lat:37.0298691, lng:-76.3452225, icon:./img/ricon.png,…}
7: {lat:37.6087608, lng:-77.3733063, icon:./img/ricon.png,…}
8: {lat:37.7440300, lng:-77.1316376, icon:./img/ricon.png,…}
9: {lat:37.5917015, lng:-77.4207993, icon:./img/bicon2.png,…}
10: {lat:37.5206985, lng:-77.3783112, icon:./img/ricon.png,…}
11: {lat:37.3306999, lng:-77.3227615, icon:./img/ricon.png,…}
12: {lat:37.1228981, lng:-75.9063034, icon:./img/bicon2.png,…}


No errors in console, and as I said, sometimes it all works (when getBounds doesn't return a crazy big LON). So what in the heck am I doing wrong, and more importantly, how do I solve it?

Answer

This is due to worldCopyJump being set to false by default. Setting it to true, and the markers will display correctly, as the world won't overlap.

Comments