使用reactjs和传单点击新地图动态更新折线
Dynamically update polyline with new map click with reactjs and leaflet
我是 reactjs 和传单的新手,正在构建 "route mapping" 应用程序。目前,我在每次单击地图时都会更新点数组 (mapPoints) 中的一到两个点。 (即标记更新以反映新地图的点击。)这些是我的 class (this.state.mapPoints
) 中的状态,每次点击地图时都会通过 setState
更新。每次单击地图时,我都试图动态更新这两点之间的多段线。我认为如果使用 this.state.mapPoints
有足够的点,则通过调用函数 return 将新标记位置作为多段线位置。
虽然函数在 this.state.mapPoints
中正确读取,因此正确更新,但多段线不会动态更新,并保持绘制在第一组两点之间最初绘制的位置。如何更新要在新更新的 mapPoints
状态之间绘制的多段线? (为了简单起见,我通过注释总结了部分代码。)
//code for imports, etc, here
constructor(props) {
super(props);
this.addMarker = this.addMarker.bind(this);
this.getClientLocation = this.getClientLocation.bind(this);
this.getMapPoints = this.getMapPoints.bind(this);
this.state = {
mapPoints: [this.getClientLocation()],
};
}
/*
other render() code is here to render leaflet map and webpage/application
*/
renderLeafletMap() {
return (
<Map
center={this.state.mapPoints[0]}
zoom={this.state.zoom}
onClick={this.addMarker}
style={{height: MAP_STYLE_LENGTH, maxWidth: MAP_STYLE_LENGTH}}>
<TileLayer url={MAP_LAYER_URL} attribution={MAP_LAYER_ATTRIBUTION}/>
{this.getMarker(this.state.mapPoints)}
<Polyline color={'red'}
positions={this.getMapPoints(this.state.mapPoints)}/>
</Map>
)
}
getMapPoints(markerPositions) {
console.log(markerPositions); //this line successfully reflects the current state of mapPoints when the application runs
if (markerPositions.length >= 2)
return markerPositions;
else
return [[0,0],[0,0]];
}
addMarker(mapClickInfo) {
let updatedArray = this.state.mapPoints;
if(updatedArray[1]){
updatedArray[0] = updatedArray[1];
updatedArray[1] = mapClickInfo.latlng;
}else {
updatedArray[1] = mapClickInfo.latlng;
}
this.setState({mapPoints: updatedArray});
}
getClientLocation() {
if(!navigator.geolocation) {
alert.show("Your browser does not support geolocation.");
} else{
navigator.geolocation.getCurrentPosition(
position => {
const currentLocation = L.latLng(position.coords.latitude, position.coords.longitude);
let updatedArray = this.state.mapPoints;
updatedArray[0] = currentLocation;
this.setState({mapPoints: updatedArray});
}
);
}
}
/*
other code to set initial mapPoints, etc, here
*/
您正在直接改变状态,这就是您看不到预期结果的原因。
您的 addMarker
函数应该是:
addMarker = mapClickInfo => {
let updatedArray = [...this.state.mapPoints]; //create a copy of the mapPoints array and then modify it
if (updatedArray[1]) {
updatedArray[0] = updatedArray[1];
// also here you want to extract the coordinates and assign them to your index 1 on your mapPoints array, mapClickInfo.latlng is an {} and you want to have an array as index 1 on your mapPoints array
updatedArray[1] = [mapClickInfo.latlng.lat, mapClickInfo.latlng.lng];
} else {
// here the same
updatedArray[1] = [mapClickInfo.latlng.lat, mapClickInfo.latlng.lng];
}
this.setState({ mapPoints: updatedArray });
};
你也在你的 getClientLocation
函数中做了类似的事情。应该是这样的:
getClientLocation = () => {
if (!navigator.geolocation) {
alert.show("Your browser does not support geolocation.");
} else {
navigator.geolocation.getCurrentPosition(position => {
const {
coords: { latitude, longitude }
} = position;
const mapPoints = [...this.state.mapPoints];
mapPoints[0] = [latitude, longitude];
this.setState({ mapPoints });
});
}
};
我是 reactjs 和传单的新手,正在构建 "route mapping" 应用程序。目前,我在每次单击地图时都会更新点数组 (mapPoints) 中的一到两个点。 (即标记更新以反映新地图的点击。)这些是我的 class (this.state.mapPoints
) 中的状态,每次点击地图时都会通过 setState
更新。每次单击地图时,我都试图动态更新这两点之间的多段线。我认为如果使用 this.state.mapPoints
有足够的点,则通过调用函数 return 将新标记位置作为多段线位置。
虽然函数在 this.state.mapPoints
中正确读取,因此正确更新,但多段线不会动态更新,并保持绘制在第一组两点之间最初绘制的位置。如何更新要在新更新的 mapPoints
状态之间绘制的多段线? (为了简单起见,我通过注释总结了部分代码。)
//code for imports, etc, here
constructor(props) {
super(props);
this.addMarker = this.addMarker.bind(this);
this.getClientLocation = this.getClientLocation.bind(this);
this.getMapPoints = this.getMapPoints.bind(this);
this.state = {
mapPoints: [this.getClientLocation()],
};
}
/*
other render() code is here to render leaflet map and webpage/application
*/
renderLeafletMap() {
return (
<Map
center={this.state.mapPoints[0]}
zoom={this.state.zoom}
onClick={this.addMarker}
style={{height: MAP_STYLE_LENGTH, maxWidth: MAP_STYLE_LENGTH}}>
<TileLayer url={MAP_LAYER_URL} attribution={MAP_LAYER_ATTRIBUTION}/>
{this.getMarker(this.state.mapPoints)}
<Polyline color={'red'}
positions={this.getMapPoints(this.state.mapPoints)}/>
</Map>
)
}
getMapPoints(markerPositions) {
console.log(markerPositions); //this line successfully reflects the current state of mapPoints when the application runs
if (markerPositions.length >= 2)
return markerPositions;
else
return [[0,0],[0,0]];
}
addMarker(mapClickInfo) {
let updatedArray = this.state.mapPoints;
if(updatedArray[1]){
updatedArray[0] = updatedArray[1];
updatedArray[1] = mapClickInfo.latlng;
}else {
updatedArray[1] = mapClickInfo.latlng;
}
this.setState({mapPoints: updatedArray});
}
getClientLocation() {
if(!navigator.geolocation) {
alert.show("Your browser does not support geolocation.");
} else{
navigator.geolocation.getCurrentPosition(
position => {
const currentLocation = L.latLng(position.coords.latitude, position.coords.longitude);
let updatedArray = this.state.mapPoints;
updatedArray[0] = currentLocation;
this.setState({mapPoints: updatedArray});
}
);
}
}
/*
other code to set initial mapPoints, etc, here
*/
您正在直接改变状态,这就是您看不到预期结果的原因。
您的 addMarker
函数应该是:
addMarker = mapClickInfo => {
let updatedArray = [...this.state.mapPoints]; //create a copy of the mapPoints array and then modify it
if (updatedArray[1]) {
updatedArray[0] = updatedArray[1];
// also here you want to extract the coordinates and assign them to your index 1 on your mapPoints array, mapClickInfo.latlng is an {} and you want to have an array as index 1 on your mapPoints array
updatedArray[1] = [mapClickInfo.latlng.lat, mapClickInfo.latlng.lng];
} else {
// here the same
updatedArray[1] = [mapClickInfo.latlng.lat, mapClickInfo.latlng.lng];
}
this.setState({ mapPoints: updatedArray });
};
你也在你的 getClientLocation
函数中做了类似的事情。应该是这样的:
getClientLocation = () => {
if (!navigator.geolocation) {
alert.show("Your browser does not support geolocation.");
} else {
navigator.geolocation.getCurrentPosition(position => {
const {
coords: { latitude, longitude }
} = position;
const mapPoints = [...this.state.mapPoints];
mapPoints[0] = [latitude, longitude];
this.setState({ mapPoints });
});
}
};