【问题标题】:Why is the GPS reporting insane longitude numbers?为什么 GPS 会报告疯狂的经度数字?
【发布时间】:2017-03-15 21:24:17
【问题描述】:

我负责维护和开发一个严重依赖于使用智能手机设备中的 GPS 跟踪用户行车路线的应用程序。

问题

问题是 GPS 坐标不准确(到了奇怪的程度)。我说的不是几百米,我说的是几千米。我的客户在新西兰,GPS 坐标位于澳大利亚西部的海洋中部。

以下是我的客户记录的手机正在记录的不良数据示例:

如您所见,纬度值似乎是正确的,或者足够理智。但是经度值都固定在100,这根本不理智。

技术

该应用程序是使用cordova-android 5.22 和cordova-ios 4.2.1 构建的,但是我们看到使用Appcelerator 的钛框架的旧版本应用程序存在相同的问题(同样仅适用于新西兰客户),所以我不认为这个问题是特定于科尔多瓦或钛的。我们也无法重现该问题(开发团队位于加拿大)。

很遗憾,此时我不知道客户端使用的是 Android 还是 iOS,或者他们使用的是什么版本的操作系统。我会在获得该信息后立即更新问题。

除了读取纬度/经度值并将其写入日志文件之外,该应用程序不做任何事情,该日志文件会上传到我们的服务器,然后使用 FLOAT 长度 16 读取数据并将数据存储到 MySQL 数据库中, 14

守则 Cordova 应用程序:

geoWatchId = navigator.geolocation.watchPosition(logGeoItem, loggingFailure, {enableHighAccuracy: true});

...

function logGeoItem(geoPoint){
if(loggingState.isLogging){
    console.log(JSON.stringify(geoPoint));
    var newLogItem = {latitude: geoPoint.coords.latitude, longitude: geoPoint.coords.longitude, heading: geoPoint.coords.heading, altitude: geoPoint.coords.altitude, created_datetime: Date.now()};
    loggingState.currentGeoLoggingData.push(newLogItem);
}

}

是的,watchPosition 代码包含在 deviceready 事件中。

NodeJS GPS 数据存储在 MySQL 数据库中

for(var j=0; j<data.location.length; j++) {
    var sqlLocation = "INSERT INTO location (session_id, heading, altitude, latitude, longitude, created_datetime) VALUES";
    sqlLocation += "('" + data.location[j].session_id + "','" + data.location[j].heading + "','" + data.location[j].altitude + "','" + data.location[j].latitude + "','" + data.location[j].longitude + "','" + data.location[j].created_datetime + "');";
    connection.query(sqlLocation, function(err, result){
      log.info(err);
      log.info(result);
      if(err) {
        connection.rollback(function(){
          callback({ result: 'error', errorMsg: constants.errors.ERROR_UPLOAD_LOCATION_DATA });
        });
      }
    });
  }

研究

我在网上搜寻,发现了几篇不同的文章和堆栈溢出帖子,描述了不准确的 GPS 位置,但这些描述的 GPS 仍然可能是正常的。

目前的问题是经度值完全不合理,经度值似乎始终为 100。

我没有找到任何可以说明为什么经度如此不正常以及为什么它始终为 100 的任何信息。如果我的问题实际上只是读数不准确,我希望有各种经度值,而不是一个常数100.

任何人都可以向我提供有关如何进行调试的建议吗?为什么只有经度固定为100?

【问题讨论】:

  • 与您的问题无关,但很重要:您的代码容易受到 SQL 注入攻击。设计 SQL 查询时应使用数据绑定:var sqlLocation = "INSERT INTO location (session_id, heading, altitude, latitude, longitude, created_datetime) VALUES (?,?,?,?,?,?);"; var sqlParams = [data.location[j].session_id, data.location[j].heading, data.location[j].altitude, data.location[j].latitude, data.location[j].longitude, data.location[j].created_datetime]; connection.query(sqlLocation, sqlParams, function(err, result) {
  • 谢谢,我实际上在发布此内容时注意到了这一点。我需要清理和解决很多杂乱的代码。
  • 记录和显示的位置来自哪个变量?您的客户能否通过同一部手机的其他应用查看当前位置?
  • 我已经解决了我的问题。由于 mysql 数据库中的表配置,该问题实际上是数据存储问题。我已经在下面发布了答案。我也会相应地更新问题标签。

标签: mysql floating-point gps location geo


【解决方案1】:

问题是经度值实际上超过了 MySQL 中设置的最大允许位数。

FLOAT (16,14)

表示最多可以有16位数字,其中14位属于小数点后的数字。

新西兰部分地区的经度值可能 >= 100。 例如,新西兰旺格雷北地是:-35.725043, 174.319490

因为 174.319490 是一个违反 16/14 规则的数字(即使该数字本身不包含小数点后的 14 位数字),所以它的上限似乎为 100 并填零。

如果我将表格更改为 FLOAT (17,14) 类型,允许小数点前第三位,则数据将正确存储。

在 MySQL 5.6.21 上测试

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多