2013-01-14 102 views
19

如果您打開Goog​​le地圖應用程序,屏幕右上方會出現一個按鈕,您可以按此按鈕將地圖居中放置在當前位置。該按鈕的圖標隨即更改。如果再次按下相同的按鈕,地圖會根據您的指南針標題自動旋轉。換句話說,地圖變成了以自我爲中心(相對於以異性爲中心的AKA始終向上)。安卓地圖自動旋轉

谷歌最近推出的地圖API V2爲Android,我當然喜歡它比舊的更多。默認情況下,android maps V2將包含「位置中心」按鈕。但是,多次按下它不會啓用自動旋轉;它只是試圖將地圖重新​​定位到您的位置。

有沒有人知道我可以使用地圖API v2自動旋轉地圖,就像谷歌地圖應用程序一樣?我必須自己實現這個功能嗎?還是在API中,我只是沒有看到它?我感謝所有幫助。

+0

這是有幫助的......我甚至不知道這個功能,謝謝。對我來說,它工作正常(v7) –

+0

他,我想做同樣的事情,請分享你的解決方案,如果你已經這樣做。 –

回答

22

好這是我認爲應該在一年後完成的方式。如果您發現任何問題,請糾正我。

大部分以下代碼處理座標系之間的差異。我正在使用旋轉矢量傳感器。從文檔: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)); 
} 
+1

mRotationMatrix? – Anthone

+1

'private float [] mRotationMatrix = new float [16];' 'getRotationMatrixFromVector'將根據事件中的值填充'mRotationMatrix'。 –

+0

這會在地圖上產生閃爍效果,我該如何限制旋轉 – Bytecode

1

您可以通過在Sensor Listener上註冊您的應用程序定位並獲取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)); 

} 
5

我已經成功實施aleph_null解決方案,在這裏我將添加未在接受的解決方案中提到的一些細節:

對於上述解決方案正常工作,您需要實現android.hardware.SensorEventListener接口。

您也需要註冊到SensorEventListener在你的onResume和方法的onPause如下:

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

'mRotVectSensor'? – theapache64

+0

其中是角度定義 – suulisin