package com.mapbox.services.android.navigation.ui.v5.camera; import android.location.Location; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.mapbox.api.directions.v5.DirectionsAdapterFactory; import com.mapbox.api.directions.v5.models.DirectionsResponse; 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.mapboxsdk.maps.MapboxMap; import com.mapbox.services.android.navigation.ui.v5.BaseTest; import com.mapbox.services.android.navigation.v5.navigation.camera.RouteInformation; import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress; import org.junit.Test; import java.io.IOException; import java.util.Collections; import java.util.List; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class DynamicCameraTest extends BaseTest { private static final String DIRECTIONS_PRECISION_6 = "directions_v5_precision_6.json"; @Test public void sanity() { DynamicCamera cameraEngine = buildDynamicCamera(); assertNotNull(cameraEngine); } @Test public void onInformationFromRoute_engineCreatesCorrectTarget() throws Exception { DynamicCamera cameraEngine = buildDynamicCamera(); RouteInformation routeInformation = RouteInformation.create(buildDirectionsRoute(), null, null); Point target = cameraEngine.target(routeInformation); double lng = target.longitude(); assertEquals(-122.416686, lng); double lat = target.latitude(); assertEquals(37.783425, lat); } @Test public void onInformationFromRoute_engineCreatesCorrectZoom() throws Exception { DynamicCamera cameraEngine = buildDynamicCamera(); RouteInformation routeInformation = RouteInformation.create(buildDirectionsRoute(), null, null); double zoom = cameraEngine.zoom(routeInformation); assertEquals(15d, zoom); } @Test public void onInformationFromRoute_engineCreatesCorrectTilt() throws Exception { DynamicCamera cameraEngine = buildDynamicCamera(); RouteInformation routeInformation = RouteInformation.create(buildDirectionsRoute(), null, null); double tilt = cameraEngine.tilt(routeInformation); assertEquals(50d, tilt); } @Test public void onInformationFromRoute_engineCreatesCorrectBearing() throws Exception { DynamicCamera cameraEngine = buildDynamicCamera(); RouteInformation routeInformation = RouteInformation.create(buildDirectionsRoute(), null, null); double bearing = cameraEngine.bearing(routeInformation); assertEquals(-99, Math.round(bearing)); } @Test public void onInformationFromLocationAndProgress_engineCreatesCorrectTarget() throws Exception { DynamicCamera cameraEngine = buildDynamicCamera(); RouteInformation routeInformation = RouteInformation.create(null, buildDefaultLocationUpdate(-77.0339782574523, 38.89993519985637), buildDefaultRouteProgress(null)); Point target = cameraEngine.target(routeInformation); double lng = target.longitude(); assertEquals(-77.0339782574523, lng); double lat = target.latitude(); assertEquals(38.89993519985637, lat); } @Test public void onHighDistanceRemaining_engineCreatesCorrectTilt() throws Exception { DynamicCamera cameraEngine = buildDynamicCamera(); RouteInformation routeInformation = RouteInformation.create(null, buildDefaultLocationUpdate(-77.0339782574523, 38.89993519985637), buildDefaultRouteProgress(1000d)); double tilt = cameraEngine.tilt(routeInformation); assertEquals(50d, tilt); } @Test public void onMediumDistanceRemaining_engineCreatesCorrectTilt() throws Exception { DynamicCamera cameraEngine = buildDynamicCamera(); RouteInformation routeInformation = RouteInformation.create(null, buildDefaultLocationUpdate(-77.0339782574523, 38.89993519985637), buildDefaultRouteProgress(200d)); double tilt = cameraEngine.tilt(routeInformation); assertEquals(40d, tilt); } @Test public void onLowDistanceRemaining_engineCreatesCorrectTilt() throws Exception { DynamicCamera cameraEngine = buildDynamicCamera(); RouteInformation routeInformation = RouteInformation.create(null, buildDefaultLocationUpdate(-77.0339782574523, 38.89993519985637), buildDefaultRouteProgress(null)); double tilt = cameraEngine.tilt(routeInformation); assertEquals(35d, tilt); } @Test public void onInformationFromLocationAndProgress_engineCreatesCorrectBearing() throws Exception { DynamicCamera cameraEngine = buildDynamicCamera(); RouteInformation routeInformation = RouteInformation.create(null, buildDefaultLocationUpdate(-77.0339782574523, 38.89993519985637), buildDefaultRouteProgress(null)); double bearing = cameraEngine.bearing(routeInformation); assertEquals(100f, bearing, DELTA); } @Test public void onInformationFromRoute_engineCreatesOverviewPointList() throws Exception { DynamicCamera cameraEngine = buildDynamicCamera(); DirectionsRoute route = buildDirectionsRoute(); List<Point> routePoints = generateRouteCoordinates(route); RouteInformation routeInformation = RouteInformation.create(route, null, null); List<Point> overviewPoints = cameraEngine.overview(routeInformation); assertEquals(routePoints, overviewPoints); } @Test public void onInformationFromRouteProgress_engineCreatesOverviewPointList() throws Exception { DynamicCamera cameraEngine = buildDynamicCamera(); RouteProgress routeProgress = buildDefaultRouteProgress(null); List<Point> routePoints = buildRouteCoordinatesFrom(routeProgress); RouteInformation routeInformation = RouteInformation.create(null, null, routeProgress); List<Point> overviewPoints = cameraEngine.overview(routeInformation); assertEquals(routePoints, overviewPoints); } @Test public void noRouteInformation_engineCreatesEmptyOverviewPointList() { DynamicCamera cameraEngine = buildDynamicCamera(); RouteInformation routeInformation = RouteInformation.create(null, null, null); List<Point> overviewPoints = cameraEngine.overview(routeInformation); assertTrue(overviewPoints.isEmpty()); } @Nullable private List<Point> buildRouteCoordinatesFrom(RouteProgress routeProgress) { DirectionsRoute route = routeProgress.directionsRoute(); return generateRouteCoordinates(route); } @NonNull private DynamicCamera buildDynamicCamera() { MapboxMap mapboxMap = mock(MapboxMap.class); return new DynamicCamera(mapboxMap); } private Location buildDefaultLocationUpdate(double lng, double lat) { return buildLocationUpdate(lng, lat, System.currentTimeMillis()); } private Location buildLocationUpdate(double lng, double lat, long time) { Location location = mock(Location.class); when(location.getLongitude()).thenReturn(lng); when(location.getLatitude()).thenReturn(lat); when(location.getSpeed()).thenReturn(30f); when(location.getBearing()).thenReturn(100f); when(location.getAccuracy()).thenReturn(10f); when(location.getTime()).thenReturn(time); return location; } private RouteProgress buildDefaultRouteProgress(@Nullable Double stepDistanceRemaining) throws Exception { DirectionsRoute aRoute = buildDirectionsRoute(); double stepDistanceRemainingFinal = stepDistanceRemaining == null ? 100 : stepDistanceRemaining; return buildRouteProgress(aRoute, stepDistanceRemainingFinal, 0, 0, 0, 0); } private DirectionsRoute buildDirectionsRoute() throws IOException { Gson gson = new GsonBuilder() .registerTypeAdapterFactory(DirectionsAdapterFactory.create()).create(); String body = loadJsonFixture(DIRECTIONS_PRECISION_6); DirectionsResponse response = gson.fromJson(body, DirectionsResponse.class); return response.routes().get(0); } private List<Point> generateRouteCoordinates(DirectionsRoute route) { if (route == null) { return Collections.emptyList(); } LineString lineString = LineString.fromPolyline(route.geometry(), Constants.PRECISION_6); return lineString.coordinates(); } }