将地图拟合到 react-leaflet 中的要素层边界

IT技术 reactjs react-leaflet
2021-05-05 18:00:12

我想要达到的目标:

具有<Map><FeatureGroup><Circle />[1 or more]...</FeatureGroup></Map>层次结构并使地图边界适合要素组,以便所有圆圈都在视口中。

如果只有一个圆,它应该适合该圆的边界(即:放大)。

我试过的:

  1. 给出FeatureGrouparef并要求getBounds它传递给Map由于生命周期FeatureGroupcomponentDidMount调用时不存在- 它稍后呈现(https://github.com/PaulLeCam/react-leaflet/issues/106#issuecomment-161594328)。
  2. 存储Circle在 state 中并调用 getBounds (假设,在这种情况下,只有一个圆圈。那也不起作用。

我想我可能需要对 React Context 做一些事情,但我不确定我现在是否完全理解它,所以我需要一些帮助。

其他信息

我正在使用 react-leaflet@2.1.2

感谢您提供的任何帮助!

2个回答

因为 的内容MapcomponentDidMount-time不可用https://github.com/PaulLeCam/react-leaflet/issues/106#issuecomment-161594328)你无法FeatureGroup在那个时候得到的界限,而且 refs你分配,只有Mapref 将在this.refs.

然而,按本GitHub的评论:https://github.com/PaulLeCam/react-leaflet/issues/106#issuecomment-366263225你可以给FeatureGroup一个onAdd处理函数:

<FeatureGroup ref="features" onAdd={this.onFeatureGroupAdd}>...

然后您可以使用Maprefs 访问leafletElement并调用fitBounds传入事件目标的边界,这将是FeatureGroup

  onFeatureGroupAdd = (e) => {
    this.refs.map.leafletElement.fitBounds(e.target.getBounds());
  }

然后,这将FeatureGroup根据需要将地图“放大”到您的 边界

更新

我修改了我的 React 组件,以便缩放和中心由查询参数控制。上述解决方案的问题在于MarkerClusterGroup,例如,如果您通过单击放大 a ,它将更新 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());
    }
  }

为了能够控制整个地图,我还调用functionToUpdateUrlonZoomEndonDragEnd事件处理程序,如下所示:

  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>

并记住给 anyMarkerClusterGrouponClusterClick回调:

<MarkerClusterGroup onAdd={this.onMarkerGroupAdd} onClusterClick={this.onClusterClick}>

你有没有试过getBoundscomponentDidMount函数中而不是componentWillMount? 如果这不起作用,那么我建议扩展FeatureGroup组件并添加一个onLoaded函数作为 prop 并在componentDidMount扩展组件函数中调用该函数通过扩展FeatureGroup组件,我实际上是指从这里复制/粘贴它(如果您关心为什么需要复制整个文件,请检查线程)

这未经测试,但您的代码可能看起来像

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-leafletV1,这实际上更容易,如果需要,我可以使用该代码编辑此答案。