Подтвердить что ты не робот

Карты андроидов автоматически вращаются

Если вы открываете приложение Google maps, в верхней правой части экрана есть кнопка, которую вы можете нажать, чтобы центрировать карту в вашем текущем местоположении. Затем значок кнопки изменяется. Если вы снова нажмете ту же кнопку, карта автоматически повернется на основе вашего компаса. Другими словами, карта становится эгоцентричной (в отличие от ассигентов AKA north всегда вверх).

Недавно Google запустил карты API V2 для Android, и мне, конечно, нравится больше, чем старый. По умолчанию карты Android V2 будут включать кнопку "центр по месту". Однако при нажатии на него более одного раза не включается автоматическое вращение; он просто пытается снова центрировать карту на вашем месте.

Кто-нибудь знает, как я могу автоматически поворачивать карту, используя карты API v2, как это делает приложение Google Maps? Должен ли я реализовать эту функциональность самостоятельно или это в API, и я просто не вижу ее? Я ценю всю помощь.

4b9b3361

Ответ 1

Хорошо, вот как я думаю, это должно быть сделано через год. Пожалуйста, поправьте меня, если вы заметите какие-либо проблемы.

В большинстве случаев следующий код касается несоответствия между системами координат. Я использую датчик вектора вращения. Из документов: Y is tangential to the ground at the device current location and points towards magnetic north. С другой стороны, схождение на картах Google, похоже, указывает на истинный север. эта страница показывает, как выполняется преобразование

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

Ответ 2

Я успешно реализовал решение 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]);
    }
}

Ответ 3

Это возможно, зарегистрировав приложение с помощью 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));

}

Ответ 4

Извините, вам придется реализовать его самостоятельно с помощью диспетчера сенсоров и camera

если эти функции были доступны для карты api V2, они, безусловно, были бы на GoogleMap или UiSettings