如何在android中使用方位平滑旋转地图视图

如何在android中使用方位平滑旋转地图视图,android,google-maps,geolocation,Android,Google Maps,Geolocation,我尝试在用户改变方向时旋转地图视图,即如果用户向左和向右转弯,它应该相应地旋转。我根据当前位置旋转地图视图,它旋转正确,但抖动。以下是我用于旋转的代码 public void onGPSUpdate(Location location) { boolean check=isBetterLocation(location, tempLoc); tempLoc=location; if(check){ showLocation(location)

我尝试在用户改变方向时旋转地图视图,即如果用户向左和向右转弯,它应该相应地旋转。我根据当前位置旋转地图视图,它旋转正确,但抖动。以下是我用于旋转的代码

   public void onGPSUpdate(Location location) 
{
     boolean check=isBetterLocation(location, tempLoc);
    tempLoc=location;

     if(check){
        showLocation(location);

     }

}
isBetterLocation method is copied from google docs for better location.

private void showLocation(Location loc){
   mRotateView.rotate(-loc.getBearing());             
   }

我注册了一个位置更新,时间间隔为0,最小距离为10,用于频繁更新。这里我的问题是地图视图总是抖动,有谁能告诉我如何像其他应用程序(如waze maps)一样平滑地旋转地图视图。谢谢…

您是在尝试以平滑的方式(如一次旋转一度)旋转地图,还是在位置更新时让地图从a度旋转到B度

差不多

while (oldAngle != newAngle)
{
mapView.rotate(newAngle);
// this is where you would decied to add or subtract; 
newAngle ++ or -- ; 
}
不确定这是否会像循环运行得很快那样工作,所以可以将其作为异步任务来执行,并在其中添加一个暂停来模拟平滑的旋转

Double angle = Math.atan2((userstartPoint.getX() - userendPoint.getX()), userstartPoint.getY() - userendPoint.getY());
            angle = Math.toDegrees(angle);
            map.setRotationAngle(angle);
所以基本上我得到了起点(新位置),然后是终点(旧位置),然后对它进行Math.atan2,如您所见。然后将其转换为度数,并将其设置为“我的贴图旋转”。
现在它没有平滑的旋转,但我不需要。在这里,您可以设置自己的步进器以实现平滑旋转。除非谷歌地图已经有了

由于该位置的方向角值不是很精确,并且有跳跃的趋势,因此应使用方向角过滤器。例如,将最后5个方向角值保留在一个数组中,并使用这些值的平均值作为旋转贴图的方向角。或者使用中介绍的过滤器-它更易于使用,可以更好地调整

这将平滑贴图的旋转。保持它更稳定

编辑:

低通滤波器的一个版本:

public static float exponentialSmoothing(float input, float output, float alpha) {
    output = output + alpha * (input - output);
    return output;
}
像这样使用它:

final static float ALPHA = 0.33; // values between 0 and 1
float bearing;

// on location/bearing changed:

bearing = exponentialSmoothing(bearing, newBearing, ALPHA);
方位
将是用于实际旋转贴图的值,
新方位
将是从每个事件中获得的方位,使用
ALPHA
可以通过加权结果中考虑了多少旧方位和新方位来控制旋转作用到新方位的速度。值越小,旧值的权重越高,值越高,新值的权重越高


我希望结果会更好

要更改地图的方位,请使用
摄影机
类。你可以用新的方位定义一个新的
CameraPosition
,并告诉相机使用
GoogleMap.moveCamera
GoogleMap.animateCamera
移动,如果你想平滑移动的话。

我已经在我的应用程序中实现了这一点。我基本上做的是,我取路径的最后一个和第二个最后一个板条,用

public static float getRotationAngle(LatLng secondLastLatLng, LatLng lastLatLng)
{
    double x1 = secondLastLatLng.latitude;
    double y1 = secondLastLatLng.longitude;
    double x2 = lastLatLng.latitude;
    double y2 = lastLatLng.longitude;

    float xDiff = (float) (x2 - x1);
    float yDiff = (float) (y2 - y1);

    return (float) (Math.atan2(yDiff, xDiff) * 180.0 / Math.PI);

}
将此角度设置为相机位置的方向角


注意:有时(很少)它会将贴图旋转到相反的方向。我正在寻找它,但如果有人有理由,请回复。

如果用户改变其行驶方向,例如,如果他左转,它应该向左旋转。您可以尝试获取旧的map.angle,然后获取新的航向,并通过一个循环运行,该循环可以一次减去或增加新航向1度然后每次都将其设置为map.rotation。@科纳德谢谢你的想法,我尝试了这个方法,但效果不太好,因为如果我们试图根据航向旋转,如果用户设备指向不同的航向,那么它就不能准确旋转。下面是我在应用程序中使用的地图角度旋转,现在这有点不同了,因为我使用的是Esri API而不是谷歌,但我相信你可以实现这一点!!!将代码添加到我原来的帖子中@科纳德:我不明白u-r代码中的userStart x和y是什么。你需要澄清一下,问题是否在于你从gps上获得的方位。或者实际旋转到一个新的轴承,这就是康拉德所说的。@l如果是的,你纠正我得到的轴承是跳跃的。你对此有什么想法吗?我知道你走得越快越好。你需要对你得到的值进行某种过滤。@l是的,你知道我们应该在这里使用哪个过滤器吗。我在我的应用程序中没有做过任何过滤,做过同样的事情。过滤只会使它在开始移动时速度变慢,从而获得一个好的方向。如果我要过滤,我会做一个简单的新标题=(旧标题*(1-filter))+(gps标题*过滤器)样式,然后从0.25开始尝试过滤值。这将需要一些调整来处理359-0的不连续性,但是如果差值大于180度,则需要一些简单的加减360。感谢你的想法,我尝试了平均方位,但旋转不正确,我还检查了平均值是否大于或等于360,然后我将其调整到360。是的,这里有一些微妙之处,因为方位在北半球跳跃。0/360度——尝试实现我添加到答案中的低通滤波器。