A demo application which demonstrates movement of car on map developed after inspiration from Uber.
Youtube Link: https://www.youtube.com/watch?v=JIs4kLZ8qQI
APIs and Libraries used
- Google Maps Api
- Google Maps Directions API
- Volley
Steps:
- Parse the "overview_polyline" from the JSON by providing the appropriate GET parameters. For eg:
"https://maps.googleapis.com/maps/api/directions/json?" + "mode=driving&" + "transit_routing_preference=less_driving&" + "origin=" + latitude + "," + longitude + "&" + "destination=" + destination + "&" + "key=" + getResources().getString(R.string.google_directions_key)
- Decode the polyline which will provide you with list of latitudes and longitudes that is List<LatLng> to be apt.
- Setting up of Value animator:Create a value animator by providing the ofFloatValue, setting duration and adding update listener in Handler
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1); valueAnimator.setDuration(3000); valueAnimator.setInterpolator(new LinearInterpolator()); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { //CODE
});
- In the value animator Update listener get the Animation fraction and evaluate the latitudes and longitudes as shown:
where v is animation fraction and startposition and endPostion refer to each pair of LatLng from the decoded list from polyline for eg (0,1) then (1,2) then(2,3) and so on.
v=valueAnimator.getAnimatedFraction(); lng = v * endPosition.longitude + (1 - v)* startPosition.longitude; lat = v * endPosition.latitude + (1 - v)* startPosition.latitude;
According to linear interpolation: The parameter 'v' defines where to estimate the value on the interpolated line, it is 0 at the first point and 1 and the second point. For interpolated values between the two points v ranges between 0 and 1. We evaluate values one by one between each pair of LatLng by traversing through the list. -
Finally set position of marker to the new position, also evaluating the bearing between the consecutive points so that it seems car is turning literally
and finally update camera as:
marker.setPosition(newPos); marker.setAnchor(0.5f, 0.5f); marker.setRotation(getBearing(startPosition, newPos)); mMap.moveCamera(CameraUpdateFactory .newCameraPosition (new CameraPosition.Builder() target(newPos) .zoom(15.5f) .build()));