React-Native-Maps |在圆内/半径内显示标记?

时间:2019-02-27 15:48:53

标签: react-native

我对地图和标记有疑问。

我正在从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%",
  },
})

1 个答案:

答案 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,然后再获取用户位置的坐标。您可能需要考虑重构getLocationsgetPosition函数,以便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 },
  );
}

这绝不是唯一的方法。它确实取决于您的用例,但是应该给您足够的想法。