I have two buttons and the idea is: when I click a button, it changes the basemap
state. However, each time I click on the button to change the basemap tilelayer
, I get
Error: Map container is already initialized.
Does anyone know of a way to fix this? My code is below.
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]);
CodePudding user response:
Obviously you should avoid reinitializing your map everytime you click on a different button.
Here the "difficulty" with React functional components is that it may not be obvious where to store that map and its Tile Layers. A solution is to use a useRef
hook, which you populate at the component instanciation with a useEffect
hook that runs only once (i.e. with an empty dependency array []
).
Something in the lines of:
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]);
Note: I see that you also used a state hook to store your map. It is also a valid solution, simply do the same with your Tile Layers.
CodePudding user response:
If you want to add a layer to your map you can do: map.addLayer(layer);
And if you want to remove / clean a layer before adding a new one you can map.removeLayer(layer);
See leaflet doc: https://leafletjs.com/reference.html