I have this map:
<l-map
ref="mapRef"
:use-global-leaflet="false"
>
and wanted to fit the map based on bounds which calculated in this way:
bounds.extend([lat, lng]);
now when I use this code:
mapRef.value.leafletObject.fitBounds(bounds, { padding: [40, 40] });
I get this error:
Error fitting map bounds: Error: Bounds are not valid.
and when I use this code
zoom = mapRef.value.leafletObject.getBoundsZoom(bounds);
i get this error:
Error fitting map bounds: TypeError: can't access property "lat", this._northEast is undefined
I dont have any idea why this happens?
this is the log of bounds just before the line of using it:
Calculated bounds:
Object { _southWest: {…}, _northEast: {…} }
_northEast: Object { lat: 36.376582309526, lng: 59.671965269915 }
_southWest: Object { lat: 36.2296652, lng: 57.6810134 }
You should pass a simple bounds literal. Leaflet accepts it and creates an internal bounds.
// compute min/max lat/lng from your points
const sw = [minLat, minLng];
const ne = [maxLat, maxLng];
mapRef.value.leafletObject.fitBounds([sw, ne], { padding: [40, 40] });
or you can consider taking it from array of points
const points = [[36.2296652, 57.6810134], [36.376582309526, 59.671965269915]];
mapRef.value.leafletObject.fitBounds(points, { padding: [40, 40] }); // also valid
or you can create the bounds without importing L, using the map’s own instance methods:
const b = mapRef.value.leafletObject.getBounds();
const b = mapRef.value.leafletObject.getBounds().constructor
// Not recommended
You can go use a single global Leaflet instance If you want to use L.latLngBounds() and bounds.extend() explicitly. Kindly ensure the same L is used everywhere (attach your imported Leaflet to window.L before the map mounts):
<l-map ref="mapRef" :use-global-leaflet="true">
import * as L from 'leaflet';
window.L = L;
// now both your code and Vue-Leaflet use the same L
Build bounds accordingly:
const bounds = L.latLngBounds([]);
points.forEach(([lat, lng]) => bounds.extend(L.latLng(lat, lng)));
mapRef.value.leafletObject.fitBounds(bounds, { padding: [40, 40] });
fitBounds expects at least 2 points or a valid rectangle. If you only extended once, fallback to setView:
if (points.length === 1) {
mapRef.value.leafletObject.setView(points[0], desiredZoom);
} else {
mapRef.value.leafletObject.fitBounds(points, { padding: [40, 40] });
}
This is more safe:
// Given an array of [lat, lng] points
const points = [
[36.2296652, 57.6810134],
[36.376582309526, 59.671965269915]
];
mapRef.value.leafletObject.fitBounds(points, { padding: [40, 40] });
const lats = points.map(p => p[0]);
const lngs = points.map(p => p[1]);
const sw = [Math.min(...lats), Math.min(...lngs)];
const ne = [Math.max(...lats), Math.max(...lngs)];
mapRef.value.leafletObject.fitBounds([sw, ne], { padding: [40, 40] });
and use global Leaflet and class-based bounds
<l-map ref="mapRef" :use-global-leaflet="true">
import * as L from 'leaflet';
window.L = L;
const bounds = L.latLngBounds([]);
for (const [lat, lng] of points) bounds.extend(L.latLng(lat, lng));
if (bounds.isValid()) {
mapRef.value.leafletObject.fitBounds(bounds, { padding: [40, 40] });
} else {
console.warn('Bounds not valid, falling back to setView');
}
Hope it gives you some clarity.