Googleマップアプリを開くと、画面の右上にボタンがあり、このボタンを押すと、現在地の中心にマップを配置できます。ボタンのアイコンが変わります。同じボタンをもう一度押すと、コンパスの方位に基づいてマップが自動回転します。言い換えると、マップは自我中心になります(同心円のAKAノースが常に上にあるのとは対照的に)。
Googleは最近AndroidのMaps API V2をリリースしましたが、確かに古いものよりも気に入っています。デフォルトでは、Android Maps V2には「center on location "ボタンを押します。ただし、複数回押しても自動回転は有効になりません。単に地図を現在地の中心に配置しようとするだけです。
Googleマップアプリと同じように、maps API v2を使用してマップを自動回転させる方法を誰かが知っていますか?この機能を自分で実装する必要がありますか、それともAPIにありますか?私はすべての助けに感謝します。
わかりました、1年後に行うべきだと私は思います。問題を見つけたら訂正してください。
次のコードのほとんどは、座標系間の不一致を扱います。回転ベクトルセンサーを使用しています。ドキュメントから: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();
}
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));
}
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]);
}
}
アプリケーションを向きのセンサーリスナーに登録し、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));
}
センサーマネージャー と カメラ を使用して自分で実装する必要があります
これらの関数がマップAPI V2で使用できる場合、それらは確かに GoogleMap または iSettings のいずれかにあります。