diff --git a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.java b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.java index 5c988d710..9e3a79431 100644 --- a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.java +++ b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.java @@ -218,6 +218,7 @@ public void whenMapCameraInitializesTilted_iconsGetPlacedWithCorrectOffset() thr locationLayerPlugin.setRenderMode(RenderMode.NORMAL); locationLayerPlugin.forceLocationUpdate(location); SymbolLayer layer = mapboxMap.getLayerAs(FOREGROUND_LAYER); + uiController.loopMainThreadForAtLeast(200); Float[] value = layer.getIconOffset().getValue(); Assert.assertEquals((-0.05 * 60), value[1], 0.1); }); diff --git a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/traffic/TrafficPluginTest.java b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/traffic/TrafficPluginTest.java index 11fd20898..cad3e330c 100644 --- a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/traffic/TrafficPluginTest.java +++ b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/traffic/TrafficPluginTest.java @@ -9,8 +9,6 @@ import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.plugins.testapp.activity.TrafficActivity; -import com.mapbox.mapboxsdk.style.functions.CameraFunction; -import com.mapbox.mapboxsdk.style.functions.stops.ExponentialStops; import com.mapbox.mapboxsdk.style.layers.LineLayer; import com.mapbox.mapboxsdk.style.layers.Property; import com.mapbox.mapboxsdk.utils.OnMapReadyIdlingResource; @@ -822,11 +820,7 @@ public void lineWidthFunctionLocalBaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(Local.BASE_LAYER_ID); assertNotNull(layer.getLineWidth()); - assertNotNull(layer.getLineWidth().getFunction()); - assertEquals(CameraFunction.class, layer.getLineWidth().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineWidth().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).getBase(), 0.001); - assertEquals(2, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).size()); + assertNotNull(layer.getLineWidth().getExpression()); } }); } @@ -838,11 +832,7 @@ public void lineWidthFunctionLocalCaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(Local.CASE_LAYER_ID); assertNotNull(layer.getLineWidth()); - assertNotNull(layer.getLineWidth().getFunction()); - assertEquals(CameraFunction.class, layer.getLineWidth().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineWidth().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).getBase(), 0.001); - assertEquals(2, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).size()); + assertNotNull(layer.getLineWidth().getExpression()); } }); } @@ -855,11 +845,7 @@ public void lineWidthFunctionSecondaryBaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(Secondary.BASE_LAYER_ID); assertNotNull(layer.getLineWidth()); - assertNotNull(layer.getLineWidth().getFunction()); - assertEquals(CameraFunction.class, layer.getLineWidth().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineWidth().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).getBase(), 0.001); - assertEquals(3, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).size()); + assertNotNull(layer.getLineWidth().getExpression()); } }); } @@ -871,11 +857,7 @@ public void lineWidthFunctionSecondaryCaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(Secondary.CASE_LAYER_ID); assertNotNull(layer.getLineWidth()); - assertNotNull(layer.getLineWidth().getFunction()); - assertEquals(CameraFunction.class, layer.getLineWidth().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineWidth().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).getBase(), 0.001); - assertEquals(3, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).size()); + assertNotNull(layer.getLineWidth().getExpression()); } }); } @@ -887,11 +869,7 @@ public void lineWidthFunctionPrimaryBaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(Primary.BASE_LAYER_ID); assertNotNull(layer.getLineWidth()); - assertNotNull(layer.getLineWidth().getFunction()); - assertEquals(CameraFunction.class, layer.getLineWidth().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineWidth().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).getBase(), 0.001); - assertEquals(3, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).size()); + assertNotNull(layer.getLineWidth().getExpression()); } }); } @@ -903,11 +881,7 @@ public void lineWidthFunctionPrimaryCaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(Primary.CASE_LAYER_ID); assertNotNull(layer.getLineWidth()); - assertNotNull(layer.getLineWidth().getFunction()); - assertEquals(CameraFunction.class, layer.getLineWidth().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineWidth().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).getBase(), 0.001); - assertEquals(3, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).size()); + assertNotNull(layer.getLineWidth().getExpression()); } }); } @@ -919,11 +893,7 @@ public void lineWidthFunctionTrunkBaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(Trunk.BASE_LAYER_ID); assertNotNull(layer.getLineWidth()); - assertNotNull(layer.getLineWidth().getFunction()); - assertEquals(CameraFunction.class, layer.getLineWidth().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineWidth().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).getBase(), 0.001); - assertEquals(3, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).size()); + assertNotNull(layer.getLineWidth().getExpression()); } }); } @@ -935,11 +905,7 @@ public void lineWidthFunctionTrunkCaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(Trunk.CASE_LAYER_ID); assertNotNull(layer.getLineWidth()); - assertNotNull(layer.getLineWidth().getFunction()); - assertEquals(CameraFunction.class, layer.getLineWidth().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineWidth().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).getBase(), 0.001); - assertEquals(4, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).size()); + assertNotNull(layer.getLineWidth().getExpression()); } }); } @@ -951,11 +917,7 @@ public void lineWidthFunctionMotorwayBaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(MotorWay.BASE_LAYER_ID); assertNotNull(layer.getLineWidth()); - assertNotNull(layer.getLineWidth().getFunction()); - assertEquals(CameraFunction.class, layer.getLineWidth().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineWidth().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).getBase(), 0.001); - assertEquals(4, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).size()); + assertNotNull(layer.getLineWidth().getExpression()); } }); } @@ -967,11 +929,7 @@ public void lineWidthFunctionMotorwayCaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(MotorWay.CASE_LAYER_ID); assertNotNull(layer.getLineWidth()); - assertNotNull(layer.getLineWidth().getFunction()); - assertEquals(CameraFunction.class, layer.getLineWidth().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineWidth().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).getBase(), 0.001); - assertEquals(4, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).size()); + assertNotNull(layer.getLineWidth().getExpression()); } }); } @@ -983,11 +941,7 @@ public void lineOffsetFunctionLocalBaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(Local.BASE_LAYER_ID); assertNotNull(layer.getLineOffset()); - assertNotNull(layer.getLineOffset().getFunction()); - assertEquals(CameraFunction.class, layer.getLineOffset().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineOffset().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).getBase(), 0.001); - assertEquals(2, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).size()); + assertNotNull(layer.getLineOffset().getExpression()); } }); } @@ -999,11 +953,7 @@ public void lineOffsetFunctionLocalCaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(Local.CASE_LAYER_ID); assertNotNull(layer.getLineOffset()); - assertNotNull(layer.getLineOffset().getFunction()); - assertEquals(CameraFunction.class, layer.getLineOffset().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineOffset().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).getBase(), 0.001); - assertEquals(2, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).size()); + assertNotNull(layer.getLineOffset().getExpression()); } }); } @@ -1016,11 +966,7 @@ public void lineOffsetFunctionSecondaryBaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(Secondary.BASE_LAYER_ID); assertNotNull(layer.getLineOffset()); - assertNotNull(layer.getLineOffset().getFunction()); - assertEquals(CameraFunction.class, layer.getLineOffset().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineOffset().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).getBase(), 0.001); - assertEquals(4, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).size()); + assertNotNull(layer.getLineOffset().getExpression()); } }); } @@ -1032,11 +978,7 @@ public void lineOffsetFunctionSecondaryCaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(Secondary.CASE_LAYER_ID); assertNotNull(layer.getLineOffset()); - assertNotNull(layer.getLineOffset().getFunction()); - assertEquals(CameraFunction.class, layer.getLineOffset().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineOffset().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).getBase(), 0.001); - assertEquals(4, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).size()); + assertNotNull(layer.getLineOffset().getExpression()); } }); } @@ -1048,11 +990,7 @@ public void lineOffsetFunctionPrimaryBaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(Primary.BASE_LAYER_ID); assertNotNull(layer.getLineOffset()); - assertNotNull(layer.getLineOffset().getFunction()); - assertEquals(CameraFunction.class, layer.getLineOffset().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineOffset().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).getBase(), 0.001); - assertEquals(4, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).size()); + assertNotNull(layer.getLineOffset().getExpression()); } }); } @@ -1064,11 +1002,7 @@ public void lineOffsetFunctionPrimaryCaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(Primary.CASE_LAYER_ID); assertNotNull(layer.getLineOffset()); - assertNotNull(layer.getLineOffset().getFunction()); - assertEquals(CameraFunction.class, layer.getLineOffset().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineOffset().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).getBase(), 0.001); - assertEquals(4, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).size()); + assertNotNull(layer.getLineOffset().getExpression()); } }); } @@ -1080,11 +1014,7 @@ public void lineOffsetFunctionTrunkBaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(Trunk.BASE_LAYER_ID); assertNotNull(layer.getLineOffset()); - assertNotNull(layer.getLineOffset().getFunction()); - assertEquals(CameraFunction.class, layer.getLineOffset().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineOffset().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).getBase(), 0.001); - assertEquals(4, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).size()); + assertNotNull(layer.getLineOffset().getExpression()); } }); } @@ -1096,11 +1026,7 @@ public void lineOffsetFunctionTrunkCaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(Trunk.CASE_LAYER_ID); assertNotNull(layer.getLineOffset()); - assertNotNull(layer.getLineOffset().getFunction()); - assertEquals(CameraFunction.class, layer.getLineOffset().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineOffset().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).getBase(), 0.001); - assertEquals(4, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).size()); + assertNotNull(layer.getLineOffset().getExpression()); } }); } @@ -1112,11 +1038,7 @@ public void lineOffsetFunctionMotorwayBaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(MotorWay.BASE_LAYER_ID); assertNotNull(layer.getLineOffset()); - assertNotNull(layer.getLineOffset().getFunction()); - assertEquals(CameraFunction.class, layer.getLineOffset().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineOffset().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).getBase(), 0.001); - assertEquals(5, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).size()); + assertNotNull(layer.getLineOffset().getExpression()); } }); } @@ -1128,11 +1050,7 @@ public void lineOffsetFunctionMotorwayCaseLayer() throws Exception { public void onTrafficAction(TrafficPlugin trafficPlugin, MapboxMap mapboxMap, UiController controller) { LineLayer layer = mapboxMap.getLayerAs(MotorWay.CASE_LAYER_ID); assertNotNull(layer.getLineOffset()); - assertNotNull(layer.getLineOffset().getFunction()); - assertEquals(CameraFunction.class, layer.getLineOffset().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineOffset().getFunction().getStops().getClass()); - assertEquals(1.5f, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).getBase(), 0.001); - assertEquals(5, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).size()); + assertNotNull(layer.getLineOffset().getExpression()); } }); } diff --git a/app/src/androidTest/java/com/mapbox/mapboxsdk/utils/OnMapReadyIdlingResource.java b/app/src/androidTest/java/com/mapbox/mapboxsdk/utils/OnMapReadyIdlingResource.java index 31c699b4b..ff3ab5e4a 100644 --- a/app/src/androidTest/java/com/mapbox/mapboxsdk/utils/OnMapReadyIdlingResource.java +++ b/app/src/androidTest/java/com/mapbox/mapboxsdk/utils/OnMapReadyIdlingResource.java @@ -3,20 +3,25 @@ import android.app.Activity; import android.support.test.espresso.IdlingResource; -import timber.log.Timber; - +import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; import java.lang.reflect.Field; -public class OnMapReadyIdlingResource implements IdlingResource { +public class OnMapReadyIdlingResource implements IdlingResource, OnMapReadyCallback { - private final Activity activity; private MapboxMap mapboxMap; private IdlingResource.ResourceCallback resourceCallback; public OnMapReadyIdlingResource(Activity activity) { - this.activity = activity; + try { + Field field = activity.getClass().getDeclaredField("mapView"); + field.setAccessible(true); + ((MapView) field.get(activity)).getMapAsync(this); + } catch (Exception err) { + throw new RuntimeException(err); + } } @Override @@ -26,11 +31,7 @@ public String getName() { @Override public boolean isIdleNow() { - boolean idle = isMapboxMapReady(); - if (idle && resourceCallback != null) { - resourceCallback.onTransitionToIdle(); - } - return idle; + return mapboxMap != null; } @Override @@ -38,20 +39,15 @@ public void registerIdleTransitionCallback(ResourceCallback resourceCallback) { this.resourceCallback = resourceCallback; } - private boolean isMapboxMapReady() { - try { - Field field = activity.getClass().getDeclaredField("mapboxMap"); - field.setAccessible(true); - mapboxMap = (MapboxMap) field.get(activity); - Timber.e("isMapboxReady called with value " + (mapboxMap != null)); - return mapboxMap != null; - } catch (Exception exception) { - Timber.e("could not reflect", exception); - return false; - } - } - public MapboxMap getMapboxMap() { return mapboxMap; } + + @Override + public void onMapReady(MapboxMap mapboxMap) { + this.mapboxMap = mapboxMap; + if (resourceCallback != null) { + resourceCallback.onTransitionToIdle(); + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/BuildingActivity.java b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/BuildingActivity.java index 76a5f01a2..c081b2084 100644 --- a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/BuildingActivity.java +++ b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/BuildingActivity.java @@ -117,7 +117,6 @@ public boolean onOptionsItemSelected(MenuItem item) { return super.onOptionsItemSelected(item); } - switch (item.getItemId()) { case R.id.menu_building_min_zoom: buildingPlugin.setMinZoomLevel(14); diff --git a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java index 7f4f7b2f9..1dec7753e 100644 --- a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java +++ b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java @@ -1,6 +1,7 @@ package com.mapbox.mapboxsdk.plugins.testapp.activity.location; import android.annotation.SuppressLint; +import android.content.res.Configuration; import android.location.Location; import android.os.Bundle; import android.support.annotation.VisibleForTesting; @@ -57,6 +58,15 @@ public class LocationLayerModesActivity extends AppCompatActivity implements OnM private MapboxMap mapboxMap; private boolean customStyle; + private static final String SAVED_STATE_CAMERA = "saved_state_camera"; + private static final String SAVED_STATE_RENDER = "saved_state_render"; + + @CameraMode.Mode + private int cameraMode = CameraMode.NONE; + + @RenderMode.Mode + private int renderMode = RenderMode.NORMAL; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -65,6 +75,11 @@ protected void onCreate(Bundle savedInstanceState) { mapView.onCreate(savedInstanceState); mapView.getMapAsync(this); + + if (savedInstanceState != null) { + cameraMode = savedInstanceState.getInt(SAVED_STATE_CAMERA); + renderMode = savedInstanceState.getInt(SAVED_STATE_RENDER); + } } @SuppressWarnings( {"MissingPermission"}) @@ -88,16 +103,28 @@ public void locationModeCompass(View view) { @Override public void onMapReady(MapboxMap mapboxMap) { this.mapboxMap = mapboxMap; + locationEngine = new LocationEngineProvider(this).obtainBestLocationEngineAvailable(); locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY); + locationEngine.setFastestInterval(1000); locationEngine.addLocationEngineListener(this); locationEngine.activate(); + + int[] padding; + if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { + padding = new int[] {0, 750, 0, 0}; + } else { + padding = new int[] {0, 250, 0, 0}; + } LocationLayerOptions options = LocationLayerOptions.builder(this) - .padding(new int[] {0, 650, 0, 0}) + .padding(padding) .build(); locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMap, locationEngine, options); locationLayerPlugin.addOnLocationClickListener(this); locationLayerPlugin.addOnCameraTrackingChangedListener(this); + locationLayerPlugin.setCameraMode(cameraMode); + setRendererMode(renderMode); + getLifecycle().addObserver(locationLayerPlugin); } @@ -177,6 +204,8 @@ protected void onStop() { protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); + outState.putInt(SAVED_STATE_CAMERA, cameraMode); + outState.putInt(SAVED_STATE_RENDER, renderMode); } @Override @@ -226,17 +255,29 @@ private void showModeListDialog() { String selectedMode = modes.get(position); locationModeBtn.setText(selectedMode); if (selectedMode.contentEquals("Normal")) { - locationLayerPlugin.setRenderMode(RenderMode.NORMAL); + setRendererMode(RenderMode.NORMAL); } else if (selectedMode.contentEquals("Compass")) { - locationLayerPlugin.setRenderMode(RenderMode.COMPASS); + setRendererMode(RenderMode.COMPASS); } else if (selectedMode.contentEquals("GPS")) { - locationLayerPlugin.setRenderMode(RenderMode.GPS); + setRendererMode(RenderMode.GPS); } listPopup.dismiss(); }); listPopup.show(); } + private void setRendererMode(@RenderMode.Mode int mode) { + renderMode = mode; + locationLayerPlugin.setRenderMode(mode); + if (mode == RenderMode.NORMAL) { + locationModeBtn.setText("Normal"); + } else if (mode == RenderMode.COMPASS) { + locationModeBtn.setText("Compass"); + } else if (mode == RenderMode.GPS) { + locationModeBtn.setText("Gps"); + } + } + private void showTrackingListDialog() { List trackingTypes = new ArrayList<>(); trackingTypes.add("None"); @@ -275,6 +316,18 @@ public void onCameraTrackingDismissed() { @Override public void onCameraTrackingChanged(int currentMode) { - // do nothing + this.cameraMode = currentMode; + + if (cameraMode == CameraMode.NONE) { + locationTrackingBtn.setText("None"); + } else if (cameraMode == CameraMode.TRACKING) { + locationTrackingBtn.setText("Tracking"); + } else if (cameraMode == CameraMode.TRACKING_COMPASS) { + locationTrackingBtn.setText("Tracking Compass"); + } else if (cameraMode == CameraMode.TRACKING_GPS) { + locationTrackingBtn.setText("Tracking GPS"); + } else if (cameraMode == CameraMode.TRACKING_GPS_NORTH) { + locationTrackingBtn.setText("Tracking GPS North"); + } } } \ No newline at end of file diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index ab3e77bbf..e3199d76c 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -8,7 +8,7 @@ ext { ] version = [ - mapboxMapSdk : '6.0.0-beta.3', + mapboxMapSdk : '6.0.0-beta.5', mapboxGeocoding : '3.0.0-beta.3', mapboxGeoJson : '3.0.0-beta.3', mapboxServices : '2.2.10', diff --git a/plugin-building/src/main/java/com/mapbox/mapboxsdk/plugins/building/BuildingPlugin.java b/plugin-building/src/main/java/com/mapbox/mapboxsdk/plugins/building/BuildingPlugin.java index c0dfd11ae..89dfad003 100644 --- a/plugin-building/src/main/java/com/mapbox/mapboxsdk/plugins/building/BuildingPlugin.java +++ b/plugin-building/src/main/java/com/mapbox/mapboxsdk/plugins/building/BuildingPlugin.java @@ -8,14 +8,17 @@ import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.style.functions.Function; import com.mapbox.mapboxsdk.style.layers.FillExtrusionLayer; import com.mapbox.mapboxsdk.style.light.Light; import static com.mapbox.mapboxsdk.constants.MapboxConstants.MAXIMUM_ZOOM; import static com.mapbox.mapboxsdk.constants.MapboxConstants.MINIMUM_ZOOM; -import static com.mapbox.mapboxsdk.style.functions.stops.Stop.stop; -import static com.mapbox.mapboxsdk.style.functions.stops.Stops.exponential; +import static com.mapbox.mapboxsdk.style.expressions.Expression.exponential; +import static com.mapbox.mapboxsdk.style.expressions.Expression.get; +import static com.mapbox.mapboxsdk.style.expressions.Expression.interpolate; +import static com.mapbox.mapboxsdk.style.expressions.Expression.literal; +import static com.mapbox.mapboxsdk.style.expressions.Expression.stop; +import static com.mapbox.mapboxsdk.style.expressions.Expression.zoom; import static com.mapbox.mapboxsdk.style.layers.Property.NONE; import static com.mapbox.mapboxsdk.style.layers.Property.VISIBLE; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionColor; @@ -93,13 +96,14 @@ private void initLayer(String belowLayer) { fillExtrusionLayer.setProperties( visibility(visible ? VISIBLE : NONE), fillExtrusionColor(color), - fillExtrusionHeight(Function.composite( - "height", - exponential( - stop(15f, 0f, fillExtrusionHeight(0f)), - stop(16f, 0f, fillExtrusionHeight(0f)), - stop(16f, 1000f, fillExtrusionHeight(1000f)) - ))), + fillExtrusionHeight( + interpolate( + exponential(1f), + zoom(), + stop(15, literal(0)), + stop(16, get("height")) + ) + ), fillExtrusionOpacity(opacity) ); addLayer(fillExtrusionLayer, belowLayer); diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java index 8cdf952c7..e82f0a22e 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java @@ -42,9 +42,10 @@ import static com.mapbox.mapboxsdk.plugins.locationlayer.Utils.generateShadow; import static com.mapbox.mapboxsdk.plugins.locationlayer.Utils.getBitmapFromDrawable; import static com.mapbox.mapboxsdk.plugins.locationlayer.Utils.getDrawable; -import static com.mapbox.mapboxsdk.style.functions.Function.zoom; -import static com.mapbox.mapboxsdk.style.functions.stops.Stop.stop; -import static com.mapbox.mapboxsdk.style.functions.stops.Stops.exponential; +import static com.mapbox.mapboxsdk.style.expressions.Expression.exponential; +import static com.mapbox.mapboxsdk.style.expressions.Expression.interpolate; +import static com.mapbox.mapboxsdk.style.expressions.Expression.stop; +import static com.mapbox.mapboxsdk.style.expressions.Expression.zoom; import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_MAP; import static com.mapbox.mapboxsdk.style.layers.Property.NONE; import static com.mapbox.mapboxsdk.style.layers.Property.VISIBLE; @@ -62,7 +63,7 @@ import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconSize; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility; -final class LocationLayer implements LocationLayerAnimator.OnAnimationsValuesChangeListener { +final class LocationLayer implements LocationLayerAnimator.OnLayerAnimationsValuesChangeListener { @RenderMode.Mode private int renderMode; @@ -164,14 +165,14 @@ private void addSymbolLayer(String layerId, String beforeLayerId) { layer.setProperties( iconAllowOverlap(true), iconIgnorePlacement(true), - iconSize(zoom( - exponential( - stop(22f, iconSize(1f)), - stop(12f, iconSize(1f)), - stop(10f, iconSize(0.6f)), - stop(0f, iconSize(0.6f)) - ).withBase(1f) - )), + iconSize( + interpolate(exponential(1f), zoom(), + stop(22f, 1f), + stop(12f, 1f), + stop(10f, 0.6f), + stop(0f, 0.6f) + ) + ), iconRotationAlignment(ICON_ROTATION_ALIGNMENT_MAP)); addLayerToMap(layer, beforeLayerId); } @@ -301,7 +302,9 @@ void setLocationsStale(boolean isStale) { this.isStale = isStale; layerMap.get(FOREGROUND_LAYER).setProperties(iconImage(isStale ? FOREGROUND_STALE_ICON : FOREGROUND_ICON)); layerMap.get(BACKGROUND_LAYER).setProperties(iconImage(isStale ? BACKGROUND_STALE_ICON : BACKGROUND_ICON)); - layerMap.get(ACCURACY_LAYER).setProperties(visibility(isStale && renderMode != RenderMode.GPS ? NONE : VISIBLE)); + if (renderMode != RenderMode.GPS) { + layerMap.get(ACCURACY_LAYER).setProperties(visibility(isStale ? NONE : VISIBLE)); + } } // diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java index 5c7859d00..25bc6f38c 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java @@ -1,9 +1,14 @@ package com.mapbox.mapboxsdk.plugins.locationlayer; +import android.animation.Animator; +import android.animation.AnimatorSet; import android.animation.ValueAnimator; import android.location.Location; +import android.os.SystemClock; import android.support.annotation.NonNull; +import android.view.animation.LinearInterpolator; +import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.plugins.locationlayer.camera.BearingAnimator; import com.mapbox.mapboxsdk.plugins.locationlayer.camera.LatLngAnimator; @@ -11,89 +16,141 @@ import java.util.ArrayList; import java.util.List; +import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.COMPASS_UPDATE_RATE_MS; + final class LocationLayerAnimator { - private final List listeners = new ArrayList<>(); - private LatLngAnimator latLngAnimator; - private BearingAnimator gpsBearingAnimator; - private BearingAnimator compassBearingAnimator; + private final List layerListeners = new ArrayList<>(); + private final List cameraListeners = new ArrayList<>(); + + private LatLngAnimator layerLatLngAnimator; + private BearingAnimator layerGpsBearingAnimator; + private BearingAnimator layerCompassBearingAnimator; + + private LatLngAnimator cameraLatLngAnimator; + private BearingAnimator cameraGpsBearingAnimator; + private BearingAnimator cameraCompassBearingAnimator; + + private Location previousLocation; + private float previousCompassBearing = -1; + private long locationUpdateTimestamp; - void addListener(OnAnimationsValuesChangeListener listener) { - listeners.add(listener); + void addLayerListener(OnLayerAnimationsValuesChangeListener listener) { + layerListeners.add(listener); } - void removeListener(OnAnimationsValuesChangeListener listener) { - listeners.remove(listener); + void removeLayerListener(OnLayerAnimationsValuesChangeListener listener) { + layerListeners.remove(listener); } - void feedNewLocation(@NonNull Location previousLocation, @NonNull Location newLocation) { - LatLng previousLatLng; - if (latLngAnimator != null) { - previousLatLng = (LatLng) latLngAnimator.getAnimatedValue(); - } else { - previousLatLng = new LatLng(previousLocation); - } - LatLng newLatLng = new LatLng(newLocation); + void addCameraListener(OnCameraAnimationsValuesChangeListener listener) { + cameraListeners.add(listener); + } - float previousBearing; - if (gpsBearingAnimator != null) { - previousBearing = (float) gpsBearingAnimator.getAnimatedValue(); - } else { - previousBearing = previousLocation.getBearing(); + void removeCameraListener(OnCameraAnimationsValuesChangeListener listener) { + cameraListeners.remove(listener); + } + + void feedNewLocation(@NonNull Location newLocation, @NonNull CameraPosition currentCameraPosition, + boolean isGpsNorth) { + if (previousLocation == null) { + previousLocation = newLocation; + locationUpdateTimestamp = SystemClock.elapsedRealtime(); } - cancelLocationAnimations(); - latLngAnimator = new LatLngAnimator(previousLatLng, newLatLng, 1000); - gpsBearingAnimator = new BearingAnimator(previousBearing, newLocation.getBearing(), 1000); - // FIXME: 22/02/2018 evaluate duration of animation better + LatLng previousLayerLatLng = getPreviousLayerLatLng(); + float previousLayerBearing = getPreviousLayerGpsBearing(); + LatLng previousCameraLatLng = currentCameraPosition.target; + float previousCameraBearing = (float) currentCameraPosition.bearing; + + LatLng targetLatLng = new LatLng(newLocation); + float targetLayerBearing = newLocation.getBearing(); + float targetCameraBearing = newLocation.getBearing(); + targetCameraBearing = checkGpsNorth(isGpsNorth, targetCameraBearing); - latLngAnimator.addUpdateListener(latLngUpdateListener); - gpsBearingAnimator.addUpdateListener(gpsBearingUpdateListener); + updateLayerAnimators(previousLayerLatLng, targetLatLng, previousLayerBearing, targetLayerBearing); + updateCameraAnimators(previousCameraLatLng, previousCameraBearing, targetLatLng, targetCameraBearing); - latLngAnimator.start(); - gpsBearingAnimator.start(); + playAllLocationAnimators(getAnimationDuration()); + + previousLocation = newLocation; } - void feedNewCompassBearing(float previousCompassBearing, float targetCompassBearing) { - cancelCompassAnimations(); - compassBearingAnimator = new BearingAnimator(previousCompassBearing, targetCompassBearing, 1000); - // FIXME: 22/02/2018 evaluate duration of animation better + void feedNewCompassBearing(float targetCompassBearing, @NonNull CameraPosition currentCameraPosition) { + if (previousCompassBearing < 0) { + previousCompassBearing = targetCompassBearing; + } + + float previousLayerBearing = getPreviousLayerCompassBearing(); + float previousCameraBearing = (float) currentCameraPosition.bearing; + + updateCompassAnimators(targetCompassBearing, previousLayerBearing, previousCameraBearing); + playCompassAnimators(COMPASS_UPDATE_RATE_MS); - compassBearingAnimator.addUpdateListener(compassBearingUpdateListener); - compassBearingAnimator.start(); + previousCompassBearing = targetCompassBearing; } - private final ValueAnimator.AnimatorUpdateListener latLngUpdateListener = + private final ValueAnimator.AnimatorUpdateListener layerLatLngUpdateListener = new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { - for (OnAnimationsValuesChangeListener listener : listeners) { + for (OnLayerAnimationsValuesChangeListener listener : layerListeners) { listener.onNewLatLngValue((LatLng) valueAnimator.getAnimatedValue()); } } }; - private final ValueAnimator.AnimatorUpdateListener compassBearingUpdateListener = + private final ValueAnimator.AnimatorUpdateListener layerCompassBearingUpdateListener = new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { - for (OnAnimationsValuesChangeListener listener : listeners) { + for (OnLayerAnimationsValuesChangeListener listener : layerListeners) { listener.onNewCompassBearingValue((Float) valueAnimator.getAnimatedValue()); } } }; - private final ValueAnimator.AnimatorUpdateListener gpsBearingUpdateListener = + private final ValueAnimator.AnimatorUpdateListener layerGpsBearingUpdateListener = new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { - for (OnAnimationsValuesChangeListener listener : listeners) { + for (OnLayerAnimationsValuesChangeListener listener : layerListeners) { listener.onNewGpsBearingValue((Float) valueAnimator.getAnimatedValue()); } } }; - interface OnAnimationsValuesChangeListener { + private final ValueAnimator.AnimatorUpdateListener cameraLatLngUpdateListener = + new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + for (OnCameraAnimationsValuesChangeListener listener : cameraListeners) { + listener.onNewLatLngValue((LatLng) valueAnimator.getAnimatedValue()); + } + } + }; + + private final ValueAnimator.AnimatorUpdateListener cameraCompassBearingUpdateListener = + new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + for (OnCameraAnimationsValuesChangeListener listener : cameraListeners) { + listener.onNewCompassBearingValue((Float) valueAnimator.getAnimatedValue()); + } + } + }; + + private final ValueAnimator.AnimatorUpdateListener cameraGpsBearingUpdateListener = + new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + for (OnCameraAnimationsValuesChangeListener listener : cameraListeners) { + listener.onNewGpsBearingValue((Float) valueAnimator.getAnimatedValue()); + } + } + }; + + interface OnLayerAnimationsValuesChangeListener { void onNewLatLngValue(LatLng latLng); void onNewGpsBearingValue(float gpsBearing); @@ -101,27 +158,239 @@ interface OnAnimationsValuesChangeListener { void onNewCompassBearingValue(float compassBearing); } + interface OnCameraAnimationsValuesChangeListener { + void onNewLatLngValue(LatLng latLng); + + void onNewGpsBearingValue(float gpsBearing); + + void onNewCompassBearingValue(float compassBearing); + } + + void resetAllCameraAnimations(CameraPosition currentCameraPosition, boolean isGpsNorth) { + resetCameraCompassAnimation(currentCameraPosition); + resetCameraLocationAnimations(currentCameraPosition, isGpsNorth); + playCameraAnimators(); + } + void cancelAllAnimations() { - cancelLocationAnimations(); - cancelCompassAnimations(); + cancelLayerLocationAnimations(); + cancelLayerCompassAnimations(); + cancelCameraLocationAnimations(); + cancelCameraCompassAnimations(); } - private void cancelLocationAnimations() { - if (latLngAnimator != null) { - latLngAnimator.cancel(); - latLngAnimator.removeAllUpdateListeners(); + private LatLng getPreviousLayerLatLng() { + LatLng previousLatLng; + if (layerLatLngAnimator != null) { + previousLatLng = (LatLng) layerLatLngAnimator.getAnimatedValue(); + } else { + previousLatLng = new LatLng(previousLocation); } + return previousLatLng; + } + + private float getPreviousLayerGpsBearing() { + float previousBearing; + if (layerGpsBearingAnimator != null) { + previousBearing = (float) layerGpsBearingAnimator.getAnimatedValue(); + } else { + previousBearing = previousLocation.getBearing(); + } + return previousBearing; + } + + private float getPreviousLayerCompassBearing() { + float previousBearing; + if (layerCompassBearingAnimator != null) { + previousBearing = (float) layerCompassBearingAnimator.getAnimatedValue(); + } else { + previousBearing = previousCompassBearing; + } + return previousBearing; + } + + private void updateLayerAnimators(LatLng previousLatLng, LatLng targetLatLng, + float previousBearing, float targetBearing) { + cancelLayerLocationAnimations(); + layerLatLngAnimator = new LatLngAnimator(previousLatLng, targetLatLng, 1000); + float normalizedLayerBearing = Utils.shortestRotation(targetBearing, previousBearing); + layerGpsBearingAnimator = new BearingAnimator(previousBearing, normalizedLayerBearing, 1000); + + layerLatLngAnimator.addUpdateListener(layerLatLngUpdateListener); + layerGpsBearingAnimator.addUpdateListener(layerGpsBearingUpdateListener); + } + + private void updateCameraAnimators(LatLng previousCameraLatLng, float previousCameraBearing, + LatLng targetLatLng, float targetBearing) { + cancelCameraLocationAnimations(); + cameraLatLngAnimator = new LatLngAnimator(previousCameraLatLng, targetLatLng, 1000); + cameraLatLngAnimator.addUpdateListener(cameraLatLngUpdateListener); + + float normalizedCameraBearing = Utils.shortestRotation(targetBearing, previousCameraBearing); + cameraGpsBearingAnimator = new BearingAnimator(previousCameraBearing, normalizedCameraBearing, 1000); + cameraGpsBearingAnimator.addUpdateListener(cameraGpsBearingUpdateListener); + } + + private long getAnimationDuration() { + float previousUpdateTimeStamp = locationUpdateTimestamp; + locationUpdateTimestamp = SystemClock.elapsedRealtime(); + + int animationDuration; + if (previousUpdateTimeStamp == 0) { + animationDuration = 0; + } else { + animationDuration = (int) ((locationUpdateTimestamp - previousUpdateTimeStamp) * 1.1f) + /*make animation slightly longer*/; + } + return animationDuration; + } + + private float checkGpsNorth(boolean isGpsNorth, float targetCameraBearing) { + if (isGpsNorth) { + targetCameraBearing = 0; + } + return targetCameraBearing; + } + + private void playAllLocationAnimators(long duration) { + List locationAnimators = new ArrayList<>(); + locationAnimators.add(layerLatLngAnimator); + locationAnimators.add(layerGpsBearingAnimator); + locationAnimators.add(cameraLatLngAnimator); + locationAnimators.add(cameraGpsBearingAnimator); + AnimatorSet locationAnimatorSet = new AnimatorSet(); + locationAnimatorSet.playTogether(locationAnimators); + locationAnimatorSet.setInterpolator(new LinearInterpolator()); + locationAnimatorSet.setDuration(duration); + locationAnimatorSet.start(); + } + + private void playCameraAnimators() { + List locationAnimators = new ArrayList<>(); + locationAnimators.add(cameraLatLngAnimator); + locationAnimators.add(cameraGpsBearingAnimator); + AnimatorSet locationAnimatorSet = new AnimatorSet(); + locationAnimatorSet.playTogether(locationAnimators); + locationAnimatorSet.setInterpolator(new LinearInterpolator()); + locationAnimatorSet.start(); + } + + private void updateCompassAnimators(float targetCompassBearing, float previousLayerBearing, + float previousCameraBearing) { + cancelLayerCompassAnimations(); + float normalizedLayerBearing = Utils.shortestRotation(targetCompassBearing, previousLayerBearing); + layerCompassBearingAnimator = new BearingAnimator(previousLayerBearing, normalizedLayerBearing, 1000); + layerCompassBearingAnimator.addUpdateListener(layerCompassBearingUpdateListener); + + cancelCameraCompassAnimations(); + float normalizedCameraBearing = Utils.shortestRotation(targetCompassBearing, previousCameraBearing); + cameraCompassBearingAnimator = new BearingAnimator(previousCameraBearing, normalizedCameraBearing, 1000); + cameraCompassBearingAnimator.addUpdateListener(cameraCompassBearingUpdateListener); + } + + private void playCompassAnimators(long duration) { + List compassAnimators = new ArrayList<>(); + compassAnimators.add(layerCompassBearingAnimator); + compassAnimators.add(cameraCompassBearingAnimator); + AnimatorSet compassAnimatorSet = new AnimatorSet(); + compassAnimatorSet.playTogether(compassAnimators); + compassAnimatorSet.setDuration(duration); + compassAnimatorSet.start(); + } + + private void cancelLayerLocationAnimations() { + cancelLayerLatLngAnimations(); + cancelLayerGpsBearingAnimations(); + } + + private void cancelLayerLatLngAnimations() { + if (layerLatLngAnimator != null) { + layerLatLngAnimator.cancel(); + layerLatLngAnimator.removeAllUpdateListeners(); + } + } + + private void cancelLayerGpsBearingAnimations() { + if (layerGpsBearingAnimator != null) { + layerGpsBearingAnimator.cancel(); + layerGpsBearingAnimator.removeAllUpdateListeners(); + } + } + + private void cancelLayerCompassAnimations() { + if (layerCompassBearingAnimator != null) { + layerCompassBearingAnimator.cancel(); + layerCompassBearingAnimator.removeAllUpdateListeners(); + } + } + + private void cancelCameraLocationAnimations() { + cancelCameraLatLngAnimations(); + cancelCameraGpsBearingAnimations(); + } + + private void resetCameraLocationAnimations(CameraPosition currentCameraPosition, boolean isGpsNorth) { + resetCameraLatLngAnimation(currentCameraPosition); + resetCameraGpsBearingAnimation(currentCameraPosition, isGpsNorth); + } + + private void cancelCameraLatLngAnimations() { + if (cameraLatLngAnimator != null) { + cameraLatLngAnimator.cancel(); + cameraLatLngAnimator.removeAllUpdateListeners(); + } + } + + private void resetCameraLatLngAnimation(CameraPosition currentCameraPosition) { + if (cameraLatLngAnimator == null) { + return; + } + long duration = cameraLatLngAnimator.getDuration(); + cancelCameraLatLngAnimations(); + LatLng currentTarget = cameraLatLngAnimator.getTarget(); + LatLng previousCameraTarget = currentCameraPosition.target; + cameraLatLngAnimator = new LatLngAnimator(previousCameraTarget, currentTarget, duration); + cameraLatLngAnimator.addUpdateListener(cameraLatLngUpdateListener); + } + + private void cancelCameraGpsBearingAnimations() { + if (cameraGpsBearingAnimator != null) { + cameraGpsBearingAnimator.cancel(); + cameraGpsBearingAnimator.removeAllUpdateListeners(); + } + } + + private void resetCameraGpsBearingAnimation(CameraPosition currentCameraPosition, boolean isGpsNorth) { + if (cameraGpsBearingAnimator == null) { + return; + } + long duration = cameraLatLngAnimator.getDuration(); + cancelCameraGpsBearingAnimations(); + float currentTargetBearing = cameraGpsBearingAnimator.getTargetBearing(); + currentTargetBearing = checkGpsNorth(isGpsNorth, currentTargetBearing); + float previousCameraBearing = (float) currentCameraPosition.bearing; + float normalizedCameraBearing = Utils.shortestRotation(currentTargetBearing, previousCameraBearing); + cameraGpsBearingAnimator = new BearingAnimator(previousCameraBearing, normalizedCameraBearing, duration); + cameraGpsBearingAnimator.addUpdateListener(cameraGpsBearingUpdateListener); + } - if (gpsBearingAnimator != null) { - gpsBearingAnimator.cancel(); - gpsBearingAnimator.removeAllUpdateListeners(); + private void cancelCameraCompassAnimations() { + if (cameraCompassBearingAnimator != null) { + cameraCompassBearingAnimator.cancel(); + cameraCompassBearingAnimator.removeAllUpdateListeners(); } } - private void cancelCompassAnimations() { - if (compassBearingAnimator != null) { - compassBearingAnimator.cancel(); - compassBearingAnimator.removeAllUpdateListeners(); + private void resetCameraCompassAnimation(CameraPosition currentCameraPosition) { + if (cameraCompassBearingAnimator == null || cameraLatLngAnimator == null) { + return; } + long duration = cameraLatLngAnimator.getDuration(); + cancelCameraCompassAnimations(); + float currentTargetBearing = cameraCompassBearingAnimator.getTargetBearing(); + float previousCameraBearing = (float) currentCameraPosition.bearing; + float normalizedCameraBearing = Utils.shortestRotation(currentTargetBearing, previousCameraBearing); + cameraCompassBearingAnimator = new BearingAnimator(previousCameraBearing, normalizedCameraBearing, duration); + cameraCompassBearingAnimator.addUpdateListener(cameraCompassBearingUpdateListener); } } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java index 46ee59b2a..3af147b53 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java @@ -9,7 +9,7 @@ import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.plugins.locationlayer.modes.CameraMode; -final class LocationLayerCamera implements LocationLayerAnimator.OnAnimationsValuesChangeListener { +final class LocationLayerCamera implements LocationLayerAnimator.OnCameraAnimationsValuesChangeListener { @CameraMode.Mode private int cameraMode; @@ -39,8 +39,8 @@ void initializeOptions(LocationLayerOptions options) { } void setCameraMode(@CameraMode.Mode int cameraMode) { + final boolean wasTracking = isLocationTracking(); this.cameraMode = cameraMode; - boolean wasTracking = isLocationTracking(); mapboxMap.cancelTransitions(); adjustGesturesThresholds(); notifyCameraTrackingChangeListener(wasTracking); @@ -76,14 +76,14 @@ public void onNewLatLngValue(LatLng latLng) { @Override public void onNewGpsBearingValue(float gpsBearing) { + boolean trackingNorth = cameraMode == CameraMode.TRACKING_GPS_NORTH + && mapboxMap.getCameraPosition().bearing != 0; + if (cameraMode == CameraMode.TRACKING_GPS - || cameraMode == CameraMode.NONE_GPS) { + || cameraMode == CameraMode.NONE_GPS + || trackingNorth) { setBearing(gpsBearing); } - - if (cameraMode == CameraMode.TRACKING_GPS_NORTH) { - setBearing(0); - } } @Override @@ -120,7 +120,7 @@ private void notifyCameraTrackingChangeListener(boolean wasTracking) { internalCameraTrackingChangedListener.onCameraTrackingChanged(cameraMode); if (wasTracking && !isLocationTracking()) { mapboxMap.getUiSettings().setFocalPoint(null); - moveGestureDetector.setMoveThreshold(moveGestureDetector.getDefaultMoveThreshold()); + moveGestureDetector.setMoveThreshold(0f); internalCameraTrackingChangedListener.onCameraTrackingDismissed(); } } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerConstants.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerConstants.java index 2eb515d7d..840a0c92b 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerConstants.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerConstants.java @@ -15,7 +15,7 @@ final class LocationLayerConstants { static final int LOCATION_UPDATE_DELAY_MS = 500; // Sets the max allowed time for the location icon animation from one latlng to another. - static final long MAX_ANIMATION_DURATION_MS = 1500; + static final long MIN_ANIMATION_DURATION_MS = 1500; // Sources static final String LOCATION_SOURCE = "mapbox-location-source"; diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerOptions.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerOptions.java index e6f6b302d..8fd689c05 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerOptions.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerOptions.java @@ -45,7 +45,7 @@ public abstract class LocationLayerOptions implements Parcelable { /** * Default max map zoom */ - private static final float MAX_ZOOM_DEFAULT = 20; + private static final float MAX_ZOOM_DEFAULT = 18; /** * Default min map zoom diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java index ab24fba35..52f956cb6 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java @@ -64,7 +64,6 @@ public final class LocationLayerPlugin implements LifecycleObserver { private LocationLayerCamera locationLayerCamera; private LocationLayerAnimator locationLayerAnimator; - private Location lastLocation; private boolean isEnabled; private StaleStateManager staleStateManager; @@ -134,7 +133,6 @@ public LocationLayerPlugin(@NonNull MapView mapView, @NonNull MapboxMap mapboxMa * @since 0.5.0 */ @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION}) - public void setLocationLayerEnabled(boolean isEnabled) { if (isEnabled) { enableLocationLayerPlugin(); @@ -160,6 +158,8 @@ public void setLocationLayerEnabled(boolean isEnabled) { * @since 0.5.0 */ public void setCameraMode(@CameraMode.Mode int cameraMode) { + boolean isGpsNorth = cameraMode == CameraMode.TRACKING_GPS_NORTH; + locationLayerAnimator.resetAllCameraAnimations(mapboxMap.getCameraPosition(), isGpsNorth); locationLayerCamera.setCameraMode(cameraMode); } @@ -502,8 +502,8 @@ private void initialize() { locationLayer = new LocationLayer(mapView, mapboxMap, options); locationLayerCamera = new LocationLayerCamera(mapboxMap, cameraTrackingChangedListener, options); locationLayerAnimator = new LocationLayerAnimator(); - locationLayerAnimator.addListener(locationLayer); - locationLayerAnimator.addListener(locationLayerCamera); + locationLayerAnimator.addLayerListener(locationLayer); + locationLayerAnimator.addCameraListener(locationLayerCamera); compassManager = new CompassManager(mapView.getContext()); compassManager.addCompassListener(compassListener); @@ -548,17 +548,14 @@ private void updateLocation(final Location location) { if (location == null) { return; } - staleStateManager.updateLatestLocationTime(); - if (lastLocation != null) { - locationLayerAnimator.feedNewLocation(lastLocation, location); - } - - lastLocation = location; + CameraPosition currentCameraPosition = mapboxMap.getCameraPosition(); + boolean isGpsNorth = getCameraMode() == CameraMode.TRACKING_GPS_NORTH; + locationLayerAnimator.feedNewLocation(location, currentCameraPosition, isGpsNorth); } private void updateCompassHeading(float heading) { - locationLayerAnimator.feedNewCompassBearing(compassManager.getLastHeading(), heading); + locationLayerAnimator.feedNewCompassBearing(heading, mapboxMap.getCameraPosition()); } /** @@ -649,9 +646,7 @@ public void onCompassAccuracyChange(int compassStatus) { @Override @SuppressWarnings( {"MissingPermission"}) public void onConnected() { - if (locationEngine != null) { - locationEngine.requestLocationUpdates(); - } + // Currently don't handle this inside SDK } @Override diff --git a/plugin-traffic/src/main/java/com/mapbox/mapboxsdk/plugins/traffic/TrafficPlugin.java b/plugin-traffic/src/main/java/com/mapbox/mapboxsdk/plugins/traffic/TrafficPlugin.java index c9d6b56e1..68747b996 100644 --- a/plugin-traffic/src/main/java/com/mapbox/mapboxsdk/plugins/traffic/TrafficPlugin.java +++ b/plugin-traffic/src/main/java/com/mapbox/mapboxsdk/plugins/traffic/TrafficPlugin.java @@ -7,13 +7,11 @@ import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.style.functions.CameraFunction; -import com.mapbox.mapboxsdk.style.functions.Function; -import com.mapbox.mapboxsdk.style.functions.stops.Stop; -import com.mapbox.mapboxsdk.style.layers.Filter; +import com.mapbox.mapboxsdk.style.expressions.Expression; import com.mapbox.mapboxsdk.style.layers.Layer; import com.mapbox.mapboxsdk.style.layers.LineLayer; import com.mapbox.mapboxsdk.style.layers.Property; +import com.mapbox.mapboxsdk.style.layers.PropertyFactory; import com.mapbox.mapboxsdk.style.layers.SymbolLayer; import com.mapbox.mapboxsdk.style.sources.Source; import com.mapbox.mapboxsdk.style.sources.VectorSource; @@ -23,12 +21,14 @@ import timber.log.Timber; -import static com.mapbox.mapboxsdk.style.functions.Function.zoom; -import static com.mapbox.mapboxsdk.style.functions.stops.Stop.stop; -import static com.mapbox.mapboxsdk.style.functions.stops.Stops.categorical; -import static com.mapbox.mapboxsdk.style.functions.stops.Stops.exponential; -import static com.mapbox.mapboxsdk.style.layers.Filter.in; -import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillColor; +import static com.mapbox.mapboxsdk.style.expressions.Expression.exponential; +import static com.mapbox.mapboxsdk.style.expressions.Expression.get; +import static com.mapbox.mapboxsdk.style.expressions.Expression.interpolate; +import static com.mapbox.mapboxsdk.style.expressions.Expression.literal; +import static com.mapbox.mapboxsdk.style.expressions.Expression.match; +import static com.mapbox.mapboxsdk.style.expressions.Expression.stop; +import static com.mapbox.mapboxsdk.style.expressions.Expression.toColor; +import static com.mapbox.mapboxsdk.style.expressions.Expression.zoom; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineCap; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineColor; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineJoin; @@ -336,25 +336,25 @@ private void addTrafficLayersToMap(Layer layerCase, Layer layer, String idAboveL private static class TrafficLayer { - static LineLayer getLineLayer(String lineLayerId, float minZoom, Filter.Statement statement, - Function lineColor, CameraFunction lineWidth, Function lineOffset) { + static LineLayer getLineLayer(String lineLayerId, float minZoom, Expression statement, + Expression lineColor, Expression lineWidth, Expression lineOffset) { return getLineLayer(lineLayerId, minZoom, statement, lineColor, lineWidth, lineOffset, null); } - static LineLayer getLineLayer(String lineLayerId, float minZoom, Filter.Statement statement, - Function lineColor, CameraFunction lineWidth, Function lineOffset, - Function lineOpacity) { + static LineLayer getLineLayer(String lineLayerId, float minZoom, Expression statement, + Expression lineColorExpression, Expression lineWidthExpression, + Expression lineOffsetExpression, Expression lineOpacityExpression) { LineLayer lineLayer = new LineLayer(lineLayerId, TrafficData.SOURCE_ID); lineLayer.setSourceLayer(TrafficData.SOURCE_LAYER); lineLayer.setProperties( lineCap("round"), lineJoin("round"), - lineColor(lineColor), - lineWidth(lineWidth), - lineOffset(lineOffset) + lineColor(lineColorExpression), + lineWidth(lineWidthExpression), + lineOffset(lineOffsetExpression) ); - if (lineOpacity != null) { - lineLayer.setProperties(lineOpacity(lineOpacity)); + if (lineOpacityExpression != null) { + lineLayer.setProperties(lineOpacity(lineOpacityExpression)); } lineLayer.setFilter(statement); @@ -364,29 +364,14 @@ static LineLayer getLineLayer(String lineLayerId, float minZoom, Filter.Statemen } private static class TrafficFunction { - static Function getLineColorFunction(@ColorInt int low, @ColorInt int moderate, @ColorInt int heavy, - @ColorInt int severe) { - return Function.property( - "congestion", - categorical( - stop("low", fillColor(low)), - stop("moderate", fillColor(moderate)), - stop("heavy", fillColor(heavy)), - stop("severe", fillColor(severe)) - ) - ).withDefaultValue(fillColor(Color.TRANSPARENT)); - } - - static CameraFunction getOffsetFunction(Stop... stops) { - return zoom(exponential(stops).withBase(1.5f)); - } - - static CameraFunction getWidthFunction(Stop... stops) { - return zoom(exponential(stops).withBase(1.5f)); - } - - static Function getOpacityFunction(Stop... stops) { - return zoom(exponential(stops)); + static Expression getLineColorFunction(@ColorInt int low, @ColorInt int moderate, @ColorInt int heavy, + @ColorInt int severe) { + // fixme replace toColor with color expression after 6.0.0-beta.5 + return match(get("congestion"), toColor(literal(PropertyFactory.colorToRgbaString(Color.TRANSPARENT))), + stop("low", toColor(literal(PropertyFactory.colorToRgbaString(low)))), + stop("moderate", toColor(literal(PropertyFactory.colorToRgbaString(moderate)))), + stop("heavy", toColor(literal(PropertyFactory.colorToRgbaString(heavy)))), + stop("severe", toColor(literal(PropertyFactory.colorToRgbaString(severe))))); } } @@ -397,9 +382,9 @@ static class TrafficData { } private static class TrafficType { - static final Function FUNCTION_LINE_COLOR = TrafficFunction.getLineColorFunction(TrafficColor.BASE_GREEN, + static final Expression FUNCTION_LINE_COLOR = TrafficFunction.getLineColorFunction(TrafficColor.BASE_GREEN, TrafficColor.BASE_YELLOW, TrafficColor.BASE_ORANGE, TrafficColor.BASE_RED); - static final Function FUNCTION_LINE_COLOR_CASE = TrafficFunction.getLineColorFunction( + static final Expression FUNCTION_LINE_COLOR_CASE = TrafficFunction.getLineColorFunction( TrafficColor.CASE_GREEN, TrafficColor.CASE_YELLOW, TrafficColor.CASE_ORANGE, TrafficColor.CASE_RED); } @@ -407,78 +392,157 @@ static class MotorWay extends TrafficType { static final String BASE_LAYER_ID = "traffic-motorway"; static final String CASE_LAYER_ID = "traffic-motorway-bg"; static final float ZOOM_LEVEL = 6.0f; - static final Filter.Statement FILTER = in("class", "motorway"); - static final CameraFunction FUNCTION_LINE_WIDTH = TrafficFunction.getWidthFunction( - stop(6, lineWidth(0.5f)), stop(9, lineWidth(1.5f)), stop(18.0f, lineWidth(14.0f)), - stop(20.0f, lineWidth(18.0f))); - static final CameraFunction FUNCTION_LINE_WIDTH_CASE = TrafficFunction.getWidthFunction( - stop(6, lineWidth(0.5f)), stop(9, lineWidth(3.0f)), stop(18.0f, lineWidth(16.0f)), - stop(20.0f, lineWidth(20.0f))); - static final CameraFunction FUNCTION_LINE_OFFSET = TrafficFunction.getOffsetFunction( - stop(7, lineOffset(0.0f)), stop(9, lineOffset(1.2f)), stop(11, lineOffset(1.2f)), - stop(18, lineOffset(10.0f)), stop(20, lineOffset(15.5f))); + static final Expression FILTER = match( + get("class"), literal(false), + stop("motorway", true) + ); + + static final Expression FUNCTION_LINE_WIDTH = interpolate(exponential(1.5f), zoom(), + stop(6, 0.5f), + stop(9, 1.5f), + stop(18.0f, 14.0f), + stop(20.0f, 18.0f) + ); + + static final Expression FUNCTION_LINE_WIDTH_CASE = interpolate(exponential(1.5f), zoom(), + stop(6, 0.5f), + stop(9, 3.0f), + stop(18.0f, 16.0f), + stop(20.0f, 20.0f) + ); + + static final Expression FUNCTION_LINE_OFFSET = interpolate(exponential(1.5f), zoom(), + stop(7, 0.0f), + stop(9, 1.2f), + stop(11, 1.2f), + stop(18, 10.0f), + stop(20, 15.5f)); } static class Trunk extends TrafficType { static final String BASE_LAYER_ID = "traffic-trunk"; static final String CASE_LAYER_ID = "traffic-trunk-bg"; static final float ZOOM_LEVEL = 6.0f; - static final Filter.Statement FILTER = in("class", "trunk"); - static final CameraFunction FUNCTION_LINE_WIDTH = TrafficFunction.getWidthFunction( - stop(8, lineWidth(0.75f)), stop(18, lineWidth(11f)), stop(20f, lineWidth(15.0f))); - static final CameraFunction FUNCTION_LINE_WIDTH_CASE = TrafficFunction.getWidthFunction( - stop(8, lineWidth(0.5f)), stop(9, lineWidth(2.25f)), stop(18.0f, lineWidth(13.0f)), - stop(20.0f, lineWidth(17.5f))); - static final CameraFunction FUNCTION_LINE_OFFSET = TrafficFunction.getOffsetFunction( - stop(7, lineOffset(0.0f)), stop(9, lineOffset(1f)), stop(18, lineOffset(13f)), - stop(20, lineOffset(18.0f))); + + static final Expression FILTER = match( + get("class"), literal(false), + stop("trunk", true) + ); + + static final Expression FUNCTION_LINE_WIDTH = interpolate(exponential(1.5f), zoom(), + stop(8, 0.75f), + stop(18, 11f), + stop(20f, 15.0f) + ); + + static final Expression FUNCTION_LINE_WIDTH_CASE = interpolate(exponential(1.5f), zoom(), + stop(8, 0.5f), + stop(9, 2.25f), + stop(18.0f, 13.0f), + stop(20.0f, 17.5f) + ); + + static final Expression FUNCTION_LINE_OFFSET = interpolate(exponential(1.5f), zoom(), + stop(7, 0.0f), + stop(9, 1f), + stop(18, 13f), + stop(20, 18.0f)); } static class Primary extends TrafficType { static final String BASE_LAYER_ID = "traffic-primary"; static final String CASE_LAYER_ID = "traffic-primary-bg"; static final float ZOOM_LEVEL = 6.0f; - static final Filter.Statement FILTER = in("class", "primary"); - static final CameraFunction FUNCTION_LINE_WIDTH = TrafficFunction.getWidthFunction( - stop(10, lineWidth(1.0f)), stop(15, lineWidth(4.0f)), stop(20, lineWidth(16f))); - static final CameraFunction FUNCTION_LINE_WIDTH_CASE = TrafficFunction.getWidthFunction( - stop(10, lineWidth(0.75f)), stop(15, lineWidth(6f)), stop(20.0f, lineWidth(18.0f))); - static final CameraFunction FUNCTION_LINE_OFFSET = TrafficFunction.getOffsetFunction( - stop(10, lineOffset(0.0f)), stop(12, lineOffset(1.5f)), stop(18, lineOffset(13f)), - stop(20, lineOffset(16.0f))); - static final Function FUNCTION_LINE_OPACITY_CASE = TrafficFunction.getOpacityFunction( - stop(11, lineOpacity(0.0f)), stop(12, lineOpacity(1.0f))); + + static final Expression FILTER = match( + get("class"), literal(false), + stop("primary", literal(true)) + ); + + static final Expression FUNCTION_LINE_WIDTH = interpolate(exponential(1.5f), zoom(), + stop(10, 1.0f), + stop(15, 4.0f), + stop(20, 16f) + ); + + static final Expression FUNCTION_LINE_WIDTH_CASE = interpolate(exponential(1.5f), zoom(), + stop(10, 0.75f), + stop(15, 6f), + stop(20.0f, 18.0f) + ); + + static final Expression FUNCTION_LINE_OFFSET = interpolate(exponential(1.5f), zoom(), + stop(10, 0.0f), + stop(12, 1.5f), + stop(18, 13f), + stop(20, 16.0f) + ); + + static final Expression FUNCTION_LINE_OPACITY_CASE = interpolate(exponential(1.0f), zoom(), + stop(11, 0.0f), + stop(12, 1.0f) + ); } static class Secondary extends TrafficType { static final String BASE_LAYER_ID = "traffic-secondary-tertiary"; static final String CASE_LAYER_ID = "traffic-secondary-tertiary-bg"; static final float ZOOM_LEVEL = 6.0f; - static final Filter.Statement FILTER = in("class", "secondary", "tertiary"); - static final CameraFunction FUNCTION_LINE_WIDTH = TrafficFunction.getWidthFunction( - stop(9, lineWidth(0.5f)), stop(18, lineWidth(9.0f)), stop(20, lineWidth(14f))); - static final CameraFunction FUNCTION_LINE_WIDTH_CASE = TrafficFunction.getWidthFunction( - stop(9, lineWidth(1.5f)), stop(18, lineWidth(11f)), stop(20.0f, lineWidth(16.5f))); - static final CameraFunction FUNCTION_LINE_OFFSET = TrafficFunction.getOffsetFunction( - stop(10, lineOffset(0.5f)), stop(15, lineOffset(5f)), stop(18, lineOffset(11f)), - stop(20, lineOffset(14.5f))); - static final Function FUNCTION_LINE_OPACITY_CASE = TrafficFunction.getOpacityFunction( - stop(13, lineOpacity(0.0f)), stop(14, lineOpacity(1.0f))); + static final String[] FILTER_LAYERS = new String[] {"secondary", "tertiary"}; + + static final Expression FILTER = match(get("class"), literal(false), literal(FILTER_LAYERS), literal(true)); + + static final Expression FUNCTION_LINE_WIDTH = interpolate(exponential(1.5f), zoom(), + stop(9, 0.5f), + stop(18, 9.0f), + stop(20, 14f) + ); + + static final Expression FUNCTION_LINE_WIDTH_CASE = interpolate(exponential(1.5f), zoom(), + stop(9, 1.5f), + stop(18, 11f), + stop(20.0f, 16.5f) + ); + + static final Expression FUNCTION_LINE_OFFSET = interpolate(exponential(1.5f), zoom(), + stop(10, 0.5f), + stop(15, 5f), + stop(18, 11f), + stop(20, 14.5f) + ); + + static final Expression FUNCTION_LINE_OPACITY_CASE = interpolate(exponential(1.0f), zoom(), + stop(13, 0.0f), + stop(14, 1.0f) + ); } static class Local extends TrafficType { static final String BASE_LAYER_ID = "traffic-local"; static final String CASE_LAYER_ID = "traffic-local-case"; static final float ZOOM_LEVEL = 15.0f; - static final Filter.Statement FILTER = in("class", "motorway_link", "service", "street"); - static final CameraFunction FUNCTION_LINE_WIDTH = TrafficFunction.getWidthFunction( - stop(14, lineWidth(1.5f)), stop(20, lineWidth(13.5f))); - static final CameraFunction FUNCTION_LINE_WIDTH_CASE = TrafficFunction.getWidthFunction( - stop(14, lineWidth(2.5f)), stop(20, lineWidth(15.5f))); - static final CameraFunction FUNCTION_LINE_OFFSET = TrafficFunction.getOffsetFunction( - stop(14, lineOffset(2f)), stop(20, lineOffset(18f))); - static final Function FUNCTION_LINE_OPACITY_CASE = TrafficFunction.getOpacityFunction( - stop(15, lineOpacity(0.0f)), stop(16, lineOpacity(1.0f))); + + static final String[] FILTER_LAYERS = new String[] {"motorway_link", "service", "street"}; + + static final Expression FILTER = match(get("class"), literal(false), literal(FILTER_LAYERS), literal(true)); + + static final Expression FUNCTION_LINE_WIDTH = interpolate(exponential(1.5f), zoom(), + stop(14, 1.5f), + stop(20, 13.5f) + ); + static final Expression FUNCTION_LINE_WIDTH_CASE = interpolate(exponential(1.5f), zoom(), + stop(14, 2.5f), + stop(20, 15.5f) + ); + static final Expression FUNCTION_LINE_OFFSET = interpolate(exponential(1.5f), zoom(), + stop(14, 2f), + stop(20, 18f) + ); + + static final Expression FUNCTION_LINE_OPACITY_CASE = interpolate(exponential(1.0f), zoom(), + stop(15, 0.0f), + stop(16, 1.0f) + ); } private static class TrafficColor {