169

How do I set view to see all markers on map in Mapbox or Leaflet? Like Google Maps API does with bounds?

E.g:

var latlngbounds = new google.maps.LatLngBounds();
for (var i = 0; i < latlng.length; i++) {
  latlngbounds.extend(latlng[i]);
}
map.fitBounds(latlngbounds);
jrharshath
  • 25,975
  • 33
  • 97
  • 127
AHOYAHOY
  • 1,856
  • 4
  • 24
  • 34

12 Answers12

351
var group = new L.featureGroup([marker1, marker2, marker3]);

map.fitBounds(group.getBounds());

See the documentation for more info.

Gaël S
  • 1,598
  • 6
  • 15
L. Sanna
  • 6,482
  • 7
  • 33
  • 47
  • 4
    The problem with this solution is that it can sometimes cut off a northerly marker, since the marker extends beyonds the bounds given by its coordinates. – aaronbauman Dec 11 '13 at 18:23
  • 93
    from @user317946: "map.fitBounds(markers.getBounds().pad(0.5)); now the icons wont cut off. :-)" – László Papp Jan 19 '14 at 15:24
  • 15
    I'm glad i Googled this before reinventing the wheel. Thanks – martynas Jul 18 '14 at 15:54
  • 5
    Just in case it isn't obvious to anyone... You can get bounds of most leaflet objects. map.fitBounds(circle.getBounds()); for example. – Ravendarksky Aug 26 '14 at 15:30
  • 11
    You can use `markers.getBounds().pad()` if you want to extend bounds by a given percentage but you can also pass the padding option to fitBounds in order to set the padding in pixels. `markers.getBounds(), {padding: L.point(20, 20)})` – Alex Guerrero Jun 10 '16 at 17:30
  • This worked for me except I had to remove the word "new" – masteroleary Oct 01 '18 at 20:24
  • 1
    how do we do it for multiple groups? I'm using `markerClusterGroup` and there are many clusters and I want to show them all. – Robin Dec 06 '18 at 01:54
  • @Robin this works fine for me https://stackoverflow.com/a/15207357/5723816 – Ivan Topić Aug 20 '19 at 12:38
  • I only recently found out that instead of L.layerGroup I should use L.featureGroup - that still keeps the remaining syntax the same, but also enables me to use .getBounds() – Nikhil VJ May 23 '20 at 02:06
  • how to do this with mapbox only, no leaflet? – Marius Jun 25 '20 at 07:52
30

The 'Answer' didn't work for me some reasons. So here is what I ended up doing:

////var group = new L.featureGroup(markerArray);//getting 'getBounds() not a function error.
////map.fitBounds(group.getBounds());
var bounds = L.latLngBounds(markerArray);
map.fitBounds(bounds);//works!
IrfanClemson
  • 1,699
  • 6
  • 33
  • 52
  • 1
    Trying to do this but getting Error: `LngLatLike` argument must be specified as a LngLat instance, an object {lng: , lat: }, or an array of [, ]. Any idea? – returnvoid Nov 20 '18 at 21:23
  • 1
    tried it got: `Uncaught Error: Bounds are not valid.` – fayssal el ansari Jan 07 '23 at 21:38
  • 1
    I am sorry folks. I have not used this technology in years; as you can see, the Question was posted by me years ago. @fayssalelansari : I suggest print the Bounds in browser's console to see if the values look okay. Best luck you all. – IrfanClemson Jan 08 '23 at 13:29
21
var markerArray = [];
markerArray.push(L.marker([51.505, -0.09]));
...
var group = L.featureGroup(markerArray).addTo(map);
map.fitBounds(group.getBounds());
malhal
  • 26,330
  • 7
  • 115
  • 133
  • 1
    It works without the addTo(map): map.fitBounds(L.featureGroup(markerArray ).getBounds()); will this make any difference? – Lucas Steffen Sep 21 '16 at 14:36
17

Leaflet also has LatLngBounds that even has an extend function, just like google maps.

http://leafletjs.com/reference.html#latlngbounds

So you could simply use:

var latlngbounds = new L.latLngBounds();

The rest is exactly the same.

Jordan Arsenault
  • 7,100
  • 8
  • 53
  • 96
hassassin
  • 5,024
  • 1
  • 29
  • 38
  • 3
    Thank you! For me the solution, per the Answer above, was returning 'getBounds() is not a function. So I changed my code per your suggestion. I have it in my own Answer. – IrfanClemson May 21 '14 at 17:58
11

Belatedly, I didn't see any answers using Mapbox, despite Mapbox has more functionality such as padding, animation, and max zoom.


const coordinates = [<coordiantes>...]

// Create a 'LngLatBounds' with the first coordinate.
const bounds = new mapboxgl.LngLatBounds(
  coordinates[0],
  coordinates[0]
);
 
// Extend the 'LngLatBounds' to include every coordinate in the bounds result.
for (const coord of coordinates) {
  bounds.extend(coord);
}

// Note there are other options such as easeing animation and maxZoom
map.fitBounds(bounds, {
  padding: 20
});

Demo

Taku
  • 5,639
  • 2
  • 42
  • 31
7

For Leaflet, I'm using

    map.setView(markersLayer.getBounds().getCenter());
Yvonne Ng
  • 111
  • 1
  • 2
6

You have an array of L.Marker:

let markers = [marker1, marker2, marker3]

let latlngs = markers.map(marker => marker.getLatLng())

let latlngBounds = L.latLngBounds(latlngs)

map.fitBounds(latlngBounds)
// OR with a smooth animation
// map.flyToBounds(latlngBounds)
Quân Vương
  • 83
  • 1
  • 5
4

You also can locate all features inside a FeatureGroup or all the featureGroups, see how it works!

//Group1
m1=L.marker([7.11, -70.11]);
m2=L.marker([7.33, -70.33]);
m3=L.marker([7.55, -70.55]);
fg1=L.featureGroup([m1,m2,m3]);

//Group2
m4=L.marker([3.11, -75.11]);
m5=L.marker([3.33, -75.33]);
m6=L.marker([3.55, -75.55]);
fg2=L.featureGroup([m4,m5,m6]);

//BaseMap
baseLayer = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
var map = L.map('map', {
  center: [3, -70],
  zoom: 4,
  layers: [baseLayer, fg1, fg2]
});

//locate group 1
function LocateOne() {
    LocateAllFeatures(map, fg1);
}

function LocateAll() {
    LocateAllFeatures(map, [fg1,fg2]);
}

//Locate the features
function LocateAllFeatures(iobMap, iobFeatureGroup) {
  if(Array.isArray(iobFeatureGroup)){   
   var obBounds = L.latLngBounds();
   for (var i = 0; i < iobFeatureGroup.length; i++) {
    obBounds.extend(iobFeatureGroup[i].getBounds());
   }
   iobMap.fitBounds(obBounds);   
  } else {
   iobMap.fitBounds(iobFeatureGroup.getBounds());
  }
}
.mymap{
  height: 300px;
  width: 100%;
}
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" rel="stylesheet"/>

<div id="map" class="mymap"></div>
<button onclick="LocateOne()">locate group 1</button>
<button onclick="LocateAll()">locate All</button>
Es Noguera
  • 426
  • 1
  • 5
  • 19
3

To fit to the visible markers only, I've this method.

fitMapBounds() {
    // Get all visible Markers
    const visibleMarkers = [];
    this.map.eachLayer(function (layer) {
        if (layer instanceof L.Marker) {
            visibleMarkers.push(layer);
        }
    });

    // Ensure there's at least one visible Marker
    if (visibleMarkers.length > 0) {

        // Create bounds from first Marker then extend it with the rest
        const markersBounds = L.latLngBounds([visibleMarkers[0].getLatLng()]);
        visibleMarkers.forEach((marker) => {
            markersBounds.extend(marker.getLatLng());
        });

        // Fit the map with the visible markers bounds
        this.map.flyToBounds(markersBounds, {
            padding: L.point(36, 36), animate: true,
        });
    }
}
Rami Alloush
  • 2,308
  • 2
  • 27
  • 33
1
//Create a point Layer (in this case a GeoJSON source)
let pointLayer = L.geoJSON(pointSource, {
    pointToLayerL pointToLayer,
    onEachFeature: onEachFeature
});
//Add the newly created layer to the mapObject
pointLayer.addTo(mapObject);

//Set a padding variable for the space around the bounds
let paddingCoef = (0.5);

//Call the fit bounds to adjust to the padded extent of points.
mapObject.fitBounds(pointLayer.getBounds().pad(paddingCoef));
0

The best way is to use the next code

var group = new L.featureGroup([marker1, marker2, marker3]);

map.fitBounds(group.getBounds());
Dino
  • 7,779
  • 12
  • 46
  • 85
Kais Tounsi
  • 11
  • 4
  • 8
0

in MapBox you can use fitBound method.

you can use docs.mapbox

AliTN
  • 96
  • 5