繁体   English   中英

使用 LayersControl 处理对象数据的 React Leaflet

[英]React Leaflet with LayersControl handling object datas

我想要一张使用 OpenStreetMap 显示鲜花位置的地图。 我的观点是让LayersControl具有colourstype ,并且能够检查例如OrangeTulip ,并在地图上只看到橙色郁金香,但从我在 React LeafLet 文档中阅读的内容来看似乎很难。

为了更容易理解,我将添加一些代码:

花数据示例:

const flowers = [
  {
    "type": "Tulip",
    "colour": "Orange",
    "latlng": [52.081222, 5.235965],
  },
  {
    "type": "Crocus",
    "colour": "Red",
    "latlng": [52.081421, 5.235534],
  },
]

LeafletMap.jsx (部分):

const LeafletMap: React.FC = () => {

return (
     <MapContainer id="mapId"
          center={averagePos}
          zoom={zoom}>
            {flowerItems.map((flower, index) => (
              //Maybe do something here like sorting and creating 
              //multiple layers
              //or having already a layer for every type of search 
              //but if i want to add more colours ou type it can be very hard to update
            ))}
        </LayersControl>
     </MapContainer>
   )
}

您可以使用状态变量维护选定的图层 - 一个数组用于跟踪type (Crocus 或 Tulip),另一个用于跟踪colour (红色或橙色)。 最初,状态设置为显示所有内容:

const [type, setType] = useState(['Tulip', 'Crocus']);
const [colour, setColour] = useState(['Orange', 'Red']); 

对于每种typecolour ,您可以创建一个LayersControl ,您可以在其中挂钩addremove事件处理程序,并在用户选中或取消选中图层时更新相应的状态( typecolour ):

<LayersControl.Overlay name="Crocus" checked="true">
  <LayerGroup
    eventHandlers={{
      add: (e) => {
        updateTypeState('Crocus', true);
      },
      remove: (e) => {
        updateTypeState('Crocus', false);
      },
    }}
  ></LayerGroup>
</LayersControl.Overlay>

更新状态的函数如下所示(有一个更新type的函数和一个更新colour的函数):

  const updateTypeState = (key: string, value: boolean) => {
    setType((prevState) => {
      if (value) {
        prevState = [...prevState, key];
      } else {
        prevState = prevState.filter((e) => e !== key);
      }
      console.log(prevState);
      return prevState;
    });
  };

  const updateColourState = (key: string, value: boolean) => {
    setColour((prevState) => {
      if (value) {
        prevState = [...prevState, key];
      } else {
        prevState = prevState.filter((e) => e !== key);
      }
      return prevState;
    });
  };

然后,您可以按照您的建议使用map函数渲染标记:

{flowers
  .filter((flower) => {
    if (type.length == 0 && colour.length == 0) {
      // No layers selected, so show all
      return true;
    }
    if (type.length > 0 && colour.length > 0) {
      // Colours and types selected
      return (
        type.indexOf(flower.type) >= 0 &&
        colour.indexOf(flower.colour) >= 0
      );
    }
    if (type.length > 0) {
      // Type selected, no colour selected
      return type.indexOf(flower.type) >= 0;
    }
    // Colour selected, no type selected
    return colour.indexOf(flower.colour) >= 0;
  })
  .map((flower, index) => (
    <Marker position={flower.latlng}>
      <Popup>
        {flower.type}, {flower.colour}
      </Popup>
    </Marker>
  ))}

这里有一个正在工作的StackBlitz ,但请注意,由于此问题,标记图像无法正确显示,但您应该能够看到损坏的图像图标并单击它以查看花朵的详细信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM