我结合了两个教程来找到我的位置,并在地图上放置了一个标记:
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='© <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='© <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>
);
}
}**