如何测试地理位置是否已在“现实世界”中访问过? [英] How to test if a geographic location has been visited in the "real world"?

查看:229
本文介绍了如何测试地理位置是否已在“现实世界”中访问过?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,所以我已经有这个问题的答案,但它花了我很长时间达到它,所以我想我会分享它,特别是因为有人问我,但在无关问题



我创建了一个基于PhoneGap的导航应用程序,用于指导行走,跟踪用户的位置使用GPS的预定义路由。我的路线具有放置在路线周围的特定地理位置处的触发器,其基于用户的当前位置向用户给出指令。问题是GPS不是超级准确或可靠,所以即使我允许在大约20米的那些位置周围的访问半径,真实世界测试导致这些触发器有时被错过,因为GPS位置更新将稍微发生用户进入访问半径并稍后。我试图增加半径,但这意味着触发器太早发生与用户的当前位置相关。



那么,如何使用真实世界GPS数据解决这个问题?

解决方案

我偶然发现了这个奇妙的页面 by Movable地理空间计算的公式类型。更好的是,大多数公式都是已用Javascript写的这是超爽的我的Phonegap应用程序。但是,引起我注意的公式是这一个计算两点之间的跨轨道距离。在我的应用程序和现实世界的使用,这意味着,即使GPS更新不频繁,错过了我的目标位置的半径,我可以计算用户是否访问目标基于最近的位置和

编辑 24/04/15:我修复了 constrainedCrossTrackDistance 函数,所以任何使用它的人都应该更新他们的实现到这个答案中的一个。



JS库没有包含这个公式,所以我扩展可移动类型库实现它:

  / ** 
*计算点与大圆路径的距离(也称为交叉轨道距离或交叉轨道误差)
*
*公式:dxt = asin(sin(d13 / R)* sin(b13-b12))* R
*其中
* d13是从起点到第三点的距离
* b13是从起点到第三点的(初始)方位轴承
* b12是从起点到终点的b $ b * R是地球的半径
*
* @param {LatLon} startPoint - 表示大圆路径开始的点
* @param {LatLon} endPoint - 点表示大圆路径的结束
* @param {Number} [precision = 4] - 用于计算和返回值的有效数字的数量
* @return {Number} - 距离第三个点到大圆路径
* /
LatLon.prototype.crossTrackDistance = function(startPoint,endPoint,precision){
var R = this._radius;
var d13 = startPoint.distanceTo(this,10);
var b13 = startPoint.bearingTo(this).toRad();
var b12 = startPoint.bearingTo(endPoint).toRad();
var d = Math.asin(Math.sin(d13 / R)* Math.sin(b13-b12))* R;
return d.toPrecisionFixed(precision);
}

然而,真实世界的测试再次表明这没有做。问题是,这个函数给出了误报,因为它没有考虑到由两个端点和半径形成的边界框。这导致我添加了另一个函数来限制到该边界框内的crosstrack距离:

  / ** 
*如果点在由路径定义的边界框内,则计算点距大圆路径的距离。
*否则,它返回从点到大圆路径最近端的距离。
*
* @param {LatLon} startPoint - 指示大圆路径开始的点
* @param {LatLon} endPoint - 指示大圆路径结束的点
* @param {Number} [precision = 4] - 用于计算和返回值的有效数字的数量
* @return {Number} - 从第三点到大圆路径的距离$ b * /
LatLon.prototype.constrainedCrossTrackDistance = function(startPoint,endPoint,precision){

var bAB = startPoint.bearingTo(endPoint);
var bAB_plus_90 = Geo.adjustBearing(bAB,90);
var bAB_minus_90 = Geo.adjustBearing(bAB,-90);
var bAC = startPoint.bearingTo(this);
var bBC = endPoint.bearingTo(this);
var dAC = startPoint.distanceTo(this,10);
var dBC = endPoint.distanceTo(this,10);
if(Geo.differenceInBearings(bAC,bBC)> 90&&((bBC> bAB_plus_90&& bAC< bAB_plus_90)||(bAC> bAB_minus_90&& bBC< bAB_minus_90))){
return Math.abs(this.crossTrackDistance(startPoint,endPoint,precision));
} else if((bBC< bAB_plus_90&& bAC< bAB_plus_90)||(bBC> bAB_minus_90& bAC> bAB_minus_90)){
return Math.abs );
} else if((bBC> bAB_plus_90& bAC> bAB_plus_90)||(bBC< bAB_minus_90&& bAC< bAB_minus_90)){
return Math.abs(dAC );
} else {
return(Math.abs(dBC)< Math.abs(dAC)?Math.abs(dBC):Math.abs(dAC));
}
}

这可以用于确定目标位置已在实际场景中访问过:

  //计算目标位置是否访问
if(
currentPos.distanceTo(targetPos)* 1000< tolerance ||
(prevPos&& amp;& b $ b visited = true;
} else {
visited = false;
}

这里是一个小提琴说明了一个用例



这耗费了我很长时间和很多测试,我希望它可以帮助其他人: - )


OK, so I already have the answer to this question but it took me a long time to reach it so I thought I would share it, particularly since someone asked me but under an unrelated question

I created a Phonegap-based navigation app for guided walks that tracks the user's location around a predefined route using GPS. My routes have triggers placed at specific geo-locations around the route which give instructions to the user based on their current location. The problem is that GPS is not super accurate or reliable, so even though I allowed a "visiting radius" around those locations of around 20 metres, real-world testing resulted in those triggers sometimes being missed because a GPS position update would occur slightly before the user entered the visiting radius and slightly afterwards. I tried increasing the radius but this meant that the trigger fired too early to be relevant to the user's current position.

So how do I solve this in a way that works using "real-world" GPS data?

解决方案

I stumbled upon this fantastic page by Movable Type of formulae for geospatial calculations. Even better, most of the formulae are already written in Javascript which was super-cool for my Phonegap app. However, the formula that caught my attention was this one for calculating the cross-track distance between two points. In terms of my app and real-world use, this means that even if the GPS updates are infrequent enough to miss the radius of my target location, I can calculate if the user visited the target based on the path between the most recent position and its predecessor.

EDIT 24/04/15: I've fixed a bug in the constrainedCrossTrackDistance function, so anyone using it should update their implementation to the one in this answer.

The JS library didn’t include this formula, so I extended the Movable Type library to implement it:

/**
 * Calculates distance of a point from a great-circle path (also called cross-track distance or cross-track error)
 * 
 * Formula: dxt = asin(sin(d13/R)*sin(b13-b12)) * R
 * where 
 *  d13 is distance from start point to third point
 *  b13 is (initial) bearing from start point to third point
 *  b12 is (initial) bearing from start point to end point
 *  R is the earth's radius
 * 
 * @param {LatLon} startPoint - Point denoting the start of the great-circle path
 * @param {LatLon} endPoint - Point denoting the end of the great-circle path
 * @param {Number} [precision=4] - no of significant digits to use for calculations and returned value
 * @return {Number} - distance in km from third point to great-circle path
 */
LatLon.prototype.crossTrackDistance = function(startPoint, endPoint, precision){
    var R = this._radius;
    var d13 = startPoint.distanceTo(this, 10);
    var b13 = startPoint.bearingTo(this).toRad();
    var b12 = startPoint.bearingTo(endPoint).toRad();
    var d = Math.asin(Math.sin(d13/R)*Math.sin(b13-b12)) * R;
    return d.toPrecisionFixed(precision);
}

However, real-world testing again showed this didn’t quite do the job. The problem was that this function was giving false positives because it didn’t take it into consideration the bounding box formed by the two end points and the radius. This led me to add a further function to constrain the crosstrack distance to within that bounding box:

/**
 * Calculates distance of a point from a great-circle path if the point is within the bounding box defined by the path.
 * Otherwise, it returns the distance from the point to the closest end of the great-circle path.
 * 
 * @param {LatLon} startPoint - Point denoting the start of the great-circle path
 * @param {LatLon} endPoint - Point denoting the end of the great-circle path
 * @param {Number} [precision=4] - no of significant digits to use for calculations and returned value
 * @return {Number} - distance in km from third point to great-circle path
 */
LatLon.prototype.constrainedCrossTrackDistance = function(startPoint, endPoint, precision){

  var bAB = startPoint.bearingTo(endPoint);
  var bAB_plus_90 = Geo.adjustBearing(bAB, 90);
  var bAB_minus_90 = Geo.adjustBearing(bAB, -90);
  var bAC = startPoint.bearingTo(this);
  var bBC = endPoint.bearingTo(this);
  var dAC = startPoint.distanceTo(this, 10);
  var dBC = endPoint.distanceTo(this, 10);
  if(Geo.differenceInBearings(bAC, bBC) > 90 && ((bBC > bAB_plus_90 && bAC < bAB_plus_90) || (bAC > bAB_minus_90 && bBC < bAB_minus_90))){
    return Math.abs(this.crossTrackDistance(startPoint, endPoint, precision));
  }else if((bBC < bAB_plus_90 && bAC < bAB_plus_90) || (bBC > bAB_minus_90 && bAC > bAB_minus_90)){
    return Math.abs(dBC);
  }else if((bBC > bAB_plus_90 && bAC > bAB_plus_90) || (bBC < bAB_minus_90 && bAC < bAB_minus_90)){
    return Math.abs(dAC);
  }else{
    return (Math.abs(dBC) < Math.abs(dAC) ? Math.abs(dBC) : Math.abs(dAC));
  }
}

This can then be used to determine if the target position has been visited in a real-world scenario:

// Calculate if target location visited
    if(
        currentPos.distanceTo(targetPos)*1000 < tolerance ||
        (prevPos && Math.abs(targetPos.constrainedCrossTrackDistance(prevPos, currentPos)*1000) < tolerance)
    ){
        visited = true;
    }else{
        visited = false;
    }

Here's a fiddle illustrating a use case

It took me a long time and lot of testing to come up with this so I hope it can be of help to other people :-)

这篇关于如何测试地理位置是否已在“现实世界”中访问过?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