使用Geofences和React Native

时间:2017-09-17 14:33:40

标签: javascript reactjs react-native

任何使用过Geofences和React Native的人?你是怎么做到的?

我找到了这个插件:https://www.npmjs.com/package/react-native-geo-fencing 这将基本上取你的经度和纬度,并确定你是否在多边形,但说你有100个不同的多边形,似乎很差的性能循环所有这些,直到你找到你所在的多边形。

有更优雅的方法吗?

3 个答案:

答案 0 :(得分:3)

我刚刚在React Native中创建了一个名为react-native-boundary的地理围护软件包。它仅使用本机代码,具有非常简单的API,易于安装,并在前台或后台触发enterexit事件。

这已经很晚了,但是我想为那些在此线程上绊倒的人提供答案,就像我在寻找相同问题的解决方案时所做的那样。

答案 1 :(得分:2)

我不建议您使用此软件包,它不是最新的,最后一次提交是很久以前的事,而是我使用下面的算法来计算一个点是否在我的多边形中。我的功能如下:

point = {latitude: 0, longitude: 0} // example of point
polygonArray = [
  {
    'latitude': 35.787184,
    'longitude': 51.348038,
  },
  {
    'latitude': 35.792754,
    'longitude': 51.383057,
  }
] // example of polygonArray 

_isInPolygon = (point, polygonArray) => {

    let x = point.latitude
    let y = point.longitude

    let inside = false
    for (let i = 0, j = polygonArray.length - 1; i < polygonArray.length; j = i++) {
      let xLat = polygonArray[i].latitude
      let yLat = polygonArray[i].longitude
      let xLon = polygonArray[j].latitude
      let yLon = polygonArray[j].longitude

      let intersect = ((yLat > y) !== (yLon > y)) && (x < (xLon - xLat) * (y - yLat) / (yLon - yLat) + xLat)
      if (intersect) inside = !inside
    }
    return inside
  } 

如果该点位于多边形中,则此函数将返回true,否则返回false。您还可以看到算法here的来源。

答案 2 :(得分:0)

我认为react-native-geo-fencing适用于使用此容易找到的用户是否在区域内的地理围栏。下面我写下了地理围栏的完整示例,您可以尝试。

import MapView, { Marker, Overlay, Polygon, Circle } from "react-native-maps";
import React, { Component } from "react";
import { StyleSheet, View, Image, ToastAndroid } from "react-native";
import GeoFencing from "react-native-geo-fencing";
export default class GoogleMap extends Component {
  constructor(props) {
    super(props);
    this.state = {
      latitude: 0,
      longitute: 0,
      lat: 22.7196,
      lng: 75.8577,
      timestamp: null
    };
    /* markers: [{
        title: 'Captain',
        descripton:"indore",
        latitude:0,
        longitude: 0,
        timestamp: null
       },
      {
        title: 'Captain',
        descripton:"indore",
        latitude: 23.1793,
        longitude: 75.7849

      }]*/
  }

  componentDidMount() {
    //-------------------- Start Get current location of user---------//

    navigator.geolocation.getCurrentPosition(
      position => {
        this.setState({
          latitude: position.coords.latitude,
          longitute: position.coords.longitude,
          timestamp: position.timestamp
        });
      },

      error => {
        console.log(error);
      },
      { enableHighAccuracy: false, timeout: 50000 }
    );
    //-----------------End current location of user--------//

    //-----------------Start geo fencing-------------//

    //-------Set fencing boundary for particular area--------------//
    polygon = [
      { lat: this.state.latitude, lng: this.state.longitute },
      { lat: this.state.lat, lng: this.state.lng },
      { lat: 22.7192, lng: 75.852 },
      { lat: this.state.latitude, lng: this.state.longitute }
      // last point has to be same as first point
    ];
    //-----------------End boundary of area--------------------//

    //-----------------another user point-----------//
    let point = {
      lat: 22.7192,
      lng: 75.852
    };

    //-----------------point end of user-------------//

    // set point and polygon on containsLocation method

    GeoFencing.containsLocation(point, polygon)
      .then(() => ToastAndroid.show("User is within area", ToastAndroid.SHORT))
      .catch(() =>
        ToastAndroid.show("User is not within area", ToastAndroid.SHORT)
      );
  }

  //--------------------End geo fencing ------------//

  // console.log("latitude is=="+this.state.latitude);
  // console.log("longitute is=="+this.state.longitute)

  render() {
    return (
      <View style={styles.container}>
        <MapView
          style={styles.map}
          initialRegion={{
            latitude: this.state.latitude,
            longitude: this.state.longitute,
            latitudeDelta: 0.015 * 5,
            longitudeDelta: 0.0121 * 5
          }}
          showsUserLocation={true}
          followUserLocation={true}
          zoomEnabled={true}
          showsScale={true}
        >
          {/*Circle Draw and set radius */}
          <MapView.Circle
            key={(this.state.latitude + this.state.longitute).toString()}
            center={{
              latitude: this.state.latitude,
              longitude: this.state.longitute
            }}
            radius={1500}
            strokeWidth={2}
            strokeColor={"red"}
            fillColor={"rgba(230,238,255,0.5)"}
            // onRegionChangeComplete = { this.onRegionChangeComplete.bind(this) }
          />

          {/*this.state.markers.map(marker => (
        <MapView.Marker
          coordinate={{longitude: marker.longitude, latitude: marker.latitude}}
          title={marker.title}
          description={marker.description}
        />
  ))*/}
          {/* Marker Add */}
          <MapView.Marker
            coordinate={{
              latitude: this.state.latitude,
              longitude: this.state.longitute
            }}
            title={"Captain"}
            description={"indore"}
            //image={require("./images/login-logo.png")}
            //pinColor={"gray"}
          />
          {/* 

          <MapView.Marker
            coordinate={{ latitude: 23.1793, longitude: 75.7849 }}
            title={"Captain"}
            description={"indore"}
            centerOffset={{ x: 20, y: 70 }}
          /> */}

          <Image
            source={require("./images/ic_log_in_top.png")}
            style={{ width: 70, height: 70, marginTop: 10, paddingLeft: 10 }}
          />
          {/*<Overlay 
            image="https://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg"
            bounds={[
              [23.1793, 75.7849], 
              [this.state.latitude, this.state.longitute]
            ]}
          />*/}
        </MapView>
      </View>
    );
  }
}
var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "#F5FCFF"
  },
  map: {
    position: "absolute",
    top: 0,
    left: 0,
    right: 0,
    bottom: 0
  }
});