簡體   English   中英

android地圖自動旋轉

[英]android maps auto-rotate

如果您打開 Google 地圖應用程序,屏幕右上角有一個按鈕,您可以按下該按鈕以將地圖置於當前位置的中心。 然后按鈕的圖標會發生變化。 如果您再次按下同一個按鈕,地圖會根據您的羅盤航向自動旋轉。 換句話說,地圖變得以自我為中心(與以異體為中心的又名北總是向上相反)。

Google 最近推出了適用於 Android 的地圖 API V2,我當然比舊版本更喜歡它。 默認情況下,android maps V2 將包含“位置中心”按鈕。 但是,多次按下它不會啟用自動旋轉; 它只是嘗試再次將地圖以您的位置為中心。

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

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

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

可以通過使用 Sensor Listener for Orientation 注冊您的應用程序並獲取相對於 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));

}

抱歉,您必須自己使用傳感器管理器相機來實現

如果這些函數可用於 map api V2,它們肯定會在GoogleMapUiSettings 上

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM