¿Cómo utilizar FeatureGroup de Leaflet con OverlappingMarkerSpiderfier en react-leaflet?

Oct 23 2020

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

1 VadimGremyachev Oct 24 2020 at 17:51

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 el ES6 classcomponente con la función para implementar el Spiderfycomponente

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

1 LouisChristopher Oct 26 2020 at 06:36

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