I have followed this answer and its working great. https://stackoverflow.com/a/37048987/4209417
But the issues I'm facing now are:
This is the code I'm using :
private double bearingBetweenLocations(LatLng latLng1,LatLng latLng2) {
double PI = 3.14159;
double lat1 = latLng1.latitude * PI / 180;
double long1 = latLng1.longitude * PI / 180;
double lat2 = latLng2.latitude * PI / 180;
double long2 = latLng2.longitude * PI / 180;
double dLon = (long2 - long1);
double y = Math.sin(dLon) * Math.cos(lat2);
double x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1)
* Math.cos(lat2) * Math.cos(dLon);
double brng = Math.atan2(y, x);
brng = Math.toDegrees(brng);
brng = (brng + 360) % 360;
return brng;
}
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 = 2000;
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;
float bearing = -rot > 180 ? rot / 2 : rot;
marker.setRotation(bearing);
CameraPosition camPos = CameraPosition
.builder(mMap.getCameraPosition())
.bearing(bearing)
.target(marker.getPosition())
.build();
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(camPos));
if (t < 1.0) {
// Post again 16ms later.
handler.postDelayed(this, 16);
} else {
isMarkerRotating = false;
}
}
});
}
}
In onLocationChanged()
float toRotation = (float) bearingBetweenLocations(toLatLng(oldLocation), toLatLng(newLocation));
rotateMarker(my_marker, toRotation);
Marker({ position: a, map: map, icon: { path: google. maps. SymbolPath. FORWARD_CLOSED_ARROW, scale: 6, fillColor: "red", fillOpacity: 0.8, strokeWeight: 2, rotation: angleDegrees //this is how to rotate the pointer } });
initialize() function creates a google Map with location Marker. transition() & moveMarker() are used to move location marker smoothly on Google Map.
So finally found my own answer which i will post here, so others could find it useful.
whenever my onLocationChanged updates, i check my old & current locations then i update the marker. Like below.
double oldLat = oldLocation.getLatitude();
double oldLng = oldLocation.getLongitude();
double newLat = newLocation.getLatitude();
double newLng = newLocation.getLongitude();
if (oldLat != newLat && oldLng != newLng){
updateMyLocation(toLatLng(oldLocation), toLatLng(mCurrentLocation));
}
Also i updated my marker rotation code. This rotates the marker & moves to new location with smooth animation. (adjust duration for smooth animation).
float rotation = (float) SphericalUtil.computeHeading(old, new);
rotateMarker(bus_marker, new, rotation);
private void rotateMarker(final Marker marker, final LatLng destination, final float rotation) {
if (marker != null) {
final LatLng startPosition = marker.getPosition();
final float startRotation = marker.getRotation();
final LatLngInterpolator latLngInterpolator = new LatLngInterpolator.Spherical();
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.setDuration(3000); // duration 3 second
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
try {
float v = animation.getAnimatedFraction();
LatLng newPosition = latLngInterpolator.interpolate(v, startPosition, destination);
float bearing = computeRotation(v, startRotation, rotation);
marker.setRotation(bearing);
marker.setPosition(newPosition);
}
catch (Exception e){
e.printStackTrace();
}
}
});
valueAnimator.start();
}
}
private static float computeRotation(float fraction, float start, float end) {
float normalizeEnd = end - start; // rotate start to 0
float normalizedEndAbs = (normalizeEnd + 360) % 360;
float direction = (normalizedEndAbs > 180) ? -1 : 1; // -1 = anticlockwise, 1 = clockwise
float rotation;
if (direction > 0) {
rotation = normalizedEndAbs;
} else {
rotation = normalizedEndAbs - 360;
}
float result = fraction * rotation + start;
return (result + 360) % 360;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With