任何使用过Geofences和React Native的人?你是怎么做到的?
我找到了这个插件:https://www.npmjs.com/package/react-native-geo-fencing 这将基本上取你的经度和纬度,并确定你是否在多边形,但说你有100个不同的多边形,似乎很差的性能循环所有这些,直到你找到你所在的多边形。
有更优雅的方法吗?
答案 0 :(得分:3)
我刚刚在React Native中创建了一个名为react-native-boundary的地理围护软件包。它仅使用本机代码,具有非常简单的API,易于安装,并在前台或后台触发enter
和exit
事件。
这已经很晚了,但是我想为那些在此线程上绊倒的人提供答案,就像我在寻找相同问题的解决方案时所做的那样。
答案 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
}
});