package com.mapbox.services.android.navigation.v5.navigation.camera; import com.mapbox.api.directions.v5.models.DirectionsRoute; import com.mapbox.core.constants.Constants; import com.mapbox.geojson.LineString; import com.mapbox.geojson.Point; import com.mapbox.turf.TurfMeasurement; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * The default camera used by {@link com.mapbox.services.android.navigation.v5.navigation.MapboxNavigation}. * * @since 0.10.0 */ public class SimpleCamera extends Camera { protected static final int DEFAULT_TILT = 50; protected static final double DEFAULT_ZOOM = 15d; private List<Point> routeCoordinates = new ArrayList<>(); private double initialBearing; private DirectionsRoute initialRoute; @Override public double bearing(RouteInformation routeInformation) { if (routeInformation.route() != null) { setupLineStringAndBearing(routeInformation.route()); return initialBearing; } else if (routeInformation.location() != null) { return routeInformation.location().getBearing(); } return 0; } @Override public Point target(RouteInformation routeInformation) { double lng; double lat; Point targetPoint = null; if (routeInformation.route() != null) { setupLineStringAndBearing(routeInformation.route()); lng = routeCoordinates.get(0).longitude(); lat = routeCoordinates.get(0).latitude(); return Point.fromLngLat(lng, lat); } else if (routeInformation.location() != null) { lng = routeInformation.location().getLongitude(); lat = routeInformation.location().getLatitude(); targetPoint = Point.fromLngLat(lng, lat); } return targetPoint; } @Override public double tilt(RouteInformation routeInformation) { return DEFAULT_TILT; } @Override public double zoom(RouteInformation routeInformation) { return DEFAULT_ZOOM; } @Override public List<Point> overview(RouteInformation routeInformation) { boolean invalidCoordinates = routeCoordinates == null || routeCoordinates.isEmpty(); if (invalidCoordinates) { buildRouteCoordinatesFromRouteData(routeInformation); } return routeCoordinates; } private void buildRouteCoordinatesFromRouteData(RouteInformation routeInformation) { if (routeInformation.route() != null) { setupLineStringAndBearing(routeInformation.route()); } else if (routeInformation.routeProgress() != null) { setupLineStringAndBearing(routeInformation.routeProgress().directionsRoute()); } } private void setupLineStringAndBearing(DirectionsRoute route) { if (initialRoute != null && route.equals(initialRoute)) { return; //no need to recalculate these values } initialRoute = route; routeCoordinates = generateRouteCoordinates(route); initialBearing = TurfMeasurement.bearing( Point.fromLngLat(routeCoordinates.get(0).longitude(), routeCoordinates.get(0).latitude()), Point.fromLngLat(routeCoordinates.get(1).longitude(), routeCoordinates.get(1).latitude()) ); } private List<Point> generateRouteCoordinates(DirectionsRoute route) { if (route == null) { return Collections.emptyList(); } LineString lineString = LineString.fromPolyline(route.geometry(), Constants.PRECISION_6); return lineString.coordinates(); } }