使地图适合于React-leaflet中的要素图层范围

时间:2018-12-03 20:51:07

标签: reactjs react-leaflet

我想要实现的目标:

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

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

我尝试过的事情:

  1. FeatureGroup一个ref并在其上调用getBounds以传递到Map上。由于生命周期FeatureGroup在调用componentDidMount时不存在-稍后会呈现(https://github.com/PaulLeCam/react-leaflet/issues/106#issuecomment-161594328)。
  2. 在状态中存储Circle并在其上调用getBounds(在这种情况下,假设只有一个圆圈。那也不起作用。

我认为我可能需要对React Context做些事情,但是我不确定我现在是否完全了解它,因此我需要一些帮助。

其他信息

我正在使用react-leaflet@2.1.2

感谢您提供的任何帮助!

2 个答案:

答案 0 :(得分:1)

由于Map的内容在componentDidMount时(https://github.com/PaulLeCam/react-leaflet/issues/106#issuecomment-161594328)不可用,因此您无法获得FeatureGroup的边界,并且无法获得所有边界如果您分配了refs,则Map中只有this.refs引用可用。

但是,按照以下GitHub评论:https://github.com/PaulLeCam/react-leaflet/issues/106#issuecomment-366263225,您可以为FeatureGroup提供onAdd处理函数:

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

,然后您可以使用Map引用访问leafletElement,并以传入事件目标(将为fitBounds)的边界调用FeatureGroup:< / p>

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

这将根据需要将地图“缩放”到FeatureGroup的边界。

更新

我修改了我的React组件,以便缩放和居中由查询参数控制。上述解决方案的问题是,例如,如果您通过单击来放大MarkerClusterGroup,它将更新url中的缩放比例,重新渲染地图并重新调用onFeatureGroupAdd ,从而消除了所有标记聚类的优势。

我需要的是访问所需的缩放级别,以使新绘制的圆圈很好地保持在边界内,然后使用正确的缩放级别和中心更新网址。

  onDrawCircle = (e) => {
    ...
    var targetZoom = this.refs.map.leafletElement.getBoundsZoom(e.layer.getBounds());
        // Call function to update url here:
        functionToUpdateUrl(targetZoom, e.layer.getBounds().getCenter());
    }
  }

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

  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}>

答案 1 :(得分:0)

您是否尝试过在getBounds函数而不是componentDidMount中执行componentWillMount?如果那不起作用,那么我建议扩展FeatureGroup组件并添加一个onLoaded函数作为prop,然后在扩展组件的componentDidMount函数中调用该函数。通过扩展FeatureGroup组件,我实际上是指从here复制/粘贴它。 (如果您担心为什么需要复制整个文件,请检查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,则实际上更容易,我可以根据需要用该代码编辑此答案。