如何在 react-leaflet 中使用带有 OverlappingMarkerSpiderfier 的 Leaflet 的 FeatureGroup?

How to use Leaflet's FeatureGroup with OverlappingMarkerSpiderfier in react-leaflet?

当您有复杂的平移逻辑时,我无法集成 OverlappingMarkerSpiderfier with React-Leaflet and using FeatureGroup for panning on the map. FeatureGroups are really useful

这里是plain JS demo。标记 spiderfy 和平移按钮没有问题。

这里是 react-leaflet demo. The panning will fail with the following error if spiderfy is enabled/checked in the UI. This is based on this .

layer.getLatLng is not a function

我认为问题在于使用常规 JS,我可以将标记数组命令式地添加到 omsfeatureGroup,但是使用 React-leaflet,我不知道该怎么做达到相同的结果。

错误是因为 <Spiderfy> 图层出于某种原因没有 getLatLng 函数,即使我正在扩展 MapLayer.

我不确定需要修复什么,JS 版本似乎可以工作,因此 OverlappingMarkerSpiderfier 库可能不需要更改。它可能是特定于 React-leaflet 的 problem/limitation,可以通过自定义 FeatureGroup/MapLayer?

修复

出现错误

layer.getLatLng is not a function

发生是因为 FeatureGroup.getBounds 函数期望底层实现 getBoundsgetLatLng 方法,而自定义 Spiderfy.js component 则不是这种情况,其中容器 (layerContainer prop) 属于 L.layerGroup 类型。

要考虑的一个选项是重构 Spiderfy.js 组件:

  • 放弃L.layerGroup作为图层容器
  • 由于使用了最新的 React 版本(16.8 或更高版本)将 ES6 class 组件替换为实现 Spiderfy 组件
  • 的功能

Spiderfy.js分量

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);

这样 FeatureGroup.getBounds 函数应该 return 预期的结果,与 plain JS demo 中提供的相同。

Forked example

由于L.layerGroup没有实现getBounds

放弃 layerGroup 的主要缺点是,不是 children 的 Spiderfy 组件的组件也会被蜘蛛化,因为它使用 layerContainer

  • 看到这个 demo。如果您查看控制台日志,markerCount 变量为 4,即使只有三个标记如 Spiderfy 的 children.

查看 Leaflet 的文档,我们可以使用 L.featureGroup 而不是 layerGroup,因为它只是 layerGroup 的扩展。

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

  • Demo,可以看到markerCount变量是3而不是4

根据您的用例,像这样嵌套功能组不会有问题。您可以选择查看 SubGroups