Using React Leaflet I can quite happily get a LayerControl through which I can enable/disable Leaflet Marker LayerGroups, but can't fathom how I can do do this programmatically.
The Leaflet documentation suggests something along the lines of:
var layer = L.marker(latlng).addTo(map);
layer.addTo(map);
layer.remove();
And similarly this Leaflet issue suggests keeping track of the your own layers. But how do I do this in React-Leaflet? It feels like it's abstracted too much away.
I've simplified React Leaflets's example/ponents/layers-control.js to isolate the issue but can't get at any of the elements:
class App extends Component {
render() {
return (
<div className='map'>
<Map className='map' center={[51,0]} zoom={10} id='map1'>
<LayersControl position="topright" id="lc1">
<TileLayer
attribution='&copy <a href="">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap/{z}/{x}/{y}.png"
id="tl1"
/>
<Overlay name="Layer 1" id="l1">
<LayerGroup id="lg1">
<Marker position={[51, 0.1]}></Marker>
</LayerGroup>
</Overlay>
<Overlay name="Layer 2">
<LayerGroup>
<Marker position={[51, 0.2]}></Marker>
</LayerGroup>
</Overlay>
</LayersControl>
</Map>
</div>
);
}
}
Using React Leaflet I can quite happily get a LayerControl through which I can enable/disable Leaflet Marker LayerGroups, but can't fathom how I can do do this programmatically.
The Leaflet documentation suggests something along the lines of:
var layer = L.marker(latlng).addTo(map);
layer.addTo(map);
layer.remove();
And similarly this Leaflet issue suggests keeping track of the your own layers. But how do I do this in React-Leaflet? It feels like it's abstracted too much away.
I've simplified React Leaflets's example/ponents/layers-control.js to isolate the issue but can't get at any of the elements:
class App extends Component {
render() {
return (
<div className='map'>
<Map className='map' center={[51,0]} zoom={10} id='map1'>
<LayersControl position="topright" id="lc1">
<TileLayer
attribution='&copy <a href="http://osm/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap/{z}/{x}/{y}.png"
id="tl1"
/>
<Overlay name="Layer 1" id="l1">
<LayerGroup id="lg1">
<Marker position={[51, 0.1]}></Marker>
</LayerGroup>
</Overlay>
<Overlay name="Layer 2">
<LayerGroup>
<Marker position={[51, 0.2]}></Marker>
</LayerGroup>
</Overlay>
</LayersControl>
</Map>
</div>
);
}
}
Share
Improve this question
edited May 19, 2020 at 11:28
kboul
14.6k5 gold badges47 silver badges58 bronze badges
asked May 19, 2020 at 0:55
MatMat
86.8k35 gold badges95 silver badges111 bronze badges
1 Answer
Reset to default 3You can achieve that using refs to keep track of the map instance and the overlay instances respectively and then using some vanilla leaflet code as you would do without React:
const mapRef = useRef();
const firstOverlayRef = useRef();
const secondOverlayRef = useRef();
const addLayers = () => {
if (mapRef.current && firstOverlayRef.current) {
const map = mapRef.current.leafletElement;
const firstLayer = firstOverlayRef.current.leafletElement;
const secondLayer = secondOverlayRef.current.leafletElement;
[firstLayer, secondLayer].forEach(layer => map.addLayer(layer));
}
};
const removeLayers = () => {
if (mapRef.current && firstOverlayRef.current) {
const map = mapRef.current.leafletElement;
const firstLayer = firstOverlayRef.current.leafletElement;
const secondLayer = secondOverlayRef.current.leafletElement;
[firstLayer, secondLayer].forEach(layer => map.removeLayer(layer));
}
};
....
<Map center={center} zoom={10} style={{ height: "90vh" }} ref={mapRef}>
<LayersControl position="topright">
<TileLayer
attribution='&copy <a href="http://osm/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap/{z}/{x}/{y}.png"
id="tl1"
/>
<Overlay name="Layer 1">
<LayerGroup id="lg1" ref={firstOverlayRef}>
<Marker position={[51, 0.1]} icon={icon} />
</LayerGroup>
</Overlay>
<Overlay name="Layer 2">
<LayerGroup ref={secondOverlayRef}>
<Marker position={[51, 0.2]} icon={icon} />
</LayerGroup>
</Overlay>
</LayersControl>
</Map>
<button onClick={addLayers}>Add Layers</button>
<button onClick={removeLayers}>Remove layers</button>
...
Demo