具有不同精度的纬度和经度的浮点计算
背景:我收到一个经度和纬度作为网络服务的参数。它们通常最多可达小数点后 6 位。当收到新请求时,我计算最后记录的位置与请求参数中的经度/纬度之间的距离。如果距离大于相距一定英里的阈值,我会更新当前位置。
问题:我使用 geokit gem/插件来计算位置之间的距离。极少数情况下,会出现错误(作者网站上提到的零距离错误 - 我使用的是 1.4.1,它声称该错误已修复,但我仍然看到它发生耸耸肩),导致在计算相同的两点之间的距离时,距离计算会返回非常不准确的内容(如果用户没有移动,就会发生这种情况)。这会导致不应该发生的用户当前位置的更新。您可能想知道 - 如果只是将 loc 更新为完全相同的坐标,谁在乎呢?好吧,答案是当更新 loc 时会发生一堆其他垃圾,这使它成为一个实际问题。
尝试的解决方案:我尝试添加逻辑来在计算距离之前手动检查两个位置是否相同,然后跳过计算而不更新(如果是这种情况)。传入参数为long/lats,精度为6位小数;然而,在我的数据库中,我将值存储为浮点数,它似乎只存储 4 个小数位。这导致我的浮点比较总是失败,并且不适当的位置更新继续发生。
唷,好吧,实际的问题是:我应该如何进行这种比较?我是否应该从传入的纬度/经度中截断 2 个小数位,以某种方式向上舍入以使第四位数字正确,然后进行比较?或者,我应该进行“在一定范围内”的比较(例如reported_loc.long > current_loc.long - .0001 &reported_loc.long < current_loc.long + .0001)?此外,任何对现有 ruby gem/插件或内置函数来执行此类操作的建议将不胜感激。
以下是日志的示例输出:
[update_loc] Last location history record at lat: 41.5024, long: -81.6816
[update_loc] Current loc at lat: 41.502467, long: -81.681623
[update_loc] Distance from current loc and last loc history: 5795.10615113555 miles
[update_loc] Locs not identical and distance greater than threshold, inserting new loc history
[update_loc] Location update complete
谢谢
汤姆
Background: I receive a long and lat as parameters to a web service. They are typically up to 6 decimal places. When a new request is received, I calculate the distance between the last recorded loc and the long/lat in the params of the request. If the distance is greater than a certain threshold of miles apart, I update the current loc.
Problem: I use the geokit gem/plugin to calculate the distance between the locs. Very rarely, a bug shows up (the zero distance bug mentioned on the author's site - I'm using 1.4.1 which claims the bug is fixed, but I still see it occurring shrug) that causes the distance calc to return something wildly inaccurate when calculating the distance between two points that are identical (this occurs if the user is not moving). This is causing updates to the user's current loc that should not be happening. You're probably wondering - well if it's just updating the loc to be exactly the same coordinates, who cares? Well, the answer is that a bunch of other crap occurs when the loc is updated that makes it an actual issue.
Attempted Solution: I tried to add in logic to manually check if the two locs are identical before calculating the distance and then just skipping the calc and not updating if that is the case. The incoming parameters are long/lats with 6 decimal precision; whereas, in my database, I store the values as floats, which appears to only store 4 decimal places. This is causing my float comparison to always fail and the inappropriate loc updates continue to occur.
Phew, ok so the actual question is: How should I perform this comparison? Should I truncate 2 of the decimal places from the incoming lat/longs, round up somehow so the fourth digit is correct and then compare? Or, should I do a "within a certain range" sort of comparison (e.g. reported_loc.long > current_loc.long - .0001 && reported_loc.long < current_loc.long + .0001)? Also any recommendations for existing ruby gem/plugins or built in functions to do this sort of thing would be much appreciated.
Here is sample output from the log:
[update_loc] Last location history record at lat: 41.5024, long: -81.6816
[update_loc] Current loc at lat: 41.502467, long: -81.681623
[update_loc] Distance from current loc and last loc history: 5795.10615113555 miles
[update_loc] Locs not identical and distance greater than threshold, inserting new loc history
[update_loc] Location update complete
Thank you
Tom
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
测试两个数字是否接近的常用方法是使用
abs
,即,其中
tol
是一些预先指定的容差,例如0.0001
。The usual way to test if two numbers are close is to use
abs
, ie,where
tol
is some pre-specified tolerance, eg,0.0001
.GPS 接收器可以为您提供精确到许多小数点的位置,但这并不意味着测量结果实际上那么准确。
通常,大约 95% 的测量值位于几米的圆内,这与使用 32 位浮点数存储的精度大致相同。
但是,当您将 GPS 日志绘制为地图上的浮点时,您会清楚地注意到舍入错误。
无论如何,为了进行此比较,我将使用一个范围,而不是对传入值进行四舍五入并将其与数据库值进行比较。您将无法再检测到最小的动作,但至少您也不会再收到误报。
当您使用浮子来存储东西时,您显然并不关心毫米或厘米。
A GPS receiver can give you a location with a precision of many decimals, but that doesn't mean that the measurement is actually that accurate.
Usually about 95% of the measurements lie within a circle of a couple of meters, which is about the same accuracy that you can store with a 32bits float.
However, you will clearly notice rounding errors when you plot a gps log as floats on a map.
Anyway, to do this comparison, I'd use a range instead of rounding the incoming value and comparing that to the database value. You won't be able to detect the smallest movements anymore, but at least you won't get false positives anymore either.
As you're using floats to store stuff, you clearly don't care about millimeters or centimeters anyway.