将地图拟合到 react-leaflet 中的要素层边界
Fit map to feature layer bounds in react-leaflet
我想达到的目标:
具有 <Map><FeatureGroup><Circle />[1 or more]...</FeatureGroup></Map>
层次结构并使地图边界适合要素组,以便所有圆圈都在视口中。
如果只有一个圆圈,它应该适合该圆圈的边界(即:放大)。
我尝试过的:
- 给
FeatureGroup
一个 ref
并在其上调用 getBounds
以传递给 Map
。由于生命周期 FeatureGroup
在调用 componentDidMount
时不存在 - 它稍后呈现 (https://github.com/PaulLeCam/react-leaflet/issues/106#issuecomment-161594328)。
- 在状态中存储
Circle
并在其上调用 getBounds(假设,在这种情况下,只有一个圆圈。那也不起作用。
我想我可能需要对 React Context 做些什么,但我不确定我现在是否完全理解它,所以我需要一些帮助。
其他信息
我正在使用 react-leaflet@2.1.2
感谢您提供的任何帮助!
您是否尝试过在 componentDidMount
函数中执行 getBounds
而不是 componentWillMount
?如果这不起作用,那么我建议扩展 FeatureGroup
组件并添加一个 onLoaded
函数作为 prop 并在扩展组件的 componentDidMount
函数中调用该函数。通过扩展 FeatureGroup
组件,我实际上是指 copying/pasting 来自 here. (if you care about why you need to copy that whole file check this 线程)
这没有经过测试,但您的代码可能类似于
import { FeatureGroup } from 'leaflet';
import { withLeaflet, Path } from 'react-leaflet';
class CustomFeatureGroup extends Path {
createLeafletElement(prop) {
const el = new FeatureGroup(this.getOptions(props));
this.contextValue = {
...props.leaflet,
layerContainer: el,
popupContainer: el,
};
return el;
}
componentDidMount() {
super.componentDidMount();
this.setStyle(this.props);
/*
Here you can do your centering logic with an onLoad callback or just
by using this.leafletElement.map or whatever
*/
this.props.onLoaded();
}
}
export default withLeaflet(CustomFeatureGroup)
注意:如果您使用的是 react-leaflet
V1,这实际上更容易,如果需要,我可以使用该代码编辑此答案。
因为 Map
的内容在 componentDidMount
-time (https://github.com/PaulLeCam/react-leaflet/issues/106#issuecomment-161594328) 时不可用,你无法在那个时候获得 FeatureGroup
的边界,并且出在您分配的所有 refs
中,只有 Map
ref 将在 this.refs
.
中可用
然而,根据这个 GitHub 评论:https://github.com/PaulLeCam/react-leaflet/issues/106#issuecomment-366263225 你可以给一个 FeatureGroup
一个 onAdd
处理函数:
<FeatureGroup ref="features" onAdd={this.onFeatureGroupAdd}>...
然后您可以使用 Map
refs 访问 leafletElement
并使用传入事件目标的边界调用 fitBounds
,这将是 FeatureGroup
:
onFeatureGroupAdd = (e) => {
this.refs.map.leafletElement.fitBounds(e.target.getBounds());
}
这将根据需要将地图“缩放”到您 FeatureGroup
的范围内。
更新
我修改了我的 React 组件,以便缩放和居中由查询参数控制。上述解决方案的问题是,如果您通过单击放大 MarkerClusterGroup
,例如,它会更新 url 中的缩放,重新渲染地图并重新调用 onFeatureGroupAdd
,从而消除所有标记簇的优点。
我需要的是访问将新绘制的圆很好地保持在边界内所需的缩放级别,然后使用正确的缩放级别和中心更新 url。
onDrawCircle = (e) => {
...
var targetZoom = this.refs.map.leafletElement.getBoundsZoom(e.layer.getBounds());
// Call function to update url here:
functionToUpdateUrl(targetZoom, e.layer.getBounds().getCenter());
}
}
为了能够控制整个地图,我还在 onZoomEnd
和 onDragEnd
事件处理程序中调用了 functionToUpdateUrl
,如下所示:
onChangeView = (e) => {
functionToUpdateUrl(e.target._zoom, this.refs.map.leafletElement.getCenter());
}
还有一个用于处理集群点击:
onClusterClick = (e) => {
// This time we want the center of the layer, not the map?
functionToUpdateUrl(e.target._zoom, (e.layer ? e.layer.getBounds().getCenter() : e.target.getBounds().getCenter()));
}
然后,在渲染 Map 元素时,传递这些属性:
<Map
center={center}
ref='map'
zoom={zoom}
maxZoom={18}
onZoomEnd={this.onChangeView}
onDragEnd={this.onChangeView}
>
....
</Map>
并记得给任何MarkerClusterGroup
他们的onClusterClick
回调:
<MarkerClusterGroup onAdd={this.onMarkerGroupAdd} onClusterClick={this.onClusterClick}>
我想达到的目标:
具有 <Map><FeatureGroup><Circle />[1 or more]...</FeatureGroup></Map>
层次结构并使地图边界适合要素组,以便所有圆圈都在视口中。
如果只有一个圆圈,它应该适合该圆圈的边界(即:放大)。
我尝试过的:
- 给
FeatureGroup
一个ref
并在其上调用getBounds
以传递给Map
。由于生命周期FeatureGroup
在调用componentDidMount
时不存在 - 它稍后呈现 (https://github.com/PaulLeCam/react-leaflet/issues/106#issuecomment-161594328)。 - 在状态中存储
Circle
并在其上调用 getBounds(假设,在这种情况下,只有一个圆圈。那也不起作用。
我想我可能需要对 React Context 做些什么,但我不确定我现在是否完全理解它,所以我需要一些帮助。
其他信息
我正在使用 react-leaflet@2.1.2
感谢您提供的任何帮助!
您是否尝试过在 componentDidMount
函数中执行 getBounds
而不是 componentWillMount
?如果这不起作用,那么我建议扩展 FeatureGroup
组件并添加一个 onLoaded
函数作为 prop 并在扩展组件的 componentDidMount
函数中调用该函数。通过扩展 FeatureGroup
组件,我实际上是指 copying/pasting 来自 here. (if you care about why you need to copy that whole file check this 线程)
这没有经过测试,但您的代码可能类似于
import { FeatureGroup } from 'leaflet';
import { withLeaflet, Path } from 'react-leaflet';
class CustomFeatureGroup extends Path {
createLeafletElement(prop) {
const el = new FeatureGroup(this.getOptions(props));
this.contextValue = {
...props.leaflet,
layerContainer: el,
popupContainer: el,
};
return el;
}
componentDidMount() {
super.componentDidMount();
this.setStyle(this.props);
/*
Here you can do your centering logic with an onLoad callback or just
by using this.leafletElement.map or whatever
*/
this.props.onLoaded();
}
}
export default withLeaflet(CustomFeatureGroup)
注意:如果您使用的是 react-leaflet
V1,这实际上更容易,如果需要,我可以使用该代码编辑此答案。
因为 Map
的内容在 componentDidMount
-time (https://github.com/PaulLeCam/react-leaflet/issues/106#issuecomment-161594328) 时不可用,你无法在那个时候获得 FeatureGroup
的边界,并且出在您分配的所有 refs
中,只有 Map
ref 将在 this.refs
.
然而,根据这个 GitHub 评论:https://github.com/PaulLeCam/react-leaflet/issues/106#issuecomment-366263225 你可以给一个 FeatureGroup
一个 onAdd
处理函数:
<FeatureGroup ref="features" onAdd={this.onFeatureGroupAdd}>...
然后您可以使用 Map
refs 访问 leafletElement
并使用传入事件目标的边界调用 fitBounds
,这将是 FeatureGroup
:
onFeatureGroupAdd = (e) => {
this.refs.map.leafletElement.fitBounds(e.target.getBounds());
}
这将根据需要将地图“缩放”到您 FeatureGroup
的范围内。
更新
我修改了我的 React 组件,以便缩放和居中由查询参数控制。上述解决方案的问题是,如果您通过单击放大 MarkerClusterGroup
,例如,它会更新 url 中的缩放,重新渲染地图并重新调用 onFeatureGroupAdd
,从而消除所有标记簇的优点。
我需要的是访问将新绘制的圆很好地保持在边界内所需的缩放级别,然后使用正确的缩放级别和中心更新 url。
onDrawCircle = (e) => {
...
var targetZoom = this.refs.map.leafletElement.getBoundsZoom(e.layer.getBounds());
// Call function to update url here:
functionToUpdateUrl(targetZoom, e.layer.getBounds().getCenter());
}
}
为了能够控制整个地图,我还在 onZoomEnd
和 onDragEnd
事件处理程序中调用了 functionToUpdateUrl
,如下所示:
onChangeView = (e) => {
functionToUpdateUrl(e.target._zoom, this.refs.map.leafletElement.getCenter());
}
还有一个用于处理集群点击:
onClusterClick = (e) => {
// This time we want the center of the layer, not the map?
functionToUpdateUrl(e.target._zoom, (e.layer ? e.layer.getBounds().getCenter() : e.target.getBounds().getCenter()));
}
然后,在渲染 Map 元素时,传递这些属性:
<Map
center={center}
ref='map'
zoom={zoom}
maxZoom={18}
onZoomEnd={this.onChangeView}
onDragEnd={this.onChangeView}
>
....
</Map>
并记得给任何MarkerClusterGroup
他们的onClusterClick
回调:
<MarkerClusterGroup onAdd={this.onMarkerGroupAdd} onClusterClick={this.onClusterClick}>