在React中创建自定义Leaflet图层控件

时间:2019-01-18 21:28:37

标签: reactjs leaflet

我正在尝试使用react-leaflet在其自己的单独面板中完全重新创建或重组LayersControl组件的功能。

我已经过滤了几种,并且效果很好,但是我想自定义Control元素的外观和位置。

我已经在github页面here上托管了我的Leaflet应用程序的当前版本。您可以在右侧看到该控件,它是基本的Leaflet控件,但是我想在左侧的Icon(图层图标)来完成相同的操作,而不是使用自定义的react组件。

只是想知道是否有人可以指出正确的方向来开始实现这一目标!

这是我当前的反应传单地图渲染:

AddSigningCredential(Certificate.GetCertificate())

3 个答案:

答案 0 :(得分:1)

因此,这里仍然存在一些错误,但是我已经设法通过使用实质性UI来获得大部分方式(自学成才),可以在以下沙箱链接中看到:

https://codesandbox.io/embed/competent-edison-wt5pl?fontsize=14

一般的bassis是我们扩展了MapControl,这意味着我们必须定义createLeafletElement,这必须从原始javascript传单包中返回通用传单(不反应)控件。本质上是使用传单提供的domutil进行div划分,然后使用react门户通过该div进入我们的react组件。

再加上另一个类扩展,我们将react-leaflet提供的一些类扩展到层,我将其拉出,然后制作了一个通用层,可以为其定义组,这样您就可以渲染任何层(多边形,基本层等),并指定组以告知其在层控件中的位置,即不需要特定的组件或叠加层。在扩展类时,我们需要实现并传递要使用的方法,例如addLayer,remove layer等。在这些实现期间,我只是将其添加到状态中以跟踪哪些层处于活动状态等。

不确定我实施的所有方法中是否都有更好的做法,但这绝对是一个开始,希望朝着正确的方向前进。

错误-如果未勾选第二项,则每个组中的第一层都无法正确打开,这与我认为的状态有关,但没有时间进行追踪

答案 1 :(得分:0)

仅说明Dylans答案中提到的错误...

如果您有一个以上的ControlledLayerItem,则不会将任何项目添加到地图中,直到检查了最后一项。要解决此问题,必须对ControlLayer2.js中的toggleLayer方法进行一些修改:

toggleLayer = layerInput => {
 const { layer, name, checked, group } = layerInput;

 let layers = { ...this.state.layers };
 layers[group] = layers[group].map(l => {
  if (l.name === name) {
    l.checked = !l.checked;

    l.checked
        ? this.props.leaflet.map.addLayer(layer)
        : this.removeLayer(layer);
  }
  return l;
 });

 this.setState({
  layers
 });
};

感谢Dylan提供的代码,它真的很有帮助。

答案 2 :(得分:0)

感谢Dylan和Peter提供了出色的React Leaflet自定义控件方法。我认为toggleLayer函数中仍然存在错误。它选中了多个复选框,并且图层不会正确更改。所以我进行了一些重组,现在应该可以正常工作了。

toggleLayer = layerInput => {
    const { name, group } = layerInput;
    let layers = { ...this.state.layers };

    layers[group] = layers[group].map(l => {
        l.checked = false;
        this.removeLayer(l.layer);
        if (l.name === name) {
            l.checked = !l.checked;
            this.props.leaflet.map.addLayer(l.layer);
        } 
        return l;
    });

    this.setState({
        layers
    });
};