设置位置请求属性后,我正在使用FusedLocationProviderClient获取locationUpdates。
要计算“行进的距离”,我想我会做以下事情:
Location lastLocation; // initialized to start location with getLocation() - code not shown.
LocationCallback locationCallback;
Double DistanceTraveled = 0.0;
locationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult != null) {
// Get last location in result if more than one are returned.
Location thisLocation = locationResult.getLastLocation();
// Sum up DistanceTraveled
DistanceTraveled = DistanceTraveled + lastLocation.distanceTo(thisLocation);
// Save thisLocation for next time onLocationResult() is called
lastLocation.set(thisLocation);
}
}
}
嗯,这不是很好。在每个回调中,由于结果的准确性,确切的位置会随机地从0米更改为10米。因此,如果使用此算法进行5秒更新后,我可以完全静止10分钟,那么当我完全不动时,它将总结出我所行进的几米!
我该怎么做才能准确计算出我的行进距离?有哪些选项?
答案 0 :(得分:0)
好-我在这里提出问题已经12天了。很多阅读,测试,编码,更多测试,更多阅读。现在,我有责任为这个使我受益匪浅的网站做出贡献。这样吧。
首先,以下文章提供了许多技巧和帮助的链接。 calculate actual distance travelled by mobile
现在,我特别关注跟踪某人行走的距离;确切地说是观鸟。我的应用程序是供观鸟者使用的。因此,我有兴趣记录看到的鸟儿,走到哪里以及追踪步行的总距离。事实证明,这是两个不同的问题。获取当前的坐标以观察鸟类是一件容易的事;只需获取位置即可。准确度是所报告的。
现在,解决这篇文章的问题。计算步行距离。这完全是另一个问题。这就是我在发布问题时要寻找的东西。人们在走路时如何准确地计算出行进距离?因为只注册位置更新,然后对Location1.distanceTo(Location2)求和,通常会给人一个夸大的总距离。为什么?我不明白这个问题。现在我知道了。如果我有这种了解,那么解决方案的路径将会更加清晰。
让我举个例子。假设我走路10秒钟。从第二个0(t0)开始。假设我在t1之前移动了1米。我站在这个位置直到t5,然后再步行5秒钟直到t10。步行/站立帮助相结合来说明问题。
每个GPS位置更新都包含一个坐标(lat / lng)或一个点,以及以米为单位的精度等级。与其他数据一起,但是我唯一关心的是时间(以毫秒为单位)。在此示例中,总是比上一次更新多1000毫秒。
将此GPS更新为圆的震中点,并返回半径以米为单位的精度。理论上,您的实际位置可以在该圆内或圆的边缘上的任何位置。不确定米的精度有多准确(似乎应该具有自己的精度等级),但让我们假设它是准确的,并且您的真实位置仅是距离报告点的米精度。实际上,为了说明起见,我们假定它始终是与您的真实位置之间的距离。在本示例中,对于返回的每个点,我们还假设该米的精度为20m。
因此,在t0时刻,我的真实位置可能比报告的位置早20m。我向前方走了1米,在t1报告位置更新时,我比真正的位置要早20m。因此,计算t0.distanceTo(t1)报告说,当我真正只移动了1m时,我移动了40m。开始看图片了吗?继续阅读...
现在,我站在这里直到t5。我还获得了4个位置更新信息,例如,这些位置更新信息领先20m,落后20米,左边20米,右边20米。 (这是一个极端的示例,但使用简单的数字进行说明)。因此,除了我假设的1秒后40m的行程外,现在我认为我已经移动了大约20x4或80m,总共移动了120m。而且我实际上只移动了100万!继续走5米到t10,如果您在10秒内只走了6m,您的距离可能又是5x20或100m,总距离为220m。这就是为什么仅对行进距离求和就不会准确的原因。
那是问题。直到有人明白这一点,您才对这款笨拙的Galaxy S9如何为您做到这一点感到困惑。
平均点呢? “ midpoint(t0,t1).distanceTo(midpoint(t2,t3)”,依此类推?这总是会产生比真实旅行距离少的距离。取决于运动,有时很多。
有很多方法可以尝试减少距离旅行计算中的误差(请参见上面的链接)。我发现,与谷歌的MyTracks应用相比,下面的方法在行走时可产生更准确的结果。我已经反复测试了200m,500m和1000m的距离。通常这会产生良好的结果,误差通常小于10%。谷歌的MyTracks一半时间说我在200m测试中走了500m +。
onLocationResult(LocationResult locationResult) {
lastLocationReceived.set(locationResult.getLastLocation());
// Throw away updates that don't meet a certain accuracy. e.g. 30m
if (lastLocationReceived.hasAccuracy() && locatLocationReceived.getAccuracy() <= MIN_ACC_METERS_FOR_DISTANCE_TRAVELED) {
// Don't use it if the current accuracy X 1.5 > distance traveled since last valid location
if ((lastLocationReceived.getAccuracy() * 1.5) < loastLocationReceived.distanceTo(lastLocationUsedForDistanceTraveled) {
// Calculate speed of travel to last valid location; avg walking speed is 1.4m/s; I used 2.0m/s as a high end value.
// Throw away values that are too high because it would have required that you run to get there.
// Sometimes the location is somewhere you could not have gotten to given the time.
long timeDelta = lastLocationReceived.getTime() - lastLocationUsedForDistanceTraveled.getTime();
if ((lastLocationReceived.distanceTo(lastLocationUsedForDistanceTraveled) / timeDelta) > MAX_WALKING_SPEED) {
// NOW we have a value we can use to minimize error
distanceTraveled += lastLocationReceived.distanceTo(lastLocationUsedForDistanceTraveled);
// Update last valid location
lastLocationUsedForDistanceTraveled.set(lastLocationReceived);
}
}
}
};
注意:
我测试了更多的方法,结果却截然不同。对于我的测试而言,这种简单的方法最适合行走。我敢肯定,我还有更多可以做的事情,可能会将错误进一步缩小几个百分点。如果有人有具体示例来实现更严格的准确性,请发表评论。
在测试中,我创建了一个活动,该活动允许我实时调整locationRequest()设置(停止并重新启动对更改所做的locationUpdate);以及修改最低准确度级别和准确度乘数(在上面的代码中用作1.5)。因此,我能够进行测试并使用不同的参数设置,以查看产生最佳效果的参数。
我希望这可以帮助其他人第一次走这条路。如果有人有意见,更正,改进,我们将很乐意。