Comment utiliser FeatureGroup de Leaflet avec OverlappingMarkerSpiderfier dans react-leaflet?

Oct 23 2020

J'ai du mal à intégrer OverlappingMarkerSpiderfier avec React-Leaflet et à utiliser FeatureGroup pour faire un panoramique sur la carte. Les FeatureGroups sont vraiment utiles lorsque vous avez une logique de panoramique compliquée.

Voici une démo JS simple . Les marqueurs spiderfy et le bouton de panoramique fonctionnent sans problème.

Voici la démo Reaflet . Le panoramique échouera avec l'erreur suivante si spiderfy est activé / vérifié dans l'interface utilisateur. Ceci est basé sur ce message SO .

layer.getLatLng is not a function

Je pense que le problème est qu'avec le JS régulier, je peux ajouter le tableau des marqueurs aux deux omset à l' featureGroupimpératif, mais avec React-leaflet, je ne vois pas comment je peux obtenir le même résultat.

Est-ce l'erreur parce que la <Spiderfy>couche n'a pas de getLatLngfonction pour une raison quelconque, même si j'étends le MapLayer .

Je ne suis pas sûr de ce qui doit être corrigé, la version JS semble fonctionner, donc la bibliothèque OverlappingMarkerSpiderfier n'a probablement pas besoin de modifications. Cela pourrait être un problème / limitation spécifique à React-leaflet qui peut éventuellement être corrigé avec un FeatureGroup / MapLayer personnalisé?

Réponses

1 VadimGremyachev Oct 24 2020 at 17:51

Il apparaît l'erreur

layer.getLatLng n'est pas une fonction

se produit puisque la fonction FeatureGroup.getBounds s'attend à ce que les couches sous-jacentes implémentent l'une getBoundsou l' autre des getLatLngméthodes, ce qui n'est pas le cas avec un Spiderfy.jscomposant personnalisé où le conteneur ( layerContainerprop) est de L.layerGrouptype.

Une option à considérer serait de refactoriser le Spiderfy.jscomposant:

  • abandonner en L.layerGrouptant que conteneur de couches
  • puisqu'une version récente de React est utilisée ( 16.8ou supérieure) remplacer le ES6 classcomposant par une fonction pour implémenter le Spiderfycomposant

Spiderfy.js composant

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 cette façon, la FeatureGroup.getBoundsfonction doit retourner le résultat attendu, identique à celui fourni dans la démo JS .

Exemple fourchu

1 LouisChristopher Oct 26 2020 at 06:36

Comme Vadim l'a correctement souligné , L.layerGroupne met pas en œuvre getBounds.

Le principal inconvénient de l'abandon d'un layerGroup est que les composants qui ne sont pas des enfants du composant Spiderfy sont également spiderfiés car il utilise le layerContainer

  • Regardez cette démo . Si vous regardez le journal de la console, la markerCountvariable est 4 même s'il n'y a que trois marqueurs comme enfants de Spiderfy.

En regardant la documentation de Leaflet, nous pouvons utiliser L.featureGroup au lieu d'un layerGroup car il s'agit simplement d'une extension du layerGroup.

const el = L.featureGroup([], this.getOptions(props));

  • Démo , vous pouvez voir que la markerCountvariable est 3 et non 4

Selon votre cas d'utilisation, l'imbrication de groupes de fonctionnalités comme celui-ci ne sera pas un problème. En option, vous pouvez consulter les sous- groupes