Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
674 views
in Technique[技术] by (71.8m points)

javascript - How to Set Leaflet Map's Zoom to Show All Markers in React Leaflet?

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());
question from:https://stackoverflow.com/questions/65878831/how-to-set-leaflet-maps-zoom-to-show-all-markers-in-react-leaflet

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...