如何调用在实时位置到达标记位置时显示"You've reached your destination"警报的函数?ReactJS 和 Leaflet



我结合了两个教程来找到我的位置,并在地图上放置了一个标记:

https://stackblitz.com/edit/react-fkhpjp?file=index.js

https://www.youtube.com/watch?v=PMtXhxW6t2k

我怎样才能调用一个显示";您已到达目的地";实时位置到达标记位置时发出警报?

我的代码:

App.js

import React, {Component} from 'react';
import Map from './components/Map'
class App extends React.Component {

render(){
return(

<div>
<h1>test</h1>
<Map zoom={4} center={{ lat: 39.74739, lng: -105 }} />
</div>

)

}

}
export default App;

Map.js

import React, { Component } from "react";
import { Map, TileLayer, Marker, Popup } from "react-leaflet";
import LocateControl from './LocateControl';
import L from 'leaflet';
import leafGreen from '../assets/leaf-green.png';
import leafShadow from '../assets/leaf-shadow.png';

export default class MapExample extends Component {
state = {
greenIcon:{
lat: 39.74739,
lng: -105.00019,
}
}
greenIcon = L.icon({
iconUrl: leafGreen,
shadowUrl: leafShadow,
iconSize: [38, 95], // size of the icon
shadowSize: [50, 64], // size of the shadow
iconAnchor: [22, 94], // point of the icon which will correspond to marker's location
shadowAnchor: [4, 62], // the same for the shadow
popupAnchor: [-3, -76] // point from which the popup should open relative to the iconAnchor
})
render() {
const locateOptions = {
position: 'topright',
strings: {
title: 'Show me where I am, yo!'
},
onActivate: () => {} // callback before engine starts retrieving locations
}
// SHOW CURRENT LOCATION 
const positionGreenIcon = [this.state.greenIcon.lat, this.state.greenIcon.lng]
return (
<Map center={this.props.center} zoom={this.props.zoom}>
{/* MAP LAYER */}
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
/>
{/* CURRENT LOCATION */}
<LocateControl options={locateOptions} startDirectly/>
{/* DESTINATION LOCATION  */}
<Marker position={positionGreenIcon} icon={this.greenIcon}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>
</Map>
);
}
}

LocateControl.js

import React, { Component } from "react";
import { withLeaflet } from "react-leaflet";
import Locate from "leaflet.locatecontrol";
class LocateControl extends Component {
componentDidMount() {
const { options, startDirectly } = this.props;
const { map } = this.props.leaflet;
const lc = new Locate(options);
lc.addTo(map);
console.log("lclc: ", startDirectly)
if (startDirectly) {
// request location update and set location
lc.start();
}
}
render() {
return null;
}
}
export default withLeaflet(LocateControl);

谢谢!

现在,您有了要在两个独立组件中进行比较的两点。为了能够比较它们,您需要将它们放在同一组件中。让我们将用户的当前位置添加到中,作为Map状态的一部分:

// Map.js
state = {
greenIcon:{
lat: 39.74739,
lng: -105.00019,
},
userLocation: undefined,
}

它一开始是未定义的,因为在组件装载时,我们还不知道。只有在安装LocateControl并开始运行传单定位控制后,我们才能知道用户的位置。但是,我们应该传递一个函数,将这个userLocation状态变量更新为LocateControl,以便LocateControl可以设置Map组件的状态。

// Still in Map.js
updateUserLocation = userLocation => {
this.setState({
...this.state,
userLocation: userLocation 
})
}
// inside your render function:
<LocateControl 
options={locateOptions} 
startDirectly 
updateUserLocation={this.updateUserLocation} />

现在,在LocateControl中,您可以调用此函数并更新Map的状态。我查看了传单位置控制,似乎找不到当用户的位置更新时(onlocationfound?(我们可以使用什么方法来捕捉。但您似乎在if (startDirectly)语句中的LocateControl代码中注释掉了它。我们将把我们的函数称为该语句中的道具:

// LocateControl.js
...
componentDidMount(){
if (startDirectly) {
// request location update and set location
lc.start();
const location = ?  // not sure how location is extracted from this plugin - are you?
this.props.updateUserLocation(location)
}
}
...

因此,现在,随着传单locatecontrol的每次更新,Map组件都会以自己的状态更新用户的位置。我们可以在Map组件中的componentDidUpdate语句中对这些更改进行操作:

// Map.js again
componentDidUpdate(prevState){
if (prevState.userLocation !== this.state.userLocation){
// run a check here to see if the desination and user location are close together
}
}

您可以使用map.distance为地图快速计算两点之间的距离。但你需要一份地图的参考资料。

// still Map.js
// root level of class declaration
mapRef = React.createRef()
// inside render:

<Map ref={this.mapRef} center={...} zoom={...}></Map>

componentDidUpdate中,您现在可以使用此ref来使用map提供给您的所有方法,包括distance:

// Map.js
componentDidUpdate(prevState){
if (prevState.userLocation !== this.state.userLocation){
const map = this.mapRef.current.leafletElement
if (map.distance(this.state.userLocation, desination) < 10){
alert("You've reached within 10 meters of your destination")
}
}
}

好的!这需要很多步骤。为了完成,这里有Map组件和所有添加:

**import React, { Component } from "react";
import { Map, TileLayer, Marker, Popup } from "react-leaflet";
import LocateControl from './LocateControl';
import L from 'leaflet';
import leafGreen from '../assets/leaf-green.png';
import leafShadow from '../assets/leaf-shadow.png';

export default class MapExample extends Component {
mapRef = React.createRef()
state = {
greenIcon:{
lat: 39.74739,
lng: -105.00019,
},
userLocation: undefined,
}
componentDidUpdate(prevState){
if (prevState.userLocation !== this.state.userLocation){
const map = this.mapRef.current.leafletElement
if (map.distance(this.state.userLocation, desination) < 10){
alert("You've reached within 10 meters of your destination")
}
}
}
updateUserLocation = userLocation => {
this.setState({
...this.state,
userLocation: userLocation 
})
}
greenIcon = L.icon({
iconUrl: leafGreen,
shadowUrl: leafShadow,
iconSize: [38, 95], // size of the icon
shadowSize: [50, 64], // size of the shadow
iconAnchor: [22, 94], // point of the icon which will correspond to marker's location
shadowAnchor: [4, 62], // the same for the shadow
popupAnchor: [-3, -76] // point from which the popup should open relative to the iconAnchor
})
render() {
const locateOptions = {
position: 'topright',
strings: {
title: 'Show me where I am, yo!'
},
onActivate: () => {} // callback before engine starts retrieving locations
}
// SHOW CURRENT LOCATION 
const positionGreenIcon = [this.state.greenIcon.lat, this.state.greenIcon.lng]
return (
<Map ref={this.mapRef} center={this.props.center} zoom={this.props.zoom}>
{/* MAP LAYER */}
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
/>
{/* CURRENT LOCATION */}
<LocateControl options={locateOptions} startDirectly updateUserLocation={this.updateUserLocation}/>
{/* DESTINATION LOCATION  */}
<Marker position={positionGreenIcon} icon={this.greenIcon}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>
</Map>
);
}
}**

最新更新