Marker shaky on adding animation google maps android - android

I am using this code to animate the marker to kinda replicate the movement of a vehicle on the google maps but the marker shakes vigorously when marker.setPosition is called in the handler function. Code is below:
public static void animateMarker(final GoogleMap map, final Marker marker, final LatLng toPosition) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
Projection proj = map.getProjection();
Point startPoint = proj.toScreenLocation(marker.getPosition());
final LatLng startLatLng = proj.fromScreenLocation(startPoint);
final long duration = 5000;
final Interpolator interpolator = new LinearInterpolator();
handler.post(new Runnable() {
#Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - start;
float t = interpolator.getInterpolation((float) elapsed / duration);
double lng = t * toPosition.longitude + (1 - t) * startLatLng.longitude;
double lat = t * toPosition.latitude + (1 - t) * startLatLng.latitude;
marker.setPosition(new LatLng(lat, lng));
if (t < 1.0) {
handler.postDelayed(this, 16);
}
}
});
}

Try using the AccelerateDecelerateInterpolator, an interpolator whose rate of change starts and ends slowly but accelerates through the middle, instead of LinearInterpolator as used in this Google video tutorial. The marker animation was seamless. Here's the snippet:
public class MarkerAnimation {
static void animateMarkerToGB(final Marker marker, final LatLng finalPosition, final LatLngInterpolator latLngInterpolator) {
final LatLng startPosition = marker.getPosition();
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final Interpolator interpolator = new AccelerateDecelerateInterpolator();
final float durationInMs = 3000;
handler.post(new Runnable() {
long elapsed;
float t;
float v;
#Override
public void run() {
// Calculate progress using interpolator
elapsed = SystemClock.uptimeMillis() - start;
t = elapsed / durationInMs;
v = interpolator.getInterpolation(t);
marker.setPosition(latLngInterpolator.interpolate(v, startPosition, finalPosition));
// Repeat till progress is complete.
if (t < 1) {
// Post again 16ms later.
handler.postDelayed(this, 16);
}
}
});
}
Full code [here](https://gist.github.com/broady/6314689).

Related

Android - Adding Scale animation to cluster marker?

I have implemented google map clusters and i want scale animation in the marker clusters, please see the video, i want the same animation which is present in the video.
I have tried the animation but it is not playing the same. I am posting my code.
private void animateMarkerDropping(final Marker marker) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final long duration = 800;
final Interpolator interpolator = new AccelerateInterpolator();
handler.post(new Runnable() {
#Override
public void run() {
final long elapsed = SystemClock.uptimeMillis() - start;
final float t = Math.max(1 -
interpolator.getInterpolation((float) elapsed / duration), 0);
//Log.e("---t----",""+t);
marker.setAnchor(0.5f, 1f + 14 * t);
if (t > 0f) {
handler.postDelayed(this, 15);
}
}
});
}
My requirement is : please see the video.
https://files.fm/f/vtg2pge5

Rotate marker/car icon in google maps - Android

I am trying to crate a app like ola/uber. I want to move the icon and rotate when road turn left or right. I am using following code.
private void rotateMarker(final Marker marker, final float toRotation) {
if(!isMarkerRotating) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final float startRotation = marker.getRotation();
final long duration = 1000;
final Interpolator interpolator = new LinearInterpolator();
handler.post(new Runnable() {
#Override
public void run() {
isMarkerRotating = true;
long elapsed = SystemClock.uptimeMillis() - start;
float t = interpolator.getInterpolation((float) elapsed / duration);
float rot = t * toRotation + (1 - t) * startRotation;
marker.setRotation(-rot > 180 ? rot / 2 : rot);
if (t < 1.0) {
// Post again 16ms later.
handler.postDelayed(this, 16);
} else {
isMarkerRotating = false;
}
}
});
}
}
To calculate bearing:
currentLocation = location;
if(previousLocaton!=null){
previousLocaton = tempLocation;
tempLocation = currentLocation;
Log.d("previousLocaton=====> ",""+previousLocaton);
Log.d("currentLocation=====> ",""+currentLocation);
bearing = previousLocaton.bearingTo(currentLocation) ;
}else{
previousLocaton = location;
tempLocation = location;
}
To set the bearing:
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(latLng).zoom(14).bearing(bearing).build();
To rotate the marker I call roateMarker method in onLocationChanged changed method:
currLocationMarker = mMap.addMarker(markerOptions);
rotateMarker(currLocationMarker,bearing);
Now my icon is rotating. But google map also get rotating. I want rotate icon alone. I refer the following link for animate and move the marker. Link 1. Please let me any idea to solve my issue.
there is simple method available for marker
marker.rotation(float value)
Sets the rotation of the marker in degrees clockwise about the marker's anchor point. The axis of rotation is perpendicular to the marker. A rotation of 0 corresponds to the default position of the marker. When the marker is flat on the map, the default position is North aligned and the rotation is such that the marker always remains flat on the map. When the marker is a billboard, the default position is pointing up and the rotation is such that the marker is always facing the camera. The default value is 0.
To rotate only the marker set rotation to marker using setRotation(float) method.
static public void rotateMarker(final Marker marker, final float toRotation) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final float startRotation = marker.getRotation();
final long duration = 1000;
final Interpolator interpolator = new LinearInterpolator();
L.d("Bearing: "+toRotation);
handler.post(new Runnable() {
#Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - start;
float t = interpolator.getInterpolation((float) elapsed / duration);
float rot = t * toRotation + (1 - t) * startRotation;
marker.setRotation(-rot > 180 ? rot / 2 : rot);
if (t < 1.0) {
// Post again 10ms later.
handler.postDelayed(this, 10);
}
}
});
}
Try this :
public void animateMarker(final LatLng toPosition, final LatLng startLatLng,
final boolean hideMarker) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
Projection proj = map.getProjection();
Point startPoint = proj.toScreenLocation(d_marker.getPosition());
final LatLng startLatLng = proj.fromScreenLocation(startPoint);
// final CameraPosition newcameraPosition = null;
final Interpolator interpolator = new LinearInterpolator();
handler.post(new Runnable() {
#Override
public void run() {
Location prevLoc = new Location("service Provider");
prevLoc.setLatitude(startLatLng.latitude);
prevLoc.setLongitude(startLatLng.longitude);
Location newLoc = new Location("service Provider");
newLoc.setLatitude(toPosition.latitude);
newLoc.setLongitude(toPosition.longitude);
System.out.println("Locations ---- " + prevLoc + "-" + newLoc);
float bearing = prevLoc.bearingTo(newLoc);
long elapsed = SystemClock.uptimeMillis() - start;
float t = interpolator.getInterpolation((float) elapsed
/ 1000);
double lng = t * toPosition.longitude + (1 - t)
* startLatLng.longitude;
double lat = t * toPosition.latitude + (1 - t)
* startLatLng.latitude;
d_marker.setPosition(new LatLng(lat, lng));
d_marker.setRotation(bearing);
d_marker.setFlat(true);
// googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(newcameraPosition));
if (t < 1.0) {
// Post again 16ms later.
handler.postDelayed(this, 16);
} else {
if (hideMarker) {
d_marker.setVisible(false);
} else {
d_marker.setVisible(true);
}
}
}
});
}
Try Below method:
public void animateMarker(final LatLng toPosition,
final boolean hideMarker) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
Projection proj = googleMap.getProjection();
Point startPoint = proj.toScreenLocation(cabMarker.getPosition());
final LatLng startLatLng = proj.fromScreenLocation(startPoint);
// final CameraPosition newcameraPosition = null;
final Interpolator interpolator = new LinearInterpolator();
handler.post(new Runnable() {
#Override
public void run() {
Location prevLoc = new Location("service Provider");
prevLoc.setLatitude(startLatLng.latitude);
prevLoc.setLongitude(startLatLng.longitude);
Location newLoc = new Location("service Provider");
newLoc.setLatitude(toPosition.latitude);
newLoc.setLongitude(toPosition.longitude);
System.out.println("Locations ---- " + prevLoc + "-" + newLoc);
float bearing = prevLoc.bearingTo(newLoc);
long elapsed = SystemClock.uptimeMillis() - start;
float t = interpolator.getInterpolation((float) elapsed
/ 1000);
double lng = t * toPosition.longitude + (1 - t)
* startLatLng.longitude;
double lat = t * toPosition.latitude + (1 - t)
* startLatLng.latitude;
cabMarker.setPosition(new LatLng(lat, lng));
cabMarker.setRotation(bearing);
// googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(newcameraPosition));
if (t < 1.0) {
// Post again 16ms later.
handler.postDelayed(this, 16);
} else {
if (hideMarker) {
cabMarker.setVisible(false);
} else {
cabMarker.setVisible(true);
}
}
}
});
}

