如何获取反应传单地图的边界并检查地图内的标记?

时间:2021-03-06 18:23:36

标签: javascript reactjs leaflet react-leaflet

我的代码在这里:

import React, { useState, useEffect, useRef } from 'react';
import restaurantsInfo from "./RestaurantsList.json";
import "./App.css";
import { MapContainer, Marker, Popup, TileLayer, useMapEvents } from "react-leaflet";
import { Icon, latLng } from "leaflet";
import Restaurants from "./Restaurants.js";
import LocationMarker from "./LocationMarker.js";
import L from 'leaflet';

export default function App() {
    function LocationMarker() {
        const [position, setPosition] = useState(null);
        const [bbox, setBbox] = useState([]);
    
        const map = useMap();
    
        useEffect(() => {
          map.locate().on("locationfound", function (e) {
            setPosition(e.latlng);
            map.flyTo(e.latlng, map.getZoom());
            const radius = e.accuracy;
            const circle = L.circle(e.latlng, radius);
            circle.addTo(map);
            setBbox(e.bounds.toBBoxString().split(","));
          });
        }, [map]);
    
        return position === null ? null : (
          <Marker position={position} icon={icon}>
            <Popup>
              You are here. <br />
              Map bbox: <br />
              <b>Southwest lng</b>: {bbox[0]} <br />
              <b>Southwest lat</b>: {bbox[1]} <br />
              <b>Northeast lng</b>: {bbox[2]} <br />
              <b>Northeast lat</b>: {bbox[3]}
            </Popup>
          </Marker>
        );
      }
  return (
    <div class="container">
    <div style={{height: '400px', width: '500px'}} class="map">
    <MapContainer 
    center={[49.1951, 16.6068]} 
    zoom={defaultZoom} 
    scrollWheelZoom={false}>
    <TileLayer
      attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
      url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
    />
<MapContainer/>

我的问题是,如何使用 bbox 检查我的某些标记是否在地图内?当我尝试申请时:

if (bbox.contains(marker.getPosition())===true) 

或者这个:

if ((bbox[1] < marker.lat< bbox[3])&& (bbox[2] <marker.long <bbox[4]))

我遇到了错误:bbox 未定义

我不知道如何从 LocationMarker() 函数中返回 bbox。 我将不胜感激任何帮助。谢谢。

1 个答案:

答案 0 :(得分:1)

您需要遵循稍微不同的方法:

在父组件(bbox)上声明 App 变量并存储实例。您将需要它才能稍后使用 contains 方法。您可以将 bboxsetBbox 作为道具传递给 LocationMarker comp。这样做您将在两个组件之间进行通信。

同时将 LocationMarker 组合移到应用程序之外。

这是 LcoationMarker 组件:

function LocationMarker({ bbox, setBbox }) {
  const [position, setPosition] = useState(null);

  const map = useMap();

  useEffect(() => {
    map.locate().on("locationfound", function (e) {
      setPosition(e.latlng);
      map.flyTo(e.latlng, map.getZoom());
      const radius = e.accuracy;
      const circle = L.circle(e.latlng, radius);
      circle.addTo(map);
      setBbox(e.bounds);
    });
  }, [map,setBbox]);

  const boundingBox = bbox ? bbox.toBBoxString().split(",") : null;

  if (!position || !bbox) return null;
  return (
    <Marker position={position} icon={icon}>
      <Popup>
        You are here. <br />
        Map bbox: <br />
        <b>Southwest lng</b>: {boundingBox[0]} <br />
        <b>Southwest lat</b>: {boundingBox[1]} <br />
        <b>Northeast lng</b>: {boundingBox[2]} <br />
        <b>Northeast lat</b>: {boundingBox[3]}
      </Popup>
    </Marker>
  );
}

这里是应用组件。您可以通过按钮在本示例中使用 bbox 。使用前请务必检查 bbox 是否已定义。

function App() {
  const [bbox, setBbox] = useState(null);

  const handleClick = () => {
    if (bbox) alert(bbox.contains([49.1951, 16.6068]));
  };

  return (
    <>
      <MapContainer ...>
     ...
        <LocationMarker bbox={bbox} setBbox={setBbox} />
      </MapContainer>
      <button onClick={handleClick}>bbox contains</button>
    </>
  );
}

这是一个 demo 的所有部分