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

11

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

   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地图)那样平滑旋转地图视图吗?谢谢...


你需要澄清一下问题是GPS获取的轴承跳动,还是Konrad所说的实际旋转到新轴承。 - Ifor
@lfor 是的,你说得对,我得到的轴承值一直在跳动。你有什么想法吗? - dharan
我知道你越快就会变得越好。你需要对获取的值进行某种过滤。 - Ifor
@lfor 你有任何想法在这里应该使用哪种过滤器吗? - dharan
我的应用程序中没有进行任何过滤,但是它们执行相同类型的操作。过滤只会使得开始移动时速度变慢。如果我要进行过滤,我会使用一个简单的新方向计算方式:new_heading = (old_heading * (1-filter)) + (gps_heading * filter),然后尝试一些不同的过滤值,例如从0.25开始。这将需要进行一些微调来处理359-0的不连续性,但如果差异超过180度,则可以通过加上或减去360来解决问题。 - Ifor
显示剩余2条评论
4个回答

4
你是否想以平滑的方式旋转地图,例如每次旋转一度,或者只是在位置更新时将其从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操作,如您所见。然后将其转换为角度,并将其设置为我的地图旋转。现在它不会进行平滑旋转,但我不需要那个。在这里,您可以为平稳旋转设置自己的步进器,除非google maps已经有一个。


如果用户改变了行驶方向,我必须将其旋转,例如,如果他向左转弯,它应该向左旋转。 - dharan
你可以尝试的方法是获取旧地图的角度,然后获取新的方向并通过循环逐渐减少或增加1度,并将每次的值设置为地图的旋转角度。 - Konrad Winkowski
这是我在我的应用程序中用于地图角度旋转的代码,现在这有点不同,因为我使用的是Esri API而不是Google,但我相信你可以实现这个功能。 !!! 我已将代码添加到原始帖子中 !!! - Konrad Winkowski
@Konard,我尝试了您的解决方案,但它并没有像预期的那样工作。 - dharan
你尝试使用Math.atan2了吗?它应该会返回一个角度,你可以将其转换为度数,并传递给你的地图视图以此旋转地图。 - Konrad Winkowski
显示剩余6条评论

3
由于位置的承载值不是非常精确且往往会有一些跳动,因此您应该对轴承使用滤波器。例如,将最后5个轴承值保存在数组中,并使用这些值的平均值作为旋转地图时的轴承。或者使用SensorEvent文档中解释的滤波器 - 它更易于使用并可以更好地进行调整。
这将使地图的旋转更加平稳/稳定。
编辑:低通滤波器的一个版本:
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);

bearing是实际旋转地图所需的值,newBearing是来自每个事件的方位角,使用ALPHA可以控制旋转速度,通过加权考虑多少旧的和新的方位角的结果。小的值更重视旧值,大的值更重视新值。

希望这样更易理解。


谢谢您的建议,我尝试了平均方位角,但旋转不正确。我还检查了平均值是否大于或等于360,并将其设置为360。 - dharan
是的,这里有一些微妙之处,因为方位角会在北方或0/360度周围跳动 - 请尝试我在答案中添加的低通滤波器实现。 - Ridcully

1
要更改地图的方位角,请使用Camera类。您可以使用新的方位角定义一个新的CameraPosition,然后使用GoogleMap.moveCameraGoogleMap.animateCamera告诉相机移动,如果您想要平滑的移动。

0
我在我的应用程序中已经实现了这一点。基本上我所做的是,取路径的最后一个和倒数第二个LatLng,并通过使用计算方位角。
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);

}

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

注意:有时(很少)它会将地图旋转到相反的方向。我正在寻找原因,如果有人知道,请回复。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接