Comment utiliser FeatureGroup de Leaflet avec OverlappingMarkerSpiderfier dans react-leaflet?
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
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 leES6 classcomposant par une fonction pour implémenter leSpiderfycomposant
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
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