我对地图和标记有疑问。
我正在从GeoJson文件加载标记。我只想显示当前位置内的标记,例如半径为500m(在圆圈中)。这可能吗?我不想加载该性能的所有700个标记。我希望你们能帮助我。
这是我的代码
import React from 'react';
import MapView from 'react-native-maps';
import Marker from 'react-native-maps';
import {
View,
Text,
StyleSheet,
Button,
} from "react-native";
class Spielplaetze extends React.Component {
constructor() {
super();
this.state = {
markers: [],
loaded: false
}
}
componentDidMount() {
this.getLocations();
this.getPosition();
}
getPosition(){
navigator.geolocation.getCurrentPosition(
(position) => {
console.log(position);
this.setState({
region: {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
latitudeDelta: 0.020,
longitudeDelta: 0.020,
}
});
},
(error) => this.setState({ error: error.message }),
{ enableHighAccuracy: false, timeout: 200000, maximumAge: 1000 },
);
}
getLocations(){
return fetch('http://media-panda.de/cologne.geojson')
.then(response => response.json())
.then(responseData =>{
var markers = [];
for (var i = 0; i < responseData.features.length; i++) {
if (responseData.features[i].properties.Torwand != '<Null>'){
var coords = responseData.features[i].geometry.coordinates;
var marker = {
coordinate: {
latitude: coords[1],
longitude: coords[0],
}
}
markers.push(marker);
}
}
this.setState({
markers: markers,
loaded: true,
});
}
).done();
}
render() {
return (
<View style={styles.container}>
<MapView.Animated
style={styles.map}
region={this.state.region}
showsUserLocation={true}
>
{this.state.markers.map(marker => (
<MapView.Marker
coordinate={marker.coordinate}
/>
))}
</MapView.Animated>
</View>
);
}
}
export default Spielplaetze;
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#ecf0f1',
},
map: {
width: "100%",
height: "100%",
},
})
答案 0 :(得分:0)
有一个很大的依赖项,称为geolib
,它使您可以执行计算,例如坐标之间的距离。
您可以安装npm i geolib
。使用它提供的.getDistance
函数,您可以根据标记与“中心”点的距离来过滤标记。
const geolib = require('geolib');
...
getLocations() {
let { region } = this.state;
let { latitude, longitude } = region;
fetch('http://media-panda.de/cologne.geojson')
.then(response => response.json())
.then(responseData => {
let markers = responseData.features.map(feature => {
let coords = feature.geometry.coordinates
return {
coordinate: {
latitude: coords[1],
longitude: coords[0],
}
}
}).filter(marker => {
let distance = this.calculateDistance(latitude, longitude, marker.coordinate.latitude, marker.coordinate.longitude);
return distance <= 500;
});
this.setState({
markers: markers,
loaded: true,
});
}).done(); // should probably have a catch on here otherwise you've got no way to handle your errors
}
// this function uses geolib to calculate the distance between the points
calculateDistance(origLat, origLon, markerLat, markerLon) {
return geolib.getDistance(
{latitude: origLat, longitude: origLon},
{latitude: markerLat, longitude: markerLon}
);
}
基本上,我正在做的是映射fetch
请求所返回的标记并将它们分别转换为以下对象
{ coordinate: { latitude: number, longitude: number } }
然后我要过滤它们,使用geolib
除去距中心点500m以外的任何区域。
您应该注意的一件事是,在当前代码设置中,可以先获取GeoJson,然后再获取用户位置的坐标。您可能需要考虑重构getLocations
和getPosition
函数,以便getLocations
仅在getPosition
函数返回该区域之后才能运行。否则,您将无法过滤,因为region
的状态值将不存在。
您可能希望在使用getLocations
的回调属性从getPosition
获得该区域后调用setState
。这样,该区域将处于状态,您应该能够进行过滤而不会出现任何问题。
getPosition(){
navigator.geolocation.getCurrentPosition(
(position) => {
console.log(position);
this.setState({
region: {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
latitudeDelta: 0.020,
longitudeDelta: 0.020,
}
}, () => this.getLocations());
},
(error) => this.setState({ error: error.message }),
{ enableHighAccuracy: false, timeout: 200000, maximumAge: 1000 },
);
}
这绝不是唯一的方法。它确实取决于您的用例,但是应该给您足够的想法。