html5 地理定位 API 与地理围栏
html5 Geolocation API with Geofencing
我正在使用 HTML5 地理定位 API 进行项目,目前使用 socket.io 允许用户在远程位置定位其他人。现在我的下一个目标是我希望我的应用程序创建某种地理围栏,如果用户在边界之外,它会发送通知。
现在我的问题是:
- 我可以不使用任何数据库吗?
- 是否可以只使用Javascript?
如果有人问,我正在使用 Google 地图
有一种方法可以让你观察地理位置的变化。 navigator.geolocation.watchPosition
但是没有可用的地理围栏 api,因此您必须自己创建:
我做了两个类:SquareGeofenceRegion
& CircularGeofenceRegion
具有相同的 api 但计算方式不同。
class CircularGeofenceRegion {
constructor(opts) {
Object.assign(this, opts)
}
inside(lat2, lon2) {
const lat1 = this.latitude
const lon1 = this.longitude
const R = 63710; // Earth's radius in m
return Math.acos(Math.sin(lat1)*Math.sin(lat2) +
Math.cos(lat1)*Math.cos(lat2) *
Math.cos(lon2-lon1)) * R < this.radius;
}
}
class SquareGeofenceRegion {
constructor(opts) {
Object.assign(this, opts)
}
inside(lat, lon) {
const x = this.latitude
const y = this.longitude
const { axis } = this
return lat > (x - axis) &&
lat < (x + axis) &&
lon > (y - axis) &&
lon < (y + axis)
}
}
const fenceA = new CircularGeofenceRegion({
name: 'myfence',
latitude: 59.345635,
longitude: 18.059707,
radius: 1000 // meters
});
const fenceB = new SquareGeofenceRegion({
name: 'myfence',
latitude: 59.345635,
longitude: 18.059707,
axis: 1000 // meters in all 4 directions
})
const fences = [fenceA, fenceB]
const options = {}
navigator.geolocation.watchPosition(({coords}) => {
for (const fence of fences) {
const lat = coords.latitude
const lon = coords.longitude
if (fence.inside(lat, lon)) {
// do some logic
}
}
}, console.error, options);
我只是想警告你 watchPosition 在后台时可能并不总是被触发:
我正在使用 HTML5 地理定位 API 进行项目,目前使用 socket.io 允许用户在远程位置定位其他人。现在我的下一个目标是我希望我的应用程序创建某种地理围栏,如果用户在边界之外,它会发送通知。
现在我的问题是:
- 我可以不使用任何数据库吗?
- 是否可以只使用Javascript?
如果有人问,我正在使用 Google 地图
有一种方法可以让你观察地理位置的变化。 navigator.geolocation.watchPosition
但是没有可用的地理围栏 api,因此您必须自己创建:
我做了两个类:SquareGeofenceRegion
& CircularGeofenceRegion
具有相同的 api 但计算方式不同。
class CircularGeofenceRegion {
constructor(opts) {
Object.assign(this, opts)
}
inside(lat2, lon2) {
const lat1 = this.latitude
const lon1 = this.longitude
const R = 63710; // Earth's radius in m
return Math.acos(Math.sin(lat1)*Math.sin(lat2) +
Math.cos(lat1)*Math.cos(lat2) *
Math.cos(lon2-lon1)) * R < this.radius;
}
}
class SquareGeofenceRegion {
constructor(opts) {
Object.assign(this, opts)
}
inside(lat, lon) {
const x = this.latitude
const y = this.longitude
const { axis } = this
return lat > (x - axis) &&
lat < (x + axis) &&
lon > (y - axis) &&
lon < (y + axis)
}
}
const fenceA = new CircularGeofenceRegion({
name: 'myfence',
latitude: 59.345635,
longitude: 18.059707,
radius: 1000 // meters
});
const fenceB = new SquareGeofenceRegion({
name: 'myfence',
latitude: 59.345635,
longitude: 18.059707,
axis: 1000 // meters in all 4 directions
})
const fences = [fenceA, fenceB]
const options = {}
navigator.geolocation.watchPosition(({coords}) => {
for (const fence of fences) {
const lat = coords.latitude
const lon = coords.longitude
if (fence.inside(lat, lon)) {
// do some logic
}
}
}, console.error, options);
我只是想警告你 watchPosition 在后台时可能并不总是被触发: