¿Cómo utilizar FeatureGroup de Leaflet con OverlappingMarkerSpiderfier en react-leaflet?
Tengo problemas para integrar OverlappingMarkerSpiderfier con React-Leaflet y uso FeatureGroup para desplazarse por el mapa. FeatureGroups son realmente útiles cuando tiene una lógica de panorámica complicada.
Aquí hay una demostración simple de JS . Los marcadores son arañazos y el botón de panorámica funciona sin problemas.
Aquí está la demostración del folleto de reacción . La panorámica fallará con el siguiente error si spiderfy está habilitado / marcado en la interfaz de usuario. Esto se basa en esta publicación SO .
layer.getLatLng is not a function
Creo que el problema es que con JS normal, puedo agregar la matriz de marcadores a ambos omse featureGroupimperativamente, pero con React-leaflet, no veo cómo puedo lograr el mismo resultado.
Es el error porque la <Spiderfy>capa no tiene una getLatLngfunción por alguna razón a pesar de que estoy extendiendo MapLayer .
No estoy seguro de lo que debe solucionarse, la versión JS parece funcionar, por lo que es probable que la biblioteca OverlappingMarkerSpiderfier no necesite cambios. ¿Podría ser un problema / limitación específico del folleto de React que posiblemente se pueda solucionar con un FeatureGroup / MapLayer personalizado?
Respuestas
Aparece el error
layer.getLatLng no es una función
ocurre ya que la función FeatureGroup.getBounds espera que las capas subyacentes implementen los métodos getBoundso getLatLng, lo cual no es el caso del Spiderfy.jscomponente personalizado donde el contenedor ( layerContainerprop) es de L.layerGrouptipo.
Una opción a considerar sería refactorizar el Spiderfy.jscomponente:
- abandonar
L.layerGroupcomo contenedor de capas - ya que se utiliza una versión reciente de React (
16.8o superior) reemplace elES6 classcomponente con la función para implementar elSpiderfycomponente
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);
De esta manera, la FeatureGroup.getBoundsfunción debería devolver el resultado esperado, idéntico al proporcionado en la demostración simple de JS .
Ejemplo de bifurcación
Como Vadim señaló correctamente , L.layerGroupno se implementa getBounds.
El principal inconveniente de abandonar un layerGroup es que los componentes que no son hijos del Componente Spiderfy también se transforman en araña, ya que utiliza el layerContainer
- Vea esta demostración . Si miras el registro de la consola, la
markerCountvariable es 4 aunque solo hay tres marcadores como hijos de Spiderfy.
Mirando la documentación de Leaflet, podemos usar L.featureGroup en lugar de layerGroup, ya que es simplemente una extensión de layerGroup.
const el = L.featureGroup([], this.getOptions(props));
- Demostración , puedes ver que la
markerCountvariable es 3 y no 4
Dependiendo de su caso de uso, anidar grupos de características como este no será un problema. Opcionalmente, puede echar un vistazo a los subgrupos