簡體   English   中英

如何跟蹤 map 放大反應 leaflet

[英]How to track map zoom in react leaflet

在左側的頁面上,我有一個 map,在右側我有一個地點列表。 map 的標記和來自數據庫的地點列表。 我需要跟蹤 map 縮放以過濾地點列表並刪除那些標記不可見的地點。 我怎樣才能做到這一點? 如何跟蹤 map 縮放並實現這樣的邏輯?

 const Map = ({ onSelect }) => { const [coordinates, setCoordinates] = useState([]); useEffect(() => { const q = query(collection(db, "map-markers")); onSnapshot(q, (querySnapshot) => { setCoordinates( querySnapshot.docs.map((doc) => ({ id: doc.id, data: doc.data(), })) ); }); }, []); return ( <div style={{ width: "100%" }}> <MapContainer center={center} zoom={13} scrollWheelZoom={false} style={{ height: "100vh" }} > <TileLayer attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" /> {coordinates.map((coord, index) => ( <Marker key={index} eventHandlers={{ click: () => { onSelect(index); }, }} position={[parseFloat(coord.data.lat), parseFloat(coord.data.lon)]} icon={defaultIcon} /> ))} </MapContainer> </div> ); };

 const List = ({ selectedHouse }) => { const [houseTitles, setHouseTitle] = useState([]); useEffect(() => { const q = query(collection(db, "map-markers")); onSnapshot(q, (querySnapshot) => { setHouseTitle( querySnapshot.docs.map((doc) => ({ id: doc.id, data: doc.data(), })) ); }); }, []); return ( <div style={{ width: "50%" }}> {houseTitles.map((title, index) => ( <ListItem key={index} title={title.data.title} /> ))} </div> ); };

假設您的組件結構如下:

<Parent>
  <List />
  <Map />
</Parent>

您可以將 state 提升到Parent組件中(因此Parent負責獲取數據並將其存儲在 React 的useState )。 您需要定義 2 個狀態: allHouses (房屋的完整列表)和visibleHouses (基於 map 邊界的房屋):

const [allHouses, setAllHouses] = useState([
  {
    id: 1,
    data: {
      title: 'House 1',
      lat: 52.074,
      lon: 5.217,
    },
  },
  {
    id: 2,
    data: {
      title: 'House 2',
      lat: 52.07222,
      lon: 5.221965,
    },
  },
  {
    id: 2,
    data: {
      title: 'House 3',
      lat: 52.07,
      lon: 5.215,
    },
  },
]);

const [visibleHouses, setVisibleHouses] = useState(allHouses);

為簡單起見,我對數據進行了硬編碼,而不是從 API 中獲取數據。

然后可以將 state 傳遞給ListMap組件:

<List visibleHouses={visibleHouses} />
<Map
  ...
  allHouses={allHouses}
  setVisibleHouses={setVisibleHouses}
/>

只有visibleHouses需要傳遞給List組件,因為我們只想顯示基於 map 邊界的可見房屋列表。 We'll need to pass allHouses along with the setVisibleHouses state setter to the Map component so that we can render all the houses on the map, and update the list of visible houses as the user moves or zooms the map.

您可以使用事件來偵聽 map 移動 ( dragend ) 或縮放事件 ( zoomend ),然后根據每個房屋是否在map的當前范圍內更新visibleHouses

function MyComponent() {
  const map = useMapEvents({
    dragend: () => {
      console.log('moved');

      setVisibleHouses(
        allHouses.filter((c) =>
          map.getBounds().contains({ lat: c.data.lat, lng: c.data.lon })
        )
      );
    },
    zoomend: () => {
      console.log('zoomed');

      setVisibleHouses(
        allHouses.filter((c) =>
          map.getBounds().contains({ lat: c.data.lat, lng: c.data.lon })
        )
      );
    },
  });
  return null;
}

因為List組件呈現visibleHouses ,所以每當這個 state 作為 map 移動或縮放的結果而更新時,它將導致列表相應地更新。

這個 StackBlitz展示了這個的工作演示。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM