如何获取 react-leaflet 地图的边界并检查地图内的标记?
How to get borders for the react-leaflet map and check markers inside the map?
我的代码在这里:
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='© <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() return bbox。
如果有任何帮助,我将不胜感激。谢谢。
然后您需要采用稍微不同的方法:
在父组件(App
) 上声明bbox
变量并存储实例。您将需要它以便稍后能够使用 contains 方法。您可以将 bbox
和 setBbox
作为 LocationMarker comp 的道具传递。这样你就可以在两个组件之间进行通信。
同时将 LocationMarker
comp 移到 App 之外。
这是 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>
);
}
这是 App 组件。您可以通过按钮在此示例中使用 bbox isntance。请确保在使用前检查 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 所有部分都放在一起的
我的代码在这里:
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='© <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() return bbox。 如果有任何帮助,我将不胜感激。谢谢。
然后您需要采用稍微不同的方法:
在父组件(App
) 上声明bbox
变量并存储实例。您将需要它以便稍后能够使用 contains 方法。您可以将 bbox
和 setBbox
作为 LocationMarker comp 的道具传递。这样你就可以在两个组件之间进行通信。
同时将 LocationMarker
comp 移到 App 之外。
这是 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>
);
}
这是 App 组件。您可以通过按钮在此示例中使用 bbox isntance。请确保在使用前检查 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 所有部分都放在一起的