Tengo dos botones y la idea es: cuando hago clic en un botón, cambia el estado del basemap . Sin embargo, cada vez que hago clic en el botón para cambiar la capa de mosaico del basemap tilelayer , obtengo
Error: Map container is already initialized.¿Alguien sabe de una manera de arreglar esto? Mi código está abajo.
useEffect(() => { console.log('Initializing map'); var map = L.map(ref.current).setView([53.9, -9.5], 10); setLeafletMap(map); const osm = L.tileLayer( 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', { attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>', subdomains: 'abcd', maxZoom: 20, } ); const aerial = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', { attribution:'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community' } ); const basemapLayers = { 'OSM': osm, 'Aerial': aerial }; basemapLayers[selectedBasemap].addTo(map); }, [selectedBasemap]);Obviamente, debe evitar reiniciar su mapa cada vez que haga clic en un botón diferente.
Aquí, la "dificultad" con los componentes funcionales de React es que puede no ser obvio dónde almacenar ese mapa y sus capas de mosaico. Una solución es usar un useRef , que se completa en la instanciación del componente con un useEffect que se ejecuta solo una vez (es decir, con una matriz de dependencia vacía [] ).
Algo en las líneas de:
const leafletObjects = useRef(); useEffect(() => { leafletObjects.current = { map: L.map(ref.current), basemapLayers: { OSM: L.tileLayer(osmUrlTemplate), Aerial: L.tileLayer(aerialUrlTemplate) } }; }, []); useEffect(() => { leafletObjects.current.basemapLayers[selectedBasemap].addTo(leafletObjects.current.map); }, [selectedBasemap]);Nota: Veo que también usaste un enlace de estado para almacenar tu mapa. También es una solución válida, simplemente haga lo mismo con sus capas de mosaico.
Si desea agregar una capa a su mapa, puede hacerlo: map.addLayer(layer);
Y si desea eliminar/limpiar una capa antes de agregar una nueva, puede map.removeLayer(layer);
Ver folleto doc: https://leafletjs.com/reference.html
Lo descubrí con lo siguiente:
useEffect(() => { console.log('Initializing map'); var map = L.map(ref.current).setView([53.9, -9.5], 10); setLeafletMap(map); }, []); useEffect(() => { if(!leafletMap){ return; } const osm = L.tileLayer( 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', { attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>', subdomains: 'abcd', maxZoom: 20, } ); const aerial = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', { attribution:'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community' } ); const basemapLayers = { 'OSM': osm, 'Aerial': aerial }; basemapLayers[selectedBasemap].addTo(leafletMap); }, [leafletMap, selectedBasemap]);Gracias a todos