Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to rotate map view smoothly with bearing in android

I am trying to rotate map view when the user changes his direction ie if user takes left and right turns it should rotate accordingly.I am rotating map view basing on current location bearing it is rotating correctly but it was jittering.Here is the code which i used for rotation

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

I registered a location updates with time interval 0 and min distance of 10 for frequent updates.Here my problem is map view is jittering always,can any one tell me how can I smoothly rotate map view like other applications like waze maps do.Thanks...

like image 784
dharan Avatar asked Sep 12 '12 07:09

dharan


3 Answers

are you trying to rotate the map in a smooth way such as by one degree at a time or just have it go from degree A to degree B on location update ?

Something like

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

not sure if this would work exactly as the loop would run really quickly so maybe do this as a asynctask and add a pause in there to simulate a smooth rotation.

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

so basically I get the start point (new location) and then the end point (old location) and do a Math.atan2 on it as you can see. Then convert that to a degree and set it to my map rotation. Now it does not do a smooth rotation but I don't need that. Here is where you could set up your own stepper for a smooth rotate. Unless the google maps already has one.

like image 65
Konrad Winkowski Avatar answered Oct 18 '22 19:10

Konrad Winkowski


As the bearing values of the Location are not very exact and tend to jump a little, you should use a filter for the bearing. For example, keep the last 5 bearing-values in an array and use the average of those values as the bearing to rotate the map to. Or use the filter explained in the SensorEvent docs - it's easier to use and can be tweaked better.

This will smoothen out the rotation of the map resp. keep it more stable.

EDIT:

A version of the low-pass filter:

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

use it like so:

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

// on location/bearing changed:

bearing = exponentialSmoothing(bearing, newBearing, ALPHA);

bearing would be the value to use to actually rotate the map, newBearing would be the bearing you get from every event, and with ALPHA you can control how quickly or slowly the rotation acts to a new orientation by weighting how much of the old and the new bearing is taken into account for the result. A small value weighs the old value higher, a high value weighs the new value higher.

I hope that works out better.

like image 3
Ridcully Avatar answered Oct 18 '22 20:10

Ridcully


To change the bearing of your map, use the Camera class. You can define a new CameraPosition with the new bearing and tell the camera to move with either GoogleMap.moveCamera or GoogleMap.animateCamera if you want a smooth movement.

like image 1
VD63 Avatar answered Oct 18 '22 21:10

VD63