Come utilizzare FeatureGroup di Leaflet con OverlappingMarkerSpiderfier in React-leaflet?
Ho problemi nell'integrazione di OverlappingMarkerSpiderfier con React-Leaflet e nell'utilizzo di FeatureGroup per la panoramica sulla mappa. I FeatureGroup sono davvero utili quando si dispone di una logica di panoramica complicata.
Ecco una semplice demo JS . I marker spiderfy e il pulsante Pan funzionano senza problemi.
Ecco la demo del foglietto di reazione . La panoramica fallirà con il seguente errore se spiderfy è abilitato / controllato nell'interfaccia utente. Questo è basato su questo post SO .
layer.getLatLng is not a function
Penso che il problema sia che con JS normale, posso aggiungere l'array di marcatori a entrambi omse in modo featureGroupimperativo, ma con React-leaflet, non vedo come posso ottenere lo stesso risultato.
È l'errore perché il <Spiderfy>livello non ha una getLatLngfunzione per qualche motivo anche se sto estendendo il MapLayer .
Non sono sicuro di ciò che deve essere risolto, la versione JS sembra funzionare quindi la libreria OverlappingMarkerSpiderfier probabilmente non necessita di modifiche. Potrebbe essere un problema / limitazione specifico del volantino React che può essere risolto con un FeatureGroup / MapLayer personalizzato?
Risposte
Sembra l'errore
layer.getLatLng non è una funzione
si verifica poiché la funzione FeatureGroup.getBounds prevede che i livelli sottostanti implementino uno getBoundso i getLatLngmetodi, il che non è il caso del Spiderfy.jscomponente personalizzato in cui container ( layerContainerprop) è di L.layerGrouptipo.
Un'opzione da considerare sarebbe il refactoring del Spiderfy.jscomponente:
- abbandonare
L.layerGroupcome contenitore di livelli - poiché viene utilizzata una versione recente di React (
16.8o superiore), sostituire ilES6 classcomponente con la funzione per implementare ilSpiderfycomponente
Spiderfy.js componente
import React, { useEffect } from "react";
import { withLeaflet, MapLayer, useLeaflet } from "react-leaflet";
import L from "leaflet";
import "overlapping-marker-spiderfier-leaflet/dist/oms";
function Spiderfy(props) {
const { map, layerContainer } = useLeaflet();
const oms = new window.OverlappingMarkerSpiderfier(map);
oms.addListener("spiderfy", (markers) => {
markers.forEach((m) => m.closePopup()); //force to close popup
if (props.onSpiderfy) props.onSpiderfy(markers);
});
oms.addListener("unspiderfy", (markers) => {
if (props.onUnspiderfy) props.onUnspiderfy(markers);
});
oms.addListener("click", (marker) => {
if (props.onClick) props.onClick(marker);
});
useEffect(() => {
layerContainer.eachLayer((layer) => {
if (layer instanceof L.Marker) {
oms.addMarker(layer);
}
});
}, [oms,layerContainer]);
return <div>{props.children}</div>;
}
export default withLeaflet(Spiderfy);
In questo modo la FeatureGroup.getBoundsfunzione dovrebbe restituire il risultato atteso, identico a quello fornito nella semplice demo JS .
Esempio a forcella
Come correttamente sottolineato da Vadim , L.layerGroupnon implementa getBounds.
Lo svantaggio principale dell'abbandono di un gruppo di livelli è che anche i componenti che non sono figli del componente Spiderfy sono sottoposti a spiderfy poiché utilizza il layerContainer
- Guarda questa demo . Se guardi il registro della console, la
markerCountvariabile è 4 anche se ci sono solo tre marcatori come figli di Spiderfy.
Guardando la documentazione di Leaflet, possiamo usare L.featureGroup invece di un layerGroup in quanto è semplicemente un'estensione del layerGroup.
const el = L.featureGroup([], this.getOptions(props));
- Demo , puoi vedere che la
markerCountvariabile è 3 e non 4
A seconda del caso d'uso, la nidificazione di gruppi di funzionalità come questo non sarà un problema. Facoltativamente puoi dare un'occhiata ai sottogruppi