android地图自动旋转

ale*_*ull 21 android google-maps autorotate

如果您打开Goog​​le地图应用,则屏幕右上角会显示一个按钮,您可以按此按钮将地图置于当前位置的中心位置.然后按钮的图标会发生变化.如果再次按相同按钮,地图将根据指南针标题自动旋转.换句话说,地图变得以自我为中心(与分配中心AKA北方总是向上)相反.

Google最近推出了适用于Android的地图API V2,我当然比旧版更喜欢它.默认情况下,android maps V2将包含"center on location"按钮.但是,多次按下它不会启用自动旋转; 它只是试图将地图再次置于您的位置.

有没有人知道如何使用地图API v2自动旋转地图就像谷歌地图应用程序一样?我是否必须自己实现此功能,或者它是否在API中,我只是没有看到它?我感谢所有的帮助.

ale*_*ull 25

好的,我认为应该在一年之后完成.如果您发现任何问题,请纠正我.

以下大多数代码处理坐标系之间的差异.我正在使用旋转矢量传感器.来自文档:Y is tangential to the ground at the device's current location and points towards magnetic north.另一方面,在谷歌地图中,​​似乎指向真正的北方.此页面显示转换是如何完成的

1)从当前GPS位置获取当前偏差

@Override
public void onLocationChanged(Location location) {
    GeomagneticField field = new GeomagneticField(
            (float)location.getLatitude(),
            (float)location.getLongitude(),
            (float)location.getAltitude(),
            System.currentTimeMillis()
        );

    // getDeclination returns degrees
    mDeclination = field.getDeclination();
} 
Run Code Online (Sandbox Code Playgroud)

2)从赤纬和磁北计算轴承

    @Override
public void onSensorChanged(SensorEvent event) {
    if(event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
        SensorManager.getRotationMatrixFromVector(
                mRotationMatrix , event.values);
        float[] orientation = new float[3];
        SensorManager.getOrientation(mRotationMatrix, orientation);
        float bearing = Math.toDegrees(orientation[0]) + mDeclination;
        updateCamera(bearing);  
    }
}
Run Code Online (Sandbox Code Playgroud)

3)更新地图

private void updateCamera(float bearing) {
    CameraPosition oldPos = mMap.getCameraPosition();

    CameraPosition pos = CameraPosition.builder(oldPos).bearing(bearing).build();
            mMap.moveCamera(CameraUpdateFactory.newCameraPosition(pos));
}
Run Code Online (Sandbox Code Playgroud)

  • `private float [] mRotationMatrix = new float [16];``getRotationMatrixFromVector`将根据事件中的值填充`mRotationMatrix`. (2认同)
  • 嗨,我实现了上面的代码,我在我的应用程序中获得了旋转功能,但谷歌地图不断向上移动。 (2认同)

Tec*_*i50 7

我已经成功实现了aleph_null解决方案,在这里我将添加一些在接受的解决方案中没有提到的细节:

要使上述解决方案正常工作,您需要实现android.hardware.SensorEventListener接口.

您还需要在onResume和onPause方法中注册SensorEventListener,如下所示:

@Override
    protected void onResume() {
     super.onResume();
     mSensorManager.registerListener(this,
             mRotVectSensor,
             SensorManager.SENSOR_STATUS_ACCURACY_LOW);
    }

@Override
protected void onPause() {
    // unregister listener
    super.onPause();
    mSensorManager.unregisterListener(this);
}
Run Code Online (Sandbox Code Playgroud)

"@Bytecode"注意事项:为避免闪烁,请在采样周期内使用低值,例如SensorManager.SENSOR_STATUS_ACCURACY_LOW.

我还注意到传感器发送的数据比设备可以处理的时间多一些,因此地图相机开始以奇怪的方式移动!

为了控制onSensorChanged处理的数据量,我建议以下实现:

@Override
public void onSensorChanged(SensorEvent event) {
    if(event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
        SensorManager.getRotationMatrixFromVector(
                mRotationMatrix, event.values);
        float[] orientation = new float[3];
        SensorManager.getOrientation(mRotationMatrix, orientation);
        if (Math.abs(Math.toDegrees(orientation[0]) - angle) > 0.8) {
            float bearing = (float) Math.toDegrees(orientation[0]) + mDeclination;
            updateCamera(bearing);
        }
        angle = Math.toDegrees(orientation[0]);
    }
}
Run Code Online (Sandbox Code Playgroud)