Marker move on map but sometimes it is revolving at 360 degree in android

I am facing an issue right now I am developing an Android app similar to Uber or lyft but the problem that I am facing is the car is moving on the map smoothly but sometimes it is revolving at 360 degree at one position, I need to stop that please help, here is my animation code.
private void animateMarkr(double laat, double lnng,Location prevLocation)
{
final LatLng toPosition=new LatLng(laat,lnng);
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
Projection proj = mGoogleMap.getProjection();
Point startPoint = proj.toScreenLocation(carMarker.getPosition());
final LatLng startLatLng = proj.fromScreenLocation(startPoint);
final long duration = 3000;
final boolean hideMarker=false;
final Interpolator interpolator = new LinearInterpolator();
handler.post(new Runnable() {
#Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - start;
LatLng pre=carMarker.getPosition();
float t = interpolator.getInterpolation((float) elapsed / duration);
double lng = t toPosition.longitude + (1 - t) startLatLng.longitude;
double lat = t toPosition.latitude + (1 - t) startLatLng.latitude;
// carMarker.setRotation(getBearing(pre,new LatLng(lat,lng)));
carMarker.setPosition(new LatLng(lat, lng));
if (t < 1.0) {
// Post again 16ms later.
handler.postDelayed(this, 20);
} else {
if (hideMarker) {
carMarker.setVisible(false);
} else {
carMarker.setVisible(true);
}
}
}
});
}
Here is my Rotation Code
private void rotateMarker(Location location,Location preLocation){
Location prevLocation = new Location(LocationManager.GPS_PROVIDER);
prevLocation.setLatitude(carMarker.getPosition().latitude);
prevLocation.setLongitude(carMarker.getPosition().longitude);
final float toRotation = prevLocation.bearingTo(location);
performRotaion(toRotation);
}
private void performRotaion(final float toRotation){
if(!isMarkerRotating) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final float startRotation = carMarker.getRotation();
final float totalDegree=0;
final long duration = 1000;
final Interpolator interpolator = new LinearInterpolator();
handler.post(new Runnable() {
#Override
public void run() {
isMarkerRotating = true;
long elapsed = SystemClock.uptimeMillis() - start;
float t = interpolator.getInterpolation((float) elapsed / duration);
float rot = t toRotation + (1 - t) startRotation;
if(carMarker != null){
carMarker.setAnchor(0.5f, 0.5f);
// if(rot<0.0f && rot>-355.0f) {
carMarker.setRotation(-rot > 180 ? rot / 2 : rot);
carMarker.setFlat(true);
}
if (t < 1.0) {
handler.postDelayed(this, 16);
} else {
isMarkerRotating = false;
}
}
});
}
}
// method call
rotateMarker(location,previcsLocation);
animateMarkr(location.getLatitude(), location.getLongitude(),previcsLocation);
I have implemented the check to stop rotation if the degree is 360 also I have checked if the degree is more than 180 degree than divide the same and move the car on that angle. But nothing works
Before calling these functions
rotateMarker(location,previcsLocation);
animateMarkr(location.getLatitude(), location.getLongitude(),previcsLocation);
in your code. You'll have to add a check for the new (Latitude,Logitude) which comes through the server and marker's (Latitude,Logitude) if both values are same then you should avoid to call the above functions.
Only you have to add this condition in it.
LatLng new_location = new LatLng(data.getLatitude(), data.getLongitude());
//new_location is coming through the server
LatLng current_location = marker.getPosition();
//this is the marker's location
if (current_location != new_location) {
if (current_location.equals(new_location)) {
Log.d(TAG, "LatLng " + "---------current_location-" + current_location);
Log.d(TAG, "LatLng " + "---------new_location-" + new_location);
return;
}
rotateMarker(location,previcsLocation);
animateMarkr(location.getLatitude(), location.getLongitude(),previcsLocation);
}
It worked in my project.

Implement smooth transition to emulate car marker moving on the map

I want to implement smooth transition to emulate car marker moving on the map. From current postion to selected position.
Even if I suppose that you hadn't try anything, I give you a great method to achieve that .. just because I'm in a good mood
public static void animateMarker(final GoogleMap map, final Marker marker, final LatLng toPosition,
final boolean hideMarker) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
Projection proj = map.getProjection();
Point startPoint = proj.toScreenLocation(marker.getPosition());
final LatLng startLatLng = proj.fromScreenLocation(startPoint);
final long duration = 500;
final Interpolator interpolator = new LinearInterpolator();
handler.post(new Runnable() {
#Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - start;
float t = interpolator.getInterpolation((float) elapsed / duration);
double lng = t * toPosition.longitude + (1 - t) * startLatLng.longitude;
double lat = t * toPosition.latitude + (1 - t) * startLatLng.latitude;
marker.setPosition(new LatLng(lat, lng));
if (t < 1.0) {
// Post again 16ms later.
handler.postDelayed(this, 16);
} else {
if (hideMarker) {
marker.setVisible(false);
} else {
marker.setVisible(true);
}
}
}
});
}
Enjoy it!

How to smoothly keep moving current location marker in Google Maps v2 android

I have placed a marker for my location. I would like to move my marker smoothly something like the Google maps app. The blue circle moves very smoothly when I keep moving in my car. I would like implement the same for my app. how do I implement this on my app?
As of now my location marker just jumps for different location on very location change and marks the marker there.
Here is what I have don:
googleMap.setMyLocationEnabled(true);
So onMyLocationChange method is called automatically:
#Override
public void onMyLocationChange(Location location)
{
curlat = location.getLatitude();
curlong = location.getLongitude();
if (markermylocation != null)
{
markermylocation.remove();
}
curlat = location.getLatitude();
curlong = location.getLongitude();
myLocation(curlat, curlong, username, imageURL, ZOOMVALUE);
}
in mylocaiton method:
private void myLocation(double lat, double lng, String name, String url, float zoom)
{
if(firsttime == 1)
{
LatLng ll = new LatLng(lat,lng);
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(ll, zoom);
googleMap.animateCamera(update);
firsttime = 0;
}
final String uname = name;
curlat = lat;
curlong = lng;
LatLng position = new LatLng(curlat, curlong);
markerOptionsmylocaiton = new MarkerOptions().position(position).icon(BitmapDescriptorFactory.fromBitmap(icon)).title(uname).anchor(0.5f, 1f);
markermylocation = googleMap.addMarker(markerOptionsmylocaiton);
LatLng latlang = new LatLng(curlat, curlong);
animateMarker(markermylocation, latlang, false);
}
So everytime mylocation is called the marker gets removed and calls mylocation method and then creates the marker in the new postition. Instead I would like to get a smooth transition of the marker like Google maps? How to implement this?
Update:
After working couple of times on this: I came to this code finally but then my markers are not showing up:
I am using the below method and calling this every time in myLocation method.
public void animateMarker(final Marker marker, final LatLng toPosition,
final boolean hideMarker)
{
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
Projection proj = googleMap.getProjection();
Point startPoint = proj.toScreenLocation(marker.getPosition());
final LatLng startLatLng = proj.fromScreenLocation(startPoint);
final long duration = 500;
final Interpolator interpolator = new LinearInterpolator();
handler.post(new Runnable()
{
#Override
public void run()
{
long elapsed = SystemClock.uptimeMillis() - start;
float t = interpolator.getInterpolation((float) elapsed
/ duration);
double lng = t * toPosition.longitude + (1 - t)
* startLatLng.longitude;
double lat = t * toPosition.latitude + (1 - t)
* startLatLng.latitude;
marker.setPosition(new LatLng(lat, lng));
if (t < 1.0)
{
// Post again 16ms later.
handler.postDelayed(this, 16);
}
else
{
if (hideMarker)
{
marker.setVisible(false);
}
else
{
marker.setVisible(true);
}
}
}
});
}
Thanks!
Hi I have also the same thing in one of my project and it works like charm.
Add the below piece of code after this line :
marker.setPosition(new LatLng(lat, lng));
//this code
if (googleMap != null)
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lng), 15.0f));
Hope it will help you.
Thanks
You'll have to use an interpolator a linear or maybe an acceleration interpolator between the new latlng of the location and the current latlng of the marker. Here's an example with a bounce interpolator.
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final long duration = 2500;
final Interpolator interpolator = new BounceInterpolator();
marker.setVisible(true);
handler.post(new Runnable() {
#Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - start;
float t = Math.max(
1 - interpolator.getInterpolation((float) elapsed
/ duration), 0);
marker.setAnchor(0.5f, 1.0f + 6 * t);
marker.setPosition(latlng)
if (t > 0.0) {
// Post again 16ms later.
handler.postDelayed(this, 16);
}
}
});

Categories

Resources