如何在 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,我可以将标记数组命令式地添加到 oms
和 featureGroup
,但是使用 React-leaflet,我不知道该怎么做达到相同的结果。
错误是因为 <Spiderfy>
图层出于某种原因没有 getLatLng
函数,即使我正在扩展 MapLayer.
我不确定需要修复什么,JS 版本似乎可以工作,因此 OverlappingMarkerSpiderfier 库可能不需要更改。它可能是特定于 React-leaflet 的 problem/limitation,可以通过自定义 FeatureGroup/MapLayer?
修复
出现错误
layer.getLatLng is not a function
发生是因为 FeatureGroup.getBounds 函数期望底层实现 getBounds
或 getLatLng
方法,而自定义 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 中提供的相同。
由于,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
当您有复杂的平移逻辑时,我无法集成 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,我可以将标记数组命令式地添加到 oms
和 featureGroup
,但是使用 React-leaflet,我不知道该怎么做达到相同的结果。
错误是因为 <Spiderfy>
图层出于某种原因没有 getLatLng
函数,即使我正在扩展 MapLayer.
我不确定需要修复什么,JS 版本似乎可以工作,因此 OverlappingMarkerSpiderfier 库可能不需要更改。它可能是特定于 React-leaflet 的 problem/limitation,可以通过自定义 FeatureGroup/MapLayer?
修复出现错误
layer.getLatLng is not a function
发生是因为 FeatureGroup.getBounds 函数期望底层实现 getBounds
或 getLatLng
方法,而自定义 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 中提供的相同。
由于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