Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 260
Brett Stubbs Avatar asked Aug 05 '13 16:08

Brett Stubbs


2 Answers

I was seeing a similar thing, except I was processing a map click event via a callback as event.latlng.lng. Adding worldCopyJump: true did not fix this issue for me - I was still seeing longitude values greater than 180.

In the end, I called the wrap() method to the latlng object:

event.latlng.wrap().lng

which fixed the problem.

like image 133
nickdos Avatar answered Oct 30 '22 04:10

nickdos


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.

like image 45
Brett Stubbs Avatar answered Oct 30 '22 03:10

Brett Stubbs