Как плавно поворачивать карту с помощью подшипника в андроиде

Я пытаюсь повернуть вид карты, когда пользователь меняет направление, т.е. если пользователь принимает левый и правый повороты, он должен вращаться соответственно. Я вращаю карту, основываясь на текущем местоположении, которое оно вращается правильно, но оно дрожало. код, который я использовал для вращения

   public void onGPSUpdate(Location location) 
{
     boolean check=isBetterLocation(location, tempLoc);
    tempLoc=location;

     if(check){
        showLocation(location);

     }

}
isBetterLocation method is copied from google docs for better location.

private void showLocation(Location loc){
   mRotateView.rotate(-loc.getBearing());             
   }

Я зарегистрировал обновление местоположения с интервалом времени 0 и минимальным расстоянием 10 для частых обновлений. Здесь моя проблема - отображение карты всегда дрожит, может ли кто-нибудь сказать мне, как я могу плавно поворачивать отображение карты, как и другие приложения, такие как карты Waze?.THANKS...

Ответ 1

Вы пытаетесь повернуть карту плавно, например, на один градус за раз или просто переходите от степени A до степени B при обновлении местоположения?

Что-то вроде

while (oldAngle != newAngle)
{
mapView.rotate(newAngle);
// this is where you would decied to add or subtract; 
newAngle ++ or -- ; 
}

не уверен, что это будет работать точно так же, как цикл будет работать очень быстро, поэтому, возможно, сделайте это как асинтез и добавьте паузу, чтобы имитировать плавное вращение.

Double angle = Math.atan2((userstartPoint.getX() - userendPoint.getX()), userstartPoint.getY() - userendPoint.getY());
            angle = Math.toDegrees(angle);
            map.setRotationAngle(angle);

так что в основном я получаю начальную точку (новое местоположение), а затем конечную точку (старое местоположение) и делаю Math.atan2 на ней, как вы можете видеть. Затем преобразуйте это значение в степень и установите его на поворот карты. Теперь он не делает плавного вращения, но мне это не нужно. Здесь вы можете настроить свой собственный степпер для плавного поворота. Если у карт Google уже есть один.

Ответ 2

Поскольку значения подшипника местоположения не очень точны и имеют тенденцию немного подпрыгивать, вы должны использовать фильтр для подшипника. Например, сохраните последние 5 значений подшипников в массиве и используйте среднее значение этих значений в качестве подшипника для поворота карты. Или используйте фильтр, описанный в Документы SensorEvent - он проще в использовании и может быть улучшен лучше.

Это сгладит вращение карты соответственно. держите его более стабильным.

EDIT:

Версия фильтра нижних частот:

public static float exponentialSmoothing(float input, float output, float alpha) {
    output = output + alpha * (input - output);
    return output;
}

используйте его так:

final static float ALPHA = 0.33; // values between 0 and 1
float bearing;

// on location/bearing changed:

bearing = exponentialSmoothing(bearing, newBearing, ALPHA);

bearing будет значением, которое можно использовать для фактического поворота карты, newBearing будет опорой, которую вы получаете от каждого события, а с помощью ALPHA вы можете контролировать, как быстро или медленно вращение действует в новую ориентацию взвешивая, сколько из старого и нового подшипников учитывается для результата. Небольшое значение весит старое значение выше, высокое значение весит новое значение выше.

Я надеюсь, что это получится лучше.

Ответ 3

Чтобы изменить опору вашей карты, используйте класс Camera. Вы можете определить новый CameraPosition с новым подшипником и сообщить камере двигаться с помощью GoogleMap.moveCamera или GoogleMap.animateCamera, если вы хотите плавное перемещение.

Ответ 4

Я реализовал это в своем приложении. Что я в основном сделал, так это то, что я взял последний и второй последний LatLng моего пути и вычислил несущую с помощью

public static float getRotationAngle(LatLng secondLastLatLng, LatLng lastLatLng)
{
    double x1 = secondLastLatLng.latitude;
    double y1 = secondLastLatLng.longitude;
    double x2 = lastLatLng.latitude;
    double y2 = lastLatLng.longitude;

    float xDiff = (float) (x2 - x1);
    float yDiff = (float) (y2 - y1);

    return (float) (Math.atan2(yDiff, xDiff) * 180.0 / Math.PI);

}

Установите этот угол в качестве положения камеры.

Примечание. Иногда (редко) он поворачивает карту в противоположном направлении. Я ищу его, но если кто-то получил разум, ответьте.