Как плавно поворачивать карту с помощью подшипника в андроиде
Я пытаюсь повернуть вид карты, когда пользователь меняет направление, т.е. если пользователь принимает левый и правый повороты, он должен вращаться соответственно. Я вращаю карту, основываясь на текущем местоположении, которое оно вращается правильно, но оно дрожало. код, который я использовал для вращения
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);
}
Установите этот угол в качестве положения камеры.
Примечание. Иногда (редко) он поворачивает карту в противоположном направлении. Я ищу его, но если кто-то получил разум, ответьте.