Reputation: 1200
I am creating android app which shows the location of a bus in map using mapbox sdk. I want to rotate the marker based on location just like Uber app does. How could i achieve this?
Code:
IconFactory iconFactory = IconFactory.getInstance(navigationActivity.this);
Drawable iconDrawable = ContextCompat.getDrawable(navigationActivity.this, R.drawable.bus);
Icon icon = iconFactory.fromDrawable(iconDrawable);
map.clear();
CameraPosition position = new CameraPosition.Builder()
.target(new LatLng(lat,lon)) // Sets the new camera position
.zoom(16) // Sets the zoom
.bearing(180) // Rotate the camera
.tilt(30) // Set the camera tilt
.build(); // Creates a CameraPosition from the builder
map.animateCamera(CameraUpdateFactory
.newCameraPosition(position), 7000);
final Marker marker = map.addMarker(new MarkerOptions()
.position(new LatLng(lat,lon))
.title("You!")
.snippet("YOu are Currently here."));
marker.setIcon(icon);
Upvotes: 1
Views: 2146
Reputation: 3168
Here's an example which does just what your asking for except instead of a bus, it tracks the International Space Station in realtime. Computation of the heading is done using Turf and the Mapbox Android Services SDK but if you only need that single method, you can just copy the method from the library. Here's the important code from the example I mentioned above:
// Make sure you are using marker views so you can update the rotation.
marker.setRotation((float) computeHeading(marker.getPosition(), position));
...
public static double computeHeading(LatLng from, LatLng to) {
// Compute bearing/heading using Turf and return the value.
return TurfMeasurement.bearing(
Position.fromCoordinates(from.getLongitude(), from.getLatitude()),
Position.fromCoordinates(to.getLongitude(), to.getLatitude())
);
}
You can also use this method which I previously used before Turf:
// Returns the heading from one LatLng to another LatLng. Headings are. Expressed in degrees
// clockwise from North within the range [-180,180). The math for this method came from
// http://williams.best.vwh.net/avform.htm#Crs I only converted it to Java.
public static double computeHeading(LatLng from, LatLng to) {
double fromLat = Math.toRadians(from.getLatitude());
double fromLng = Math.toRadians(from.getLongitude());
double toLat = Math.toRadians(to.getLatitude());
double toLng = Math.toRadians(to.getLongitude());
double dLng = toLng - fromLng;
double heading = Math.atan2(Math.sin(dLng) * Math.cos(toLat),
Math.cos(fromLat) * Math.sin(toLat) - Math.sin(fromLat) * Math.cos(toLat) * Math.cos(dLng));
return (Math.toDegrees(heading) >= -180 && Math.toDegrees(heading) < 180) ?
Math.toDegrees(heading) : ((((Math.toDegrees(heading) + 180) % 360) + 360) % 360 + -180);
}
Upvotes: 4