【问题标题】:android maps auto-rotateandroid地图自动旋转
【发布时间】:2012-12-28 12:08:04
【问题描述】:

如果您打开 Google 地图应用,屏幕右上角有一个按钮,您可以按下该按钮将地图置于您当前位置的中心。然后按钮的图标会发生变化。如果您再次按下相同的按钮,地图会根据您的指南针方向自动旋转。换句话说,地图变得以自我为中心(与以自我为中心的 AKA 始终向上相反)。

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

有谁知道我可以像谷歌地图应用一样使用地图 API v2 自动旋转地图吗?我必须自己实现这个功能,还是在 API 中,我只是没有看到它?感谢所有帮助。

【问题讨论】:

  • 这很有帮助...我什至不知道该功能,谢谢。对我来说,它工作正常(v7)
  • 他,我也想做同样的事情,如果你这样做了,请分享你的解决方案。

标签: android google-maps autorotate


【解决方案1】:

好的,这就是我认为应该在一年后完成的方式。如果您发现任何问题,请纠正我。

以下大部分代码都处理坐标系之间的差异。我正在使用旋转矢量传感器。来自文档:Y is tangential to the ground at the device's current location and points towards magnetic north. 另一方面,谷歌地图中的方位似乎指向真北。 this page shows how the conversion is done

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();
} 

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);  
    }
}

3) 更新地图

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

    CameraPosition pos = CameraPosition.builder(oldPos).bearing(bearing).build();
            mMap.moveCamera(CameraUpdateFactory.newCameraPosition(pos));
}

【讨论】:

  • private float[] mRotationMatrix = new float[16]; getRotationMatrixFromVector 将根据事件中的值填充mRotationMatrix
  • 这会在地图上产生闪烁效果,我该如何限制旋转
  • 需要注意的是 getRotationMatrixFromVector() 将此限制为 API 9+。应该与那些支持旧版应用的人相关。
  • 您好,我实现了上面的代码,我的应用程序中有旋转功能,但谷歌地图不断向上移动。
  • 和 mDeclination?
【解决方案2】:

我已经成功实现了 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);
}

“@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]);
    }
}

【讨论】:

  • mRotVectSensor ?
  • 角度定义在哪里
  • mRotVectSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
【解决方案3】:

可以通过向传感器监听器注册您的应用程序以获取方向并在 onSensorChanged 中获取相对于真北的角度并相应地更新相机。 角钢可用于承重。可以使用以下代码:

Instead of using Sensor.TYPE_ORIENTATION try using getOrinetation api. Sensor.TYPE_ORIENTATION
has been deprecated.

@Override
protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();
    if (sensorManager != null)
        sensorManager.registerListener(this,
                sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
                SensorManager.SENSOR_DELAY_GAME);
}

public void onSensorChanged(SensorEvent event) {

    float degree = Math.round(event.values[0]);

    Log.d(TAG, "Degree ---------- " + degree);

    updateCamera(degree);

}

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

    CameraPosition pos = CameraPosition.builder(oldPos).bearing(bearing)
            .build();

    googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(pos));

}

【讨论】:

    【解决方案4】:

    抱歉,您必须自己使用 sensor managercamera 实现它

    如果地图 api V2 可以使用这些功能,它们肯定会在 GoogleMapUiSettings

    【讨论】:

      【解决方案5】:

      新的 Location 类已经自动为您提供方位,为什么不使用它呢?

      示例代码:

      private void updateCameraBearing(GoogleMap googleMap, Location myLoc) {
          if ( googleMap == null) return;
          CameraPosition camPos = CameraPosition
                  .builder(googleMap.getCameraPosition())
                  .bearing(myLoc.getBearing())
                   // if you want to stay centered - then add the line below
                  .target(new LatLng(myLoc.getLatitude(), myLoc.getLongitude()))
                  .build();
          googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(camPos));
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-26
        • 2014-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多