Como usar o FeatureGroup do Leaflet com OverlappingMarkerSpiderfier no react-leaflet?
Estou tendo problemas para integrar OverlappingMarkerSpiderfier ao React-Leaflet e usar o FeatureGroup para deslocar o mapa. FeatureGroups são realmente úteis quando você tem uma lógica panorâmica complicada.
Aqui está uma demonstração simples de JS . Os marcadores spiderfy e o botão panorâmico funcionam sem problemas.
Aqui está a demonstração do folheto reativo . A panorâmica falhará com o seguinte erro se spiderfy estiver habilitado / verificado na IU. Isso é baseado neste post do SO .
layer.getLatLng is not a function
Acho que o problema é que com JS regular, posso adicionar o array markers a ambos omse ao featureGroupimperativamente, mas com React-leaflet, não vejo como posso obter o mesmo resultado.
É o erro porque a <Spiderfy>camada não tem getLatLngfunção por algum motivo mesmo estando estendendo o MapLayer .
Não tenho certeza do que precisa ser consertado, a versão JS parece funcionar, então a biblioteca OverlappingMarkerSpiderfier provavelmente não precisa de alterações. Pode ser um problema / limitação específico do folheto React que pode ser corrigido com um FeatureGroup / MapLayer personalizado?
Respostas
Parece que o erro
layer.getLatLng não é uma função
ocorre porque a função FeatureGroup.getBounds espera que as camadas subjacentes implementem um dos métodos getBoundsou getLatLng, o que não é o caso com o Spiderfy.jscomponente personalizado em que o contêiner ( layerContainerprop) é do L.layerGrouptipo.
Uma opção a ser considerada seria refatorar o Spiderfy.jscomponente:
- abandonar
L.layerGroupcomo um recipiente de camada - uma vez que uma versão recente do React é utilizada (
16.8ou acima), substitua oES6 classcomponente pela função para implementar oSpiderfycomponente
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);
Dessa forma, a FeatureGroup.getBoundsfunção deve retornar o resultado esperado, idêntico ao fornecido na demonstração JS simples .
Exemplo bifurcado
Como Vadim corretamente apontou , L.layerGroupnão implementa getBounds.
A principal desvantagem de abandonar um layerGroup é que os componentes que não são filhos do componente Spiderfy também são spiderficados, pois ele usa o layerContainer
- Veja esta demonstração . Se você olhar o log do console, a
markerCountvariável é 4, embora haja apenas três marcadores como filhos de Spiderfy.
Olhando a documentação do Leaflet, podemos usar L.featureGroup em vez de um layerGroup, pois é simplesmente uma extensão do layerGroup.
const el = L.featureGroup([], this.getOptions(props));
- Demo , você pode ver que a
markerCountvariável é 3 e não 4
Dependendo do seu caso de uso, aninhar grupos de recursos como este não será um problema. Opcionalmente, você pode dar uma olhada nos subgrupos