Brett Stubbs
Brett Stubbs

Reputation: 679

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?

Upvotes: 13

Views: 12553

Answers (4)

henrry
henrry

Reputation: 623

'worldCopyJump': true work for me.

Can see this link.

<!DOCTYPE html>
<html lang="en">
Lat: <p  id="LatClick"> </p><br>
Lng: <p id="LOnClick" > </p><br>
<head>
    <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
 <meta name="referrer" content="never">
    <style>
        body {
            padding: 0;
            margin: 0;
        }
        html, body, #map {
            height: 80%;
         }
        .lorem {
            font-style: italic;
            color: #AAA;
        }
    </style>
</head>
<body>
   
    <div id="map"  ></div>
    <script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
    <script>
        var map = L.map('map',{'worldCopyJump': true});
        map.setView([31.623116,84.497856], 8); L.tileLayer( 'http://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png', { maxZoom: 18}).addTo(map);
//var marker = L.marker([31.2, 97]).addTo(map);
var theMarker={};
map.on('click', function(e){
  var coord = e.latlng;
  var lat = coord.lat;
   map.removeLayer(theMarker);
  var lng = coord.lng;
  theMarker=L.marker([lat,lng]).addTo(map);
document.getElementById("LatClick").innerHTML = lat;
document.getElementById("LOnClick").innerHTML = lng;
});
     </script>
</body>
</html>

Upvotes: 0

nickdos
nickdos

Reputation: 8414

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.

Upvotes: 7

Brett Stubbs
Brett Stubbs

Reputation: 679

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.

Upvotes: 15

Michał Krzemiński
Michał Krzemiński

Reputation: 1251

I've never experienced those incorrect bounds, but wouldn't programmaticly limiting them serve as at least temporary solution?

As for markers not showing - does it happen when you are moving the map? If so it is quite likely caused by 'moveend' events overlapping. I don't know how many points are there on average but if data download doesn't finish and add markers the next call of 'moveend' will delete all existing markers and start replacing them (also it will override 'plotlist' which migth cause errors later on). You could try adding them to global list after all operations are finished and markers are drawn or you could move only markers not in new set.

On sidenote - why not use geojson to create those layers? With 'pointToLayer' and 'onEachFeature' you could customize markers/popups and have one layer at the end, rather then long list of markers.

Upvotes: 0

Related Questions