如何测试某个地理位置是否在“现实世界”中被访问过?

2024-04-14

好的,所以我已经有了这个问题的答案,但我花了很长时间才找到答案,所以我想我会分享它,特别是因为someone https://stackoverflow.com/users/975457/fusion27问我但在不相关的问题 https://stackoverflow.com/questions/16735449/beep-not-working-when-phonegap-app-is-in-background-on-ios?answertab=active#tab-top

我创建了一个基于 Phonegap 的导航应用程序,用于引导步行,使用 GPS 跟踪用户在预定义路线周围的位置。我的路线在路线周围的特定地理位置放置了触发器,这些触发器根据用户当前位置向用户提供指示。问题是 GPS 不是超级准确或可靠,因此即使我允许这些位置周围有大约 20 米的“访问半径”,但实际测试有时会导致错过这些触发器,因为 GPS 位置更新会在稍早之前发生。用户输入访问半径,稍后。我尝试增加半径,但这意味着触发器触发得太早,无法与用户当前的位置相关。

那么我该如何使用“真实世界”的 GPS 数据来解决这个问题呢?


我偶然发现这个奇妙的页面 http://www.movable-type.co.uk/scripts/latlong.html通过可移动类型的地理空间计算公式。更好的是,大多数公式都是已经用 JavaScript 编写 http://www.movable-type.co.uk/scripts/latlong.html#latlon-src这对于我的 Phonegap 应用程序来说非常酷。然而,引起我注意的公式是this one http://www.movable-type.co.uk/scripts/latlong.html#crossTrack用于计算两点之间的跨轨道距离。就我的应用程序和实际使用而言,这意味着即使 GPS 更新频率不够高而错过了目标位置的半径,我也可以根据最近位置和位置之间的路径来计算用户是否访问过目标。它的前身。

EDIT24/04/15:我修复了一个错误constrainedCrossTrackDistance函数,因此任何使用它的人都应该将其实现更新为本答案中的实现。

JS 库不包含这个公式,所以我扩展了 Movable Type 库来实现它:

/**
 * 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);
}

然而,现实世界的测试再次表明这并不能完全完成工作。问题在于该函数给出了误报,因为它没有考虑由两个端点和半径形成的边界框。这导致我添加了一个进一步的函数来将交叉轨道距离限制在该边界框内:

/**
 * 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));
  }
}

然后可以用它来确定目标位置是否在现实场景中被访问过:

// 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;
    }

这是一个小提琴 http://jsfiddle.net/dpa99c/frL2u/说明用例

我花了很长时间和大量的测试才想出这个,所以我希望它对其他人有帮助:-)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何测试某个地理位置是否在“现实世界”中被访问过? 的相关文章

随机推荐

  • Firebase:将 Facebook 帐户与现有用户关联

    我在 Firebase 中有一个当前数据库 其中包含可以使用 user pwd 登录的活动用户 但现在我正在实现 facebook 登录 并且我意识到将 facebook 帐户与现有用户链接的唯一方法只有当用户已经登录时用户 密码 但不是在
  • 如何调用 MemberwiseClone()?

    我对如何使用感到困惑MemberwiseClone 方法 我在 MSDN 中查看了示例 他们通过this关键词 为什么我不能像其他对象的方法一样直接调用它GetType or ToString 另外一个没有出现的相关方法是ShallowCo
  • 如何使用 Chrome 和 FireFox JAVA 的 webdriver 禁用 cookie

    我想启动浏览器 FF CHROME 以禁用 cookie 进行测试 我尝试了以下方法 service new ChromeDriverService Builder usingDriverExecutable new File src te
  • Postgres JDBC 驱动程序:PSQLException:返回时或附近出现语法错误

    由于某种原因 JDBC PostgreSQL 驱动程序正在添加 返回 到 select 语句的末尾 为什么 Code protected static final String AUTH QUERY SELECT SECRET FROM u
  • 未重定向到 Codeigniter 4 中的特定 URL

    为什么每当我通过 Codeigniter 4 控制器的构造函数重定向某些内容时就不起作用
  • 在php中获取今天和昨天的时间戳

    如何使用php中的strtotime 函数获取今天 昨天和前天12点的时间戳 12 点钟是一个变量 可以由用户更改 hour 12 today strtotime hour 00 00 yesterday strtotime 1 day t
  • 我可以在 Visual Studio (c++) 中设置断点以在线程上下文切换时中断吗?

    我们只想打破某个线程 知道该怎么做吗 我似乎找不到打破这个条件的方法 我应该在文字中更具体 正如标题所示 我想中断上下文切换到线程中 您需要设置断点过滤器 右键单击断点并选择 Filter 选项 它将显示一个对话框 允许您将断点过滤到特定的
  • 在覆盖 ProcessCmdKey EventHandler 时跳过 KeyDown

    我通过按向下箭头键在文本框上进行了简单的增量 如下所示 protected override bool ProcessCmdKey ref Message msg Keys keyData if keyData Keys Down int
  • CLLocationManager 坐标

    我一直致力于实现步行 骑自行车和开车的路线跟踪图 然而 正如您在下面的屏幕截图中看到的那样 即使我没有步行 骑自行车或开车前往该位置 我的坐标也会时不时地突然跳跃 在图像上画了圆圈来指出问题 我的问题是为什么坐标突然跳跃 这是我的实施快照
  • IP_RECVERR 的 OSX 等效项

    我正在尝试将 TraceRoute 程序从 Linux 移植到 OSX 但在找到 IP RECVERR 等效项时遇到问题 大多数人进行数据包解析的方式是 setsockopt sock IPPROTO IPV4 IP RECVERR on
  • 车把中的“{{{variable}}}”是什么意思?

    三重花括号在车把模板语法中意味着什么 例如 variable 我找不到任何文档 Thanks 因为它最初设计用于生成 HTML 所以 Handlebars 转义了由 expression 如果您不希望 Handlebars 转义值 请使用
  • Memcached 与 Windows 和 .NET

    有没有人已经在 Windows 环境中实现了 memcached 以供生产使用 因为我读过很多博客 不建议在 Windows 中运行 memcached 尤其是用于生产用途 例如在 Windows 上运行 memcached http la
  • 如何将 Citrix 中的 C# 程序实例限制为每用户 1 个

    我有一个带有 C 代码的 Windows 窗体应用程序 如下所示 针对 NET Framework 4 在我的开发人员工作站上 此代码可以阻止我启动该程序的多个实例 但是 QA 有一个 Citrix 测试环境 每个用户仍然能够启动多个实例
  • 使用 r.js 打包使用“文本”加载视图的 SPA 应用程序

    我正在尝试使用 grunt 将 SPA 应用程序 requirejs durandal 2 knockout 构建到单个 main build js 文件中 并且我遇到了 durandal 用于加载我的 文本 插件的严重问题意见 在开发中
  • 如何将单行拆分为多行并插入到 Oracle 中的表中?

    我从表中选择数据Employee Master使用下面的查询 SELECT EMP ID EMP NAME EMP LOC1 EMP LOC2 EMP LOC3 EMP DESG EMP ADDR1 EMP ADDR2 EMP ADDR3
  • android studio 3.4 中的 R.java 文件

    我只是想学习android开发 并且正在使用最新版本的android studio 但是 我找不到R java我的文件夹树视图中的文件 我还清理并重建了我的项目 但我仍然看不到 source R文件夹也不R java file 我也在学习
  • 我的 PHP 应用程序是否正确支持 UTF-8?

    我想确保我所知道的有关 UTF 8 的一切都是正确的 我已经尝试使用 UTF 8 一段时间了 但我不断遇到越来越多的错误和其他奇怪的事情 这使得拥有 100 UTF 8 网站几乎不可能 总有一些地方是我似乎想念的 也许这里有人可以更正我的列
  • 从 A 系列升级到 D 系列 Azure 虚拟机

    我们在 A 系列虚拟机上安装了 SQL Sever 我们想要升级到 D 系列虚拟机 是否只是在 Azure 中升级 VM 并单击 保存 那么简单 或者还有其他我需要注意的事情吗 我听说有人因为虚拟机所在的集群中不可用的级别而遇到升级问题 A
  • 是否有适用于 Nunit 的免费 Visual Studio 插件?

    我很便宜 不想支付 ReSharper 或 TestDriven NET 的费用 是否有适用于 NUnit 的免费 Visual Studio 插件 您可以创建一个空白项目 例如选择控制台应用程序 并在项目的属性中选择 DEBUG 标签并选
  • 如何测试某个地理位置是否在“现实世界”中被访问过?

    好的 所以我已经有了这个问题的答案 但我花了很长时间才找到答案 所以我想我会分享它 特别是因为someone https stackoverflow com users 975457 fusion27问我但在不相关的问题 https sta