Android如何在没有getSpeed()的情况下计算移动速度 [英] Android How to calclulate the movement speed without the getSpeed()

查看:168
本文介绍了Android如何在没有getSpeed()的情况下计算移动速度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如我们都知道GPS系统远非完美,当您在GPS丢失信号时使用GPS进行应用时,它会再次开始计算。如果您尝试正确计算距离,它将开始计算,例如,如果距离目的地30米,它将计算例如130米。这扰乱了我如何计算距离。所以我发现了一些建议,我应该使用速度来过滤GPS协调。



我想计算没有 location.getSpeed() 我想通过比较最近已知的坐标与某个给定点的坐标之间的距离来计算速度,并获得设备移动的速度。如果速度大于15米/小时,则坐标无效并且不重新计算距离。 解决方案

这可以做你想做的。它写在Kotlin。它应用加权移动平均线。最近的地点重量更重。它可以平滑速度,但会增加更多滞后。这是为了避免在某些情况下我无法使用getSpeed()的错误。但通常情况下,如果您在Android上使用Fused位置,则在典型的现代ACTIVE手机上,速度非常稳定和准确。

  var recentGPSLocationSegments = listOf< Pair< android.location.Location,android.location.Location>>()

apply applyWeightedMovingAverageSpeed(location:android.location.Location,android.location.Location ):Double
{
recentGPSLocationSegments + = Pair(location,previous)
val cachedLocationsNs = location.elapsedRealtimeNanos - 4500000000 // 4.5秒,通常会得到4个条目(间隔1秒)
val targetZeroWeightNs = location.elapsedRealtimeNanos - 5000000000 // 5.0秒,重量约为5000000000,4000000000,3000000000,1000000000

//折旧地点
recentGPSLocationSegments = recentGPSLocationSegments.filter {它 - > it.first.elapsedRealtimeNanos> cachedLocationsNs}

//总计所有权重。体重基于年龄,年轻人的体重更高
val权重= recentGPSLocationSegments.map {it.first.elapsedRealtimeNanos --targetZeroWeightNs} .sum()

//应用权重并获得平均速度以米/秒为单位
return recentGPSLocationSegments.map {speedFromGPS(it.first,it.second)*(it.first.elapsedRealtimeNanos - targetZeroWeightNs)} .sum()/ weights
}

fun speedFromGPS(location:android.location.Location,previous:android.location.Location):Double
{
val dist = location.distanceTo(previous)
val time =( location.elapsedRealtimeNanos - previous.elapsedRealtimeNanos)/ 1000000000.0
return dist / time
}

location locationManager示例:LocationListener = object:LocationListener
{
var lastLocation :android.location.Location? = null
var lastPreviousLocation:android.location.Location? = null

覆盖fun onLocationChanged(位置:android.location.Location?)
{
if(location!= null)
{
if( lastPreviousLocation!= null)
{
currentSpeed = applyWeightedMovingAverageSpeed(location,lastPreviousLocation !!)

lastPreviousLocation = lastLocation
}

lastLocation =位置

if(currentSpeed <0.0)
{
currentSpeed = 0.0
}
}
}

重写fun onStatusChanged(provider:String,status:Int,extras:Bundle)
{
}

覆盖fun onProviderEnabled(provider:String)
{


覆盖fun onProviderDisabled(provider:String)
{
}
}


As we all know GPS system is far from perfect and when you go around with your app using the gps when the GPS loses the signal and it starts calculating again. And if you try to calculate the distance correctly it will start calculating and for example if you were 30 meters away from your destination it will calculate for example 130 meters. Which messes my how calculation of the distance up. So I found some suggestion that I should filter the GPS coordination using the speed.

I want to calculate the speed without the location.getSpeed() I want to calculate the speed by comparing the distance from the last known coordinates to the coordinates at some given point and I get the speed of the device moving. And if the speed is for example greater than 15 m/h coordinates are invalid and don't re-calculate the distance.

解决方案

This may do what you want. It is written in Kotlin. It applies a weighted moving average. Most recent locations have a heavier weight. It can "smooth" out the speed, at the cost of adding more lag. This was to get around a bug in certain situations that I could not use getSpeed(). But normally if you use "Fused" location on Android, the speed is quite stable and accurate on a typical modern, ACTIVE phone.

var recentGPSLocationSegments = listOf<Pair<android.location.Location, android.location.Location>>()

fun applyWeightedMovingAverageSpeed(location: android.location.Location, previous: android.location.Location): Double
{
    recentGPSLocationSegments += Pair(location, previous)
    val cachedLocationsNs = location.elapsedRealtimeNanos - 4500000000 // 4.5 seconds, This will typically get 4 entries (1 second apart)
    val targetZeroWeightNs = location.elapsedRealtimeNanos - 5000000000 // 5.0 seconds, Weights will be approx 5000000000, 4000000000, 3000000000, 1000000000

    // Toss old locations
    recentGPSLocationSegments = recentGPSLocationSegments.filter { it -> it.first.elapsedRealtimeNanos > cachedLocationsNs }

    // Total up all the weights. Weight is based on age, younger has higher weight
    val weights = recentGPSLocationSegments.map { it.first.elapsedRealtimeNanos - targetZeroWeightNs }.sum()

    // Apply the weights and get average speed in meters/second
    return recentGPSLocationSegments.map { speedFromGPS(it.first, it.second) * (it.first.elapsedRealtimeNanos - targetZeroWeightNs) }.sum() / weights
}

fun speedFromGPS(location: android.location.Location, previous: android.location.Location): Double
{
    val dist = location.distanceTo(previous)
    val time = (location.elapsedRealtimeNanos - previous.elapsedRealtimeNanos) / 1000000000.0
    return dist / time
}

val locationManagerExample: LocationListener = object : LocationListener
{
    var lastLocation: android.location.Location? = null
    var lastPreviousLocation: android.location.Location? = null

    override fun onLocationChanged(location: android.location.Location?)
    {
        if (location != null)
        {
            if (lastPreviousLocation != null)
            {
                currentSpeed = applyWeightedMovingAverageSpeed(location, lastPreviousLocation!!)

                lastPreviousLocation = lastLocation
            }

            lastLocation = location

            if (currentSpeed < 0.0)
            {
                currentSpeed = 0.0
            }
        }
    }

    override fun onStatusChanged(provider: String, status: Int, extras: Bundle)
    {
    }

    override fun onProviderEnabled(provider: String)
    {
    }

    override fun onProviderDisabled(provider: String)
    {
    }
}

这篇关于Android如何在没有getSpeed()的情况下计算移动速度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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