Zoom out to show all markers

4,246 views
Skip to first unread message

Brad McCarron

unread,
Mar 13, 2013, 11:26:40 AM3/13/13
to leafl...@googlegroups.com
Hi all, I know this has to be easy, but I haven't figured it out due to lack of examples in the documentation.

Basically, when the map loads with all the markers, I want it to zoom out so that all markers are shown.

My app loops through an array and creates markers with two variables:  cood[0] and cood[1]

How can I build an array of all these coordinates, then adjust the map accordingly?

Please help


Heather Mann

unread,
Mar 13, 2013, 1:20:43 PM3/13/13
to leafl...@googlegroups.com
I'm really new to this but here's what I did (using your cood variables)

bounds = new L.LatLngBounds(cood[0], cood[1]);
map.fitBounds(bounds);

hth.

Heather

ps - if there's a better way to do this I'd love to know

Brad McCarron

unread,
Mar 13, 2013, 1:49:37 PM3/13/13
to leafl...@googlegroups.com
Hi Heather, thanks for your reply.

That's a great start, but I still need to figure out how to make it work with an array of points :( this should be documented somewhere.

Heather Mann

unread,
Mar 13, 2013, 6:28:04 PM3/13/13
to leafl...@googlegroups.com
Just figured this out myself.  This might be a bit different to your application but hopefully it will put you on the right path.  I'm creating the markers from a database so I do something like the following (simplified for the example)

---------------------------------------------------------------
//loop through the database table and put all of the lats in one array and all the lngs in another
<?php
while($row = mysql_fetch_array($result)){
    $lats[] = $row['lat'];
    $lngs[] = $row['lng'];
}

//get the max and mins
    $maxlat = max($lats);
    $maxlng = max($lngs);
   
    $minlat = min($lats);
    $minlng = min($lngs);
?>

<script>

    var southwest = new L.LatLng(<?php echo $minlat . "," . $minlng; ?>);
    var northeast = new L.LatLng(<?php echo $maxlat . "," . $maxlng;?>);
    bounds = new L.LatLngBounds(southwest, northeast);
    map.fitBounds(bounds);

</script>

------------------------------------------------------

There very well might be a better way to do this but this does work.  Of course if there's a simpler way I would love to know about it.

Brad McCarron

unread,
Mar 13, 2013, 8:37:17 PM3/13/13
to leafl...@googlegroups.com
Heather, great work. I sincerely cannot thank you enough. 

Below is the final code that I wrote with javascript. I hope this snippet gets added to the Leaflet documentation.

var lats = [];
var lngs = [];

for (var i = 0; i < markers.length; i++) {

// create a marker here

// add the marker coordinates to the lats and lngs arrays
lats.push(lat[i]);
lngs.push(lng[i]);

// if iteration creates the last marker, then execute setbounds() function, passing variables [map, lats (array), and lngs (array)] to the function
  if(i>markercount-2){
         setbounds(map, lats, lngs);
      }
 
}  // END MAIN FOR EACH MARKER LOOP
   

function setbounds(map, lats, lngs){
  
  var maxlat = Math.max.apply(Math, lats);
  var maxlng = Math.max.apply(Math, lngs);
  
  var minlat = Math.min.apply(Math, lats);
  var minlng = Math.min.apply(Math, lngs);

  var sw = new L.LatLng(minlat,minlng);
  var ne = new L.LatLng(maxlat,maxlng);
    
  var bounds = new L.LatLngBounds(sw, ne);
  
  map.fitBounds(bounds); 
}

Many many thanks Heather.

Heather Mann

unread,
Mar 13, 2013, 9:24:10 PM3/13/13
to leafl...@googlegroups.com
Hi Brad - you're very welcome!  And thanks for posting your final code - nice work!  It should definitely be added to the leaflet docs - or better yet to the core somehow!

Heather Mann

unread,
Mar 13, 2013, 9:24:22 PM3/13/13
to leafl...@googlegroups.com

Craig Ballantyne

unread,
Mar 14, 2013, 7:12:40 AM3/14/13
to leafl...@googlegroups.com
Hi Brad, 

I know you have already managed to solve this but I thought I would offer another option.

Leaflet featureGroups have a getBounds function so how I solved this was to create a featureGroup, loop through my json array and creating and adding each marker to the featureGroup before adding it to the map.


Rough code (quickly simplified from what I'm actually using to give you an idea of how it works):

        //create the marker group
var markers = new L.featureGroup();
plotMarkers([JSON ARRAY OF MARKER ITEMS]);
//add the markers to the map
map.addLayer(markers);
//fit the map to the markers
map.fitBounds(markers.getBounds());

function plotMarkers(MarkerItems)
{
if(MarkerItems)
{
var len = MarkerItems.length;
for(var i = 0; i<len; i++)
{
                        var marker =  L.marker(new L.LatLng([LAT],[LNG])).bindPopup([WINDOW CONTENT])
markers.addLayer(marker);
}
}

}

Heather Mann

unread,
Mar 14, 2013, 11:00:58 AM3/14/13
to leafl...@googlegroups.com
Aha!  That's probably the best way to do it.  Thanks Craig!  And Sorry Brad for leading you a bit astray!
Heather

Brad McCarron

unread,
Mar 18, 2013, 7:58:02 AM3/18/13
to leafl...@googlegroups.com
Craig -
Nice dude! That will definitely shave a few lines off my code.

Heather -
No worries, your advice was a huge help.

Todd Albert

unread,
Mar 19, 2013, 12:46:54 PM3/19/13
to leafl...@googlegroups.com
Hi Craig,

This is essentially what I've done, but it often is such that the northern-most or southern-most pins are not shown without a slight nudge or zoom-out of the map.

Any idea how to remedy this?

-Todd

Craig Ballantyne

unread,
Mar 19, 2013, 1:12:17 PM3/19/13
to leafl...@googlegroups.com
Hi Todd, 

the latlngbounds object has a pad function, you'll just need to play with the padding percentage to get it looking neat.

map.fitBounds(markers.getBounds().pad(0.3));

Craig

Todd Albert

unread,
Mar 19, 2013, 1:25:55 PM3/19/13
to leafl...@googlegroups.com
Awesome. That helps. Is it possible to have different padding for latitude than longitude? (e.g. map.fitBounds(markers.getBounds().pad(0.3,0.1)); or something similar?)

Craig Ballantyne

unread,
Mar 19, 2013, 1:41:21 PM3/19/13
to leafl...@googlegroups.com
No, not as it is.  
I just took a quick look at the function though and it looks like it would be simple enough to tweak (or to duplicate and adjust if you don't want to mess with the core).

ORIGINAL:
// extend the bounds by a percentage
pad: function (bufferRatio) { // (Number) -> LatLngBounds
var sw = this._southWest,
ne = this._northEast,
heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio,
widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio;

return new L.LatLngBounds(
new L.LatLng(sw.lat - heightBuffer, sw.lng - widthBuffer),
new L.LatLng(ne.lat + heightBuffer, ne.lng + widthBuffer));
}


--
 
---
You received this message because you are subscribed to a topic in the Google Groups "Leaflet" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/leaflet-js/F66YlMCaQK4/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to leaflet-js+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Todd Albert

unread,
Mar 19, 2013, 1:43:09 PM3/19/13
to leafl...@googlegroups.com
Very true, but I solved the issue another way. I had something dropping down OVER one side of the map. Now I slide the map out from under so I don't have to buffer the sides more. It works and looks better now.

Thanks,
Todd

Todd Albert

unread,
Mar 19, 2013, 1:44:07 PM3/19/13
to leafl...@googlegroups.com
P.S. Please feel free to check out the map at http://www.madvalorem.com/search/

I welcome feedback.

-Todd

Craig Ballantyne

unread,
Mar 19, 2013, 1:57:19 PM3/19/13
to leafl...@googlegroups.com
That makes sense, glad its working.  
That looks like a good project, I only recently started using leaflet and haven't had a chance to build anything too exciting with it yet.
Reply all
Reply to author
Forward
0 new messages