I have a React Leaflet map that needs to change its center and zoom when given a set of markers. The zoom should be changed such that all the markers are visible.
This change of view is currently being attempted using the function ChangeView
.
Using my code below, I am able to move the map view, but not able to let the map fit to the bounds. Running the code gives the error:
Error: Bounds are not valid.
on the line
map.fitBounds(markerBounds)
What can we do? Thanks!
import L, { LatLng, latLngBounds, FeatureGroup } from 'leaflet'; import React from 'react'; import { MapContainer, TileLayer, Marker, Popup, useMap } from 'react-leaflet'; import MarkerClusterGroup from 'react-leaflet-markercluster'; import { LatLon, MapMarker } from '../../common/types'; import { config } from '../../config'; interface IProps { markers: MapMarker[]; searchCenter: LatLon; } interface IChangeView { center: LatLon; markers: MapMarker[]; } function ChangeView({ center, markers }: IChangeView) { const map = useMap(); map.setView({lng: center.lon, lat: center.lat}, DEFAULT_ZOOM); let markerBounds = latLngBounds([]); markers.forEach(marker => { markerBounds.extend([marker.lat, marker.lon]) }) map.fitBounds(markerBounds) // <===== Error: Bounds are not valid. return null; } export function MapView({markers, searchCenter}: IProps): JSX.Element { return ( <MapContainer center={[searchCenter.lat, searchCenter.lon]} zoom=14 style={{ width:'100%', height:'100vh' }} className='markercluster-map' > <ChangeView center={searchCenter} markers={markers} /> <TileLayer url={`https://api.mapbox.com/styles/v1/mapbox/streets-v11/tiles/{z}/{x}/{y}?access_token=${config.api.mapbox}`} /> <MarkerClusterGroup> { markers.map((marker, index) => ( <Marker position={[marker.lat, marker.lon]} key={index} /> )) } </MarkerClusterGroup> </MapContainer> ) }
Also tried using FeatureGroup
instead of latLngBounds
, but it gave the exact same error
Error: Bounds are not valid
let group = new FeatureGroup(); markers.forEach(marker => { L.marker([marker.lat, marker.lon]).addTo(group); }) map.fitBounds(group.getBounds());
Advertisement
Answer
If the markers
array is empty, or null
, the bounds you create will not have ._southWest
and ._northEast
properties, and that error will throw. Just make the fitBounds
statement conditional on there being markers in the array:
if (markers.length && markers.length > 0){ markers.forEach(marker => { markerBounds.extend([marker.lat, marker.lon]) }) map.fitBounds(markerBounds) }
Or even just a quick one liner:
markerBounds.isValid() && map.fitBounds(markerBounds)