summaryrefslogtreecommitdiff
path: root/platform/android
diff options
context:
space:
mode:
authorTim Watson <tewatson89@gmail.com>2019-04-03 14:51:13 -0700
committerGitHub <noreply@github.com>2019-04-03 14:51:13 -0700
commit0ff25060dae4858a1b60e2277dbd8921de7a6785 (patch)
treed29d578b9b9d6cfb0999b7a30819d379b85172b7 /platform/android
parentba2b7a74c420856401d344ff15b27771175c9819 (diff)
parent0f416fbbde9b146eb28a4bf88586738d12505007 (diff)
downloadqtlocation-mapboxgl-0ff25060dae4858a1b60e2277dbd8921de7a6785.tar.gz
Merge pull request #1 from mapbox/masterupstream/friedbunny-external-pr-14135
Merge Master
Diffstat (limited to 'platform/android')
-rw-r--r--platform/android/CHANGELOG.md42
-rw-r--r--platform/android/LICENSE.md36
-rw-r--r--platform/android/MapboxGLAndroidSDK/build.gradle12
-rw-r--r--platform/android/MapboxGLAndroidSDK/gradle.properties2
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java37
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java6
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java16
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentConstants.java32
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationLayerController.java17
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraChangeDispatcher.java8
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java103
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java4
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java7
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMap.java2
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java9
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Style.java17
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java49
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/glsurfaceview/GLSurfaceViewMapRenderer.java10
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/textureview/TextureViewRenderThread.java1
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java4
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/PerformanceEvent.java94
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/TelemetryImpl.java5
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java4
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java5
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java40
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java32
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/Formatted.java8
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/FormattedSection.java10
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/BitmapUtils.java3
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_internal.xml4
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngTest.java11
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationCameraControllerTest.java30
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.java40
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.kt150
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/build.gradle2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/assets/streets.json5331
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/InstrumentationApplication.kt10
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/InstrumentationRunner.kt11
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/BaseIntegrationTest.kt39
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/FragmentBackStackTest.kt52
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/GLSurfaceViewReopenTest.kt30
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/GLSurfaceViewReuseTest.kt31
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/OrientationChangeTest.kt34
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/TextureViewReopenTest.kt33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/TextureViewReuseTest.kt31
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/ViewPagerScrollTest.kt38
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt96
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.kt34
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/GLSurfaceViewReopenTest.kt73
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxTest.java3
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/OrientationTest.java41
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/TextureViewReopenTest.kt77
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/VisibleRegionTest.kt80
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/module/telemetry/PerformanceEventTest.java188
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/OrientationAction.java (renamed from platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/OrientationChangeAction.java)18
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/WaitAction.java7
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseTest.java126
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/EspressoTest.java18
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/IconTest.java161
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraForTest.java340
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/fragment/MapDialogFragmentTest.kt4
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/geometry/GeoJsonConversionTest.java118
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/StyleLoadTest.kt8
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/AttributionTest.java16
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/CompassViewTest.java3
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/offline/OfflineManagerTest.kt123
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CustomGeometrySourceTest.kt21
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ExpressionTest.java26
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/GeoJsonSourceTests.java2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ImageTest.java46
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ImageTest.kt75
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTests.java13
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java28
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/FinishLoadingStyleIdlingResource.java35
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/LoadStyleIdlingResource.java40
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/MapboxIdlingResource.java46
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/OnMapReadyIdlingResource.java60
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml50
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxApplication.java2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/GestureDetectorActivity.java13
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/espresso/PixelTestActivity.kt66
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java14
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/SupportMapFragmentActivity.java14
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/ViewPagerActivity.java117
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/ViewPagerActivity.kt109
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/SnapshotActivity.java114
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/SnapshotActivity.kt80
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/GLSurfaceRecyclerViewActivity.kt155
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapInDialogActivity.java34
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/RecyclerViewActivity.kt151
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/TextureRecyclerViewActivity.kt15
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/telemetry/PerformanceMeasurementActivity.java187
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_backstack_fragment.xml1
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_pixel_test.xml16
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_snapshot.xml12
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_viewpager.xml2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/item_map_gl.xml10
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/item_map_texture.xml (renamed from platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/item_map.xml)0
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/categories.xml2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml4
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/titles.xml4
-rw-r--r--platform/android/build.gradle1
-rw-r--r--platform/android/gradle/android-nitpick.gradle10
-rw-r--r--platform/android/gradle/dependencies.gradle6
-rw-r--r--platform/android/gradle/jacoco-report.gradle33
-rw-r--r--platform/android/scripts/exclude-activity-gen.json4
-rwxr-xr-xplatform/android/scripts/generate-style-code.js7
-rwxr-xr-xplatform/android/scripts/parse-jacoco-report.py31
-rw-r--r--platform/android/scripts/validate-license.py17
-rw-r--r--platform/android/src/conversion/constant.hpp11
-rw-r--r--platform/android/src/file_source.cpp27
-rw-r--r--platform/android/src/file_source.hpp6
-rw-r--r--platform/android/src/map_renderer.hpp4
-rwxr-xr-xplatform/android/src/native_map_view.cpp13
-rwxr-xr-xplatform/android/src/native_map_view.hpp1
-rw-r--r--platform/android/src/offline/offline_manager.cpp13
-rw-r--r--platform/android/src/offline/offline_manager.hpp8
-rw-r--r--platform/android/src/offline/offline_region.cpp14
-rw-r--r--platform/android/src/offline/offline_region.hpp2
-rw-r--r--platform/android/src/snapshotter/map_snapshotter.cpp10
-rw-r--r--platform/android/src/style/layers/symbol_layer.cpp12
-rw-r--r--platform/android/src/style/layers/symbol_layer.hpp4
m---------platform/android/vendor/mapbox-events-android0
123 files changed, 7977 insertions, 1847 deletions
diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md
index 7a117f4b2a..55cfd1a6cd 100644
--- a/platform/android/CHANGELOG.md
+++ b/platform/android/CHANGELOG.md
@@ -4,6 +4,48 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to
## master
+## 7.4.0-alpha.1 - April 3, 2019
+
+### Bugs
+ - Clean up location permissions annotation [#14311](https://github.com/mapbox/mapbox-gl-native/pull/14311)
+ - Clear camera callbacks' message queue when the map is destroyed [#14292](https://github.com/mapbox/mapbox-gl-native/pull/14292)
+ - Use a valid gestures focal point when resetting a manager [#14284](https://github.com/mapbox/mapbox-gl-native/pull/14284)
+ - Disable move gesture detector foreseeing the quickzoom [#14268](https://github.com/mapbox/mapbox-gl-native/pull/14268)
+ - Remove request render from MapboxMap#onStart [#14245](https://github.com/mapbox/mapbox-gl-native/pull/14245)
+ - Use TurfMeasurement#distance in LatLng#distanceTo [#14220](https://github.com/mapbox/mapbox-gl-native/pull/14220)
+
+### Features
+ - Add pixel dimension annotation to public UiSettings methods [#14281](https://github.com/mapbox/mapbox-gl-native/pull/14281)
+ - Add #toString override for formatted sections [#14247](https://github.com/mapbox/mapbox-gl-native/pull/14247)
+ - Harden fetching camera for bounds when padding is excessive [#14221](https://github.com/mapbox/mapbox-gl-native/pull/14221)
+ - Traverse expression tree when checking for property overrides [#14259](https://github.com/mapbox/mapbox-gl-native/pull/14259)
+ - Variable label placement [#14184](https://github.com/mapbox/mapbox-gl-native/pull/14184)
+
+### Build
+ - Disable binary programs until we fix [#14294]((https://github.com/mapbox/mapbox-gl-native/pull/14298)
+ - Disable leak canary during instrumentation tests [#14296](https://github.com/mapbox/mapbox-gl-native/pull/14296)
+ - Remove Android v7 support library [#14265](https://github.com/mapbox/mapbox-gl-native/pull/14265)
+
+## 7.3.0 - March 28, 2019
+
+### Bugs
+ - Fix MapView reuse issues [#14127](https://github.com/mapbox/mapbox-gl-native/pull/14127)
+ - Don't call OnSurfaceCreated from the main thread [#14244](https://github.com/mapbox/mapbox-gl-native/pull/14244)
+
+## 7.3.0-beta.1 - March 20, 2019
+
+### Features
+ - Expose "text-color" option for formatted sections [#14128](https://github.com/mapbox/mapbox-gl-native/pull/14128)
+ - Expose LocationComponent's layer IDs [#14155](https://github.com/mapbox/mapbox-gl-native/pull/14155)
+
+### Bugs
+ - Cache location layer IDs in a set instead of a list [#14141](https://github.com/mapbox/mapbox-gl-native/pull/14141)
+ - Clear the style object when the map is destroyed [#14171](https://github.com/mapbox/mapbox-gl-native/pull/14171)
+ - Cache source/layer only when successfully added [#14171](https://github.com/mapbox/mapbox-gl-native/pull/14171)
+
+### Build
+ - Bump telemetry version to 4.3.0 [#14140](https://github.com/mapbox/mapbox-gl-native/pull/14140)
+
## 7.3.0-alpha.2 - March 13, 2019
### Features
diff --git a/platform/android/LICENSE.md b/platform/android/LICENSE.md
index f69b393541..d6f4e65302 100644
--- a/platform/android/LICENSE.md
+++ b/platform/android/LICENSE.md
@@ -1,11 +1,5 @@
<!-- This file was generated. Use `make android-license` to update. -->
## Additional Mapbox GL licenses
-Mapbox GL uses portions of the Android AppCompat Library v7.
-URL: [http://developer.android.com/tools/extras/support-library.html](http://developer.android.com/tools/extras/support-library.html)
-License: [The Apache Software License](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
-===========================================================================
-
Mapbox GL uses portions of the Android Arch-Common.
URL: [https://developer.android.com/topic/libraries/architecture/index.html](https://developer.android.com/topic/libraries/architecture/index.html)
License: [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)
@@ -18,18 +12,6 @@ License: [The Apache Software License, Version 2.0](http://www.apache.org/licens
===========================================================================
-Mapbox GL uses portions of the Android Lifecycle Extensions.
-URL: [https://developer.android.com/topic/libraries/architecture/index.html](https://developer.android.com/topic/libraries/architecture/index.html)
-License: [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
-===========================================================================
-
-Mapbox GL uses portions of the Android Lifecycle LiveData.
-URL: [https://developer.android.com/topic/libraries/architecture/index.html](https://developer.android.com/topic/libraries/architecture/index.html)
-License: [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
-===========================================================================
-
Mapbox GL uses portions of the Android Lifecycle LiveData Core.
URL: [https://developer.android.com/topic/libraries/architecture/index.html](https://developer.android.com/topic/libraries/architecture/index.html)
License: [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)
@@ -54,12 +36,6 @@ License: [The Apache Software License, Version 2.0](http://www.apache.org/licens
===========================================================================
-Mapbox GL uses portions of the Android Support AnimatedVectorDrawable.
-URL: [http://developer.android.com/tools/extras/support-library.html](http://developer.android.com/tools/extras/support-library.html)
-License: [The Apache Software License](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
-===========================================================================
-
Mapbox GL uses portions of the Android Support Library Annotations.
URL: [http://developer.android.com/tools/extras/support-library.html](http://developer.android.com/tools/extras/support-library.html)
License: [The Apache Software License](http://www.apache.org/licenses/LICENSE-2.0.txt)
@@ -90,12 +66,6 @@ License: [The Apache Software License](http://www.apache.org/licenses/LICENSE-2.
===========================================================================
-Mapbox GL uses portions of the Android Support VectorDrawable.
-URL: [http://developer.android.com/tools/extras/support-library.html](http://developer.android.com/tools/extras/support-library.html)
-License: [The Apache Software License](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
-===========================================================================
-
Mapbox GL uses portions of the Converter: Gson.
License: [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt)
@@ -157,6 +127,12 @@ License: [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)
===========================================================================
+Mapbox GL uses portions of the ReLinker.
+URL: [https://github.com/KeepSafe/ReLinker](https://github.com/KeepSafe/ReLinker)
+License: [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)
+
+===========================================================================
+
Mapbox GL uses portions of the Retrofit.
License: [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt)
diff --git a/platform/android/MapboxGLAndroidSDK/build.gradle b/platform/android/MapboxGLAndroidSDK/build.gradle
index 89937448e9..74c7c4c465 100644
--- a/platform/android/MapboxGLAndroidSDK/build.gradle
+++ b/platform/android/MapboxGLAndroidSDK/build.gradle
@@ -8,7 +8,6 @@ dependencies {
api dependenciesList.mapboxJavaGeoJSON
api dependenciesList.mapboxAndroidGestures
implementation dependenciesList.mapboxJavaTurf
- implementation dependenciesList.supportAppcompatV7
implementation dependenciesList.supportAnnotations
implementation dependenciesList.supportFragmentV4
implementation dependenciesList.okhttp3
@@ -23,10 +22,6 @@ dependencies {
android {
compileSdkVersion androidVersions.compileSdkVersion
- // Roboelectric 4.0 required config
- // http://robolectric.org/migrating/#migrating-to-40
- testOptions.unitTests.includeAndroidResources = true
-
defaultConfig {
minSdkVersion androidVersions.minSdkVersion
targetSdkVersion androidVersions.targetSdkVersion
@@ -134,12 +129,16 @@ android {
testOptions {
unitTests {
returnDefaultValues true
+
+ // Roboelectric 4.0 required config
+ // http://robolectric.org/migrating/#migrating-to-40
includeAndroidResources = true
}
}
buildTypes {
debug {
+ testCoverageEnabled true
jniDebuggable true
}
}
@@ -169,4 +168,5 @@ apply from: "${rootDir}/gradle/gradle-checkstyle.gradle"
apply from: "${rootDir}/gradle/gradle-dependencies-graph.gradle"
apply from: "${rootDir}/gradle/gradle-update-vendor-modules.gradle"
apply from: "${rootDir}/gradle/android-nitpick.gradle"
-apply from: "${rootDir}/gradle/gradle-bintray.gradle" \ No newline at end of file
+apply from: "${rootDir}/gradle/gradle-bintray.gradle"
+apply from: "${rootDir}/gradle/jacoco-report.gradle" \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/gradle.properties b/platform/android/MapboxGLAndroidSDK/gradle.properties
index be4246a903..5f3ea808fa 100644
--- a/platform/android/MapboxGLAndroidSDK/gradle.properties
+++ b/platform/android/MapboxGLAndroidSDK/gradle.properties
@@ -1,4 +1,4 @@
-VERSION_NAME=7.3.0-SNAPSHOT
+VERSION_NAME=7.4.0-SNAPSHOT
# Only build native dependencies for the current ABI
# See https://code.google.com/p/android/issues/detail?id=221098#c20
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java
index 8ae388549e..ce12489b49 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java
@@ -5,10 +5,14 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.FloatRange;
import android.support.annotation.Keep;
-
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+
+import com.mapbox.geojson.Point;
import com.mapbox.mapboxsdk.constants.GeometryConstants;
+import com.mapbox.turf.TurfMeasurement;
+
+import static com.mapbox.turf.TurfConstants.UNIT_METRES;
/**
@@ -209,7 +213,8 @@ public class LatLng implements Parcelable {
@NonNull
public LatLng wrap() {
return new LatLng(latitude, wrap(longitude,
- GeometryConstants.MIN_WRAP_LONGITUDE, GeometryConstants.MAX_WRAP_LONGITUDE));
+ GeometryConstants.MIN_WRAP_LONGITUDE, GeometryConstants.MAX_WRAP_LONGITUDE)
+ );
}
@@ -218,8 +223,10 @@ public class LatLng implements Parcelable {
* <p>
* Same formula as used in Core GL (wrap.hpp)
* std::fmod((std::fmod((value - min), d) + d), d) + min;
- *
+ * </p>
+ * <p>
* Multiples of max value will be wrapped to max.
+ * </p>
*
* @param value Value to wrap
* @param min Minimum value
@@ -318,24 +325,10 @@ public class LatLng implements Parcelable {
* @return distance in meters
*/
public double distanceTo(@NonNull LatLng other) {
- if (latitude == other.latitude && longitude == other.longitude) {
- // return 0.0 to avoid a NaN
- return 0.0;
- }
-
- final double a1 = Math.toRadians(this.latitude);
- final double a2 = Math.toRadians(this.longitude);
- final double b1 = Math.toRadians(other.getLatitude());
- final double b2 = Math.toRadians(other.getLongitude());
-
- final double cosa1 = Math.cos(a1);
- final double cosb1 = Math.cos(b1);
-
- final double t1 = cosa1 * Math.cos(a2) * cosb1 * Math.cos(b2);
- final double t2 = cosa1 * Math.sin(a2) * cosb1 * Math.sin(b2);
- final double t3 = Math.sin(a1) * Math.sin(b1);
- final double tt = Math.acos(t1 + t2 + t3);
-
- return GeometryConstants.RADIUS_EARTH_METERS * tt;
+ return TurfMeasurement.distance(
+ Point.fromLngLat(longitude, latitude),
+ Point.fromLngLat(other.getLongitude(), other.getLatitude()),
+ UNIT_METRES
+ );
}
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java
index 4e56c6e9c0..b9aa371a47 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java
@@ -77,9 +77,11 @@ final class LocationCameraController {
void initializeOptions(LocationComponentOptions options) {
this.options = options;
if (options.trackingGesturesManagement()) {
- mapboxMap.setGesturesManager(internalGesturesManager, true, true);
+ if (mapboxMap.getGesturesManager() != internalGesturesManager) {
+ mapboxMap.setGesturesManager(internalGesturesManager, true, true);
+ }
adjustGesturesThresholds();
- } else {
+ } else if (mapboxMap.getGesturesManager() != initialGesturesManager) {
mapboxMap.setGesturesManager(initialGesturesManager, true, true);
}
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java
index b97ab75b5e..327ab3c8ed 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java
@@ -220,7 +220,6 @@ public final class LocationComponent {
* @param style the proxy object for current map style. More info at {@link Style}
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
*/
- @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
@Deprecated
public void activateLocationComponent(@NonNull Context context, @NonNull Style style) {
activateLocationComponent(context, style,
@@ -237,7 +236,6 @@ public final class LocationComponent {
* there should be no location engine initialized
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
*/
- @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
@Deprecated
public void activateLocationComponent(@NonNull Context context, @NonNull Style style,
boolean useDefaultLocationEngine) {
@@ -259,7 +257,6 @@ public final class LocationComponent {
* @param locationEngineRequest the location request
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
*/
- @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
@Deprecated
public void activateLocationComponent(@NonNull Context context, @NonNull Style style,
boolean useDefaultLocationEngine,
@@ -284,7 +281,6 @@ public final class LocationComponent {
* @param options the options
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
*/
- @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
@Deprecated
public void activateLocationComponent(@NonNull Context context, @NonNull Style style,
boolean useDefaultLocationEngine,
@@ -309,7 +305,6 @@ public final class LocationComponent {
* @param styleRes the LocationComponent style res
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
*/
- @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
@Deprecated
public void activateLocationComponent(@NonNull Context context, @NonNull Style style, @StyleRes int styleRes) {
activateLocationComponent(context, style, LocationComponentOptions.createFromAttributes(context, styleRes));
@@ -327,7 +322,6 @@ public final class LocationComponent {
* @param options the options
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
*/
- @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
@Deprecated
public void activateLocationComponent(@NonNull Context context, @NonNull Style style,
@NonNull LocationComponentOptions options) {
@@ -346,7 +340,6 @@ public final class LocationComponent {
* @param styleRes the LocationComponent style res
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
*/
- @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
@Deprecated
public void activateLocationComponent(@NonNull Context context, @NonNull Style style,
@Nullable LocationEngine locationEngine, @StyleRes int styleRes) {
@@ -365,7 +358,6 @@ public final class LocationComponent {
* @param styleRes the LocationComponent style res
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
*/
- @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
@Deprecated
public void activateLocationComponent(@NonNull Context context, @NonNull Style style,
@Nullable LocationEngine locationEngine,
@@ -382,7 +374,6 @@ public final class LocationComponent {
* @param locationEngine the engine
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
*/
- @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
@Deprecated
public void activateLocationComponent(@NonNull Context context, @NonNull Style style,
@Nullable LocationEngine locationEngine) {
@@ -398,7 +389,6 @@ public final class LocationComponent {
* @param locationEngineRequest the location request
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
*/
- @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
@Deprecated
public void activateLocationComponent(@NonNull Context context, @NonNull Style style,
@Nullable LocationEngine locationEngine,
@@ -415,7 +405,6 @@ public final class LocationComponent {
* @param options the options
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
*/
- @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
@Deprecated
public void activateLocationComponent(@NonNull Context context, @NonNull Style style,
@Nullable LocationEngine locationEngine,
@@ -453,8 +442,7 @@ public final class LocationComponent {
*
* @param activationOptions a fully built {@link LocationComponentActivationOptions} object
*/
- public void activateLocationComponent(@NonNull LocationComponentActivationOptions
- activationOptions) {
+ public void activateLocationComponent(@NonNull LocationComponentActivationOptions activationOptions) {
LocationComponentOptions options = activationOptions.locationComponentOptions();
if (options == null) {
int styleRes = activationOptions.styleRes();
@@ -496,6 +484,7 @@ public final class LocationComponent {
*
* @param isEnabled true if the plugin should be visible and listen for location updates, false otherwise.
*/
+ @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
public void setLocationComponentEnabled(boolean isEnabled) {
checkActivationState();
if (isEnabled) {
@@ -954,7 +943,6 @@ public final class LocationComponent {
* @return the last known location
*/
@Nullable
- @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
public Location getLastKnownLocation() {
checkActivationState();
return lastLocation;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentConstants.java
index 093c91e799..c0173cb8e8 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentConstants.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentConstants.java
@@ -1,7 +1,7 @@
package com.mapbox.mapboxsdk.location;
/**
- * Contains all the constants being used for the Location layer.
+ * Contains all the constants being used for the {@link LocationComponent}.
*/
final class LocationComponentConstants {
@@ -49,11 +49,31 @@ final class LocationComponentConstants {
static final String PROPERTY_BEARING_ICON = "mapbox-property-shadow-icon";
// Layers
- static final String SHADOW_LAYER = "mapbox-location-shadow";
- static final String FOREGROUND_LAYER = "mapbox-location-layer";
- static final String BACKGROUND_LAYER = "mapbox-location-stroke-layer";
- static final String ACCURACY_LAYER = "mapbox-location-accuracy-layer";
- static final String BEARING_LAYER = "mapbox-location-bearing-layer";
+
+ /**
+ * Layer ID of the location shadow.
+ */
+ public static final String SHADOW_LAYER = "mapbox-location-shadow-layer";
+
+ /**
+ * Layer ID of the location foreground icon.
+ */
+ public static final String FOREGROUND_LAYER = "mapbox-location-foreground-layer";
+
+ /**
+ * Layer ID of the location background icon.
+ */
+ public static final String BACKGROUND_LAYER = "mapbox-location-background-layer";
+
+ /**
+ * Layer ID of the location accuracy.
+ */
+ public static final String ACCURACY_LAYER = "mapbox-location-accuracy-layer";
+
+ /**
+ * Layer ID of the location bearing icon.
+ */
+ public static final String BEARING_LAYER = "mapbox-location-bearing-layer";
// Icons
static final String FOREGROUND_ICON = "mapbox-location-icon";
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationLayerController.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationLayerController.java
index f11acacf31..aa8a82bf6d 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationLayerController.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationLayerController.java
@@ -5,6 +5,7 @@ import android.graphics.PointF;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
@@ -18,7 +19,6 @@ import com.mapbox.mapboxsdk.style.layers.Layer;
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
-import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -70,7 +70,8 @@ final class LocationLayerController {
private LocationComponentOptions options;
private final OnRenderModeChangedListener internalRenderModeChangedListener;
- private final List<String> layerMap = new ArrayList<>();
+ @VisibleForTesting
+ final Set<String> layerSet = new HashSet<>();
private Feature locationFeature;
private GeoJsonSource locationSource;
@@ -112,7 +113,7 @@ final class LocationLayerController {
removeLayers();
addLayers(newLayerBelowOption);
if (isHidden) {
- for (String layerId : layerMap) {
+ for (String layerId : layerSet) {
setLayerVisibility(layerId, false);
}
}
@@ -193,7 +194,7 @@ final class LocationLayerController {
void hide() {
isHidden = true;
- for (String layerId : layerMap) {
+ for (String layerId : layerSet) {
setLayerVisibility(layerId, false);
}
}
@@ -257,14 +258,14 @@ final class LocationLayerController {
private void addLayerToMap(Layer layer, @NonNull String idBelowLayer) {
style.addLayerBelow(layer, idBelowLayer);
- layerMap.add(layer.getId());
+ layerSet.add(layer.getId());
}
private void removeLayers() {
- for (String layerId : layerMap) {
+ for (String layerId : layerSet) {
style.removeLayer(layerId);
}
- layerMap.clear();
+ layerSet.clear();
}
private void setBearingProperty(@NonNull String propertyId, float bearing) {
@@ -351,7 +352,7 @@ final class LocationLayerController {
}
private void styleScaling(@NonNull LocationComponentOptions options) {
- for (String layerId : layerMap) {
+ for (String layerId : layerSet) {
Layer layer = style.getLayer(layerId);
if (layer instanceof SymbolLayer) {
layer.setProperties(
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraChangeDispatcher.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraChangeDispatcher.java
index b3472ac81e..a1fd4e7e3e 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraChangeDispatcher.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraChangeDispatcher.java
@@ -142,6 +142,14 @@ class CameraChangeDispatcher implements MapboxMap.OnCameraMoveStartedListener, M
}
}
+ void onDestroy() {
+ handler.removeCallbacksAndMessages(null);
+ onCameraMoveStarted.clear();
+ onCameraMoveCanceled.clear();
+ onCameraMove.clear();
+ onCameraIdle.clear();
+ }
+
private static class CameraChangeHandler extends Handler {
private WeakReference<CameraChangeDispatcher> dispatcherWeakReference;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java
index c9e6e633aa..9473ea7091 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java
@@ -74,7 +74,7 @@ final class MapGestureDetector {
* User-set focal point.
*/
@Nullable
- private PointF focalPoint;
+ private PointF constantFocalPoint;
private AndroidGesturesManager gesturesManager;
@@ -158,7 +158,7 @@ final class MapGestureDetector {
/**
* Set the gesture focal point.
* <p>
- * this is the center point used for calculate transformations from gestures, value is
+ * This is the center point used for calculate transformations from gestures, value is
* overridden if end user provides his own through {@link UiSettings#setFocalPoint(PointF)}.
* </p>
*
@@ -172,22 +172,7 @@ final class MapGestureDetector {
focalPoint = uiSettings.getFocalPoint();
}
}
- this.focalPoint = focalPoint;
- }
-
- /**
- * Get the current active gesture focal point.
- * <p>
- * This could be either the user provided focal point in
- * {@link UiSettings#setFocalPoint(PointF)}or <code>null</code>.
- * If it's <code>null</code>, gestures will use focal pointed returned by the detector.
- * </p>
- *
- * @return the current active gesture focal point.
- */
- @Nullable
- PointF getFocalPoint() {
- return focalPoint;
+ this.constantFocalPoint = focalPoint;
}
/**
@@ -357,18 +342,25 @@ final class MapGestureDetector {
int action = motionEvent.getActionMasked();
if (action == MotionEvent.ACTION_DOWN) {
executeDoubleTap = true;
+
+ // disable the move detector in preparation for the quickzoom,
+ // so that we don't move the map's center slightly before the quickzoom is started (see #14227)
+ gesturesManager.getMoveGestureDetector().setEnabled(false);
}
if (motionEvent.getActionMasked() == MotionEvent.ACTION_UP) {
+ // re-enabled the move detector
+ gesturesManager.getMoveGestureDetector().setEnabled(true);
+
if (!uiSettings.isZoomGesturesEnabled() || !uiSettings.isDoubleTapGesturesEnabled() || !executeDoubleTap) {
return false;
}
PointF zoomFocalPoint;
// Single finger double tap
- if (focalPoint != null) {
+ if (constantFocalPoint != null) {
// User provided focal point
- zoomFocalPoint = focalPoint;
+ zoomFocalPoint = constantFocalPoint;
} else {
// Zoom in on gesture
zoomFocalPoint = new PointF(motionEvent.getX(), motionEvent.getY());
@@ -468,9 +460,6 @@ final class MapGestureDetector {
private final class ScaleGestureListener extends StandardScaleGestureDetector.SimpleStandardOnScaleGestureListener {
private final float minimumVelocity;
-
- @Nullable
- private PointF scaleFocalPoint;
private boolean quickZoom;
ScaleGestureListener(float minimumVelocity) {
@@ -496,8 +485,6 @@ final class MapGestureDetector {
if (!uiSettings.isQuickZoomGesturesEnabled()) {
return false;
}
- // when quickzoom, disable move gesture
- gesturesManager.getMoveGestureDetector().setEnabled(false);
}
cancelTransitionsIfRequired();
@@ -510,10 +497,7 @@ final class MapGestureDetector {
);
}
- // setting focalPoint in #onScaleBegin() as well, because #onScale() might not get called before #onScaleEnd()
- setScaleFocalPoint(detector);
-
- sendTelemetryEvent(TelemetryConstants.PINCH, scaleFocalPoint);
+ sendTelemetryEvent(TelemetryConstants.PINCH, getScaleFocalPoint(detector));
notifyOnScaleBeginListeners(detector);
@@ -525,11 +509,10 @@ final class MapGestureDetector {
// dispatching camera start event only when the movement actually occurred
cameraChangeDispatcher.onCameraMoveStarted(CameraChangeDispatcher.REASON_API_GESTURE);
- setScaleFocalPoint(detector);
-
float scaleFactor = detector.getScaleFactor();
double zoomBy = getNewZoom(scaleFactor, quickZoom);
- transform.zoomBy(zoomBy, scaleFocalPoint);
+ PointF focalPoint = getScaleFocalPoint(detector);
+ transform.zoomBy(zoomBy, focalPoint);
notifyOnScaleListeners(detector);
@@ -538,11 +521,6 @@ final class MapGestureDetector {
@Override
public void onScaleEnd(@NonNull StandardScaleGestureDetector detector, float velocityX, float velocityY) {
- if (quickZoom) {
- //if quickzoom, re-enabling move gesture detector
- gesturesManager.getMoveGestureDetector().setEnabled(true);
- }
-
if (uiSettings.isIncreaseRotateThresholdWhenScaling()) {
// resetting default angle threshold
gesturesManager.getRotateGestureDetector().setAngleThreshold(
@@ -562,21 +540,23 @@ final class MapGestureDetector {
double zoomAddition = calculateScale(velocityXY, detector.isScalingOut());
double currentZoom = transform.getRawZoom();
+ PointF focalPoint = getScaleFocalPoint(detector);
long animationTime = (long) (Math.abs(zoomAddition) * 1000 / 4);
- scaleAnimator = createScaleAnimator(currentZoom, zoomAddition, scaleFocalPoint, animationTime);
+ scaleAnimator = createScaleAnimator(currentZoom, zoomAddition, focalPoint, animationTime);
scheduleAnimator(scaleAnimator);
}
- private void setScaleFocalPoint(@NonNull StandardScaleGestureDetector detector) {
- if (focalPoint != null) {
+ @NonNull
+ private PointF getScaleFocalPoint(@NonNull StandardScaleGestureDetector detector) {
+ if (constantFocalPoint != null) {
// around user provided focal point
- scaleFocalPoint = focalPoint;
+ return constantFocalPoint;
} else if (quickZoom) {
// around center
- scaleFocalPoint = new PointF(uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
+ return new PointF(uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
} else {
// around gesture
- scaleFocalPoint = detector.getFocalPoint();
+ return detector.getFocalPoint();
}
}
@@ -603,14 +583,12 @@ final class MapGestureDetector {
}
private final class RotateGestureListener extends RotateGestureDetector.SimpleOnRotateGestureListener {
- @Nullable
- private PointF rotateFocalPoint;
private final float minimumScaleSpanWhenRotating;
private final float minimumAngularVelocity;
private final float defaultSpanSinceStartThreshold;
- public RotateGestureListener(float minimumScaleSpanWhenRotating, float minimumAngularVelocity,
- float defaultSpanSinceStartThreshold) {
+ RotateGestureListener(float minimumScaleSpanWhenRotating, float minimumAngularVelocity,
+ float defaultSpanSinceStartThreshold) {
this.minimumScaleSpanWhenRotating = minimumScaleSpanWhenRotating;
this.minimumAngularVelocity = minimumAngularVelocity;
this.defaultSpanSinceStartThreshold = defaultSpanSinceStartThreshold;
@@ -631,10 +609,7 @@ final class MapGestureDetector {
gesturesManager.getStandardScaleGestureDetector().interrupt();
}
- // setting in #onRotateBegin() as well, because #onRotate() might not get called before #onRotateEnd()
- setRotateFocalPoint(detector);
-
- sendTelemetryEvent(TelemetryConstants.ROTATION, rotateFocalPoint);
+ sendTelemetryEvent(TelemetryConstants.ROTATION, getRotateFocalPoint(detector));
notifyOnRotateBeginListeners(detector);
@@ -647,13 +622,12 @@ final class MapGestureDetector {
// dispatching camera start event only when the movement actually occurred
cameraChangeDispatcher.onCameraMoveStarted(CameraChangeDispatcher.REASON_API_GESTURE);
- setRotateFocalPoint(detector);
-
// Calculate map bearing value
double bearing = transform.getRawBearing() + rotationDegreesSinceLast;
// Rotate the map
- transform.setBearing(bearing, rotateFocalPoint.x, rotateFocalPoint.y);
+ PointF focalPoint = getRotateFocalPoint(detector);
+ transform.setBearing(bearing, focalPoint.x, focalPoint.y);
notifyOnRotateListeners(detector);
@@ -687,21 +661,24 @@ final class MapGestureDetector {
angularVelocity = -angularVelocity;
}
- rotateAnimator = createRotateAnimator(angularVelocity, animationTime);
+ PointF focalPoint = getRotateFocalPoint(detector);
+ rotateAnimator = createRotateAnimator(angularVelocity, animationTime, focalPoint);
scheduleAnimator(rotateAnimator);
}
- private void setRotateFocalPoint(@NonNull RotateGestureDetector detector) {
- if (focalPoint != null) {
+ @NonNull
+ private PointF getRotateFocalPoint(@NonNull RotateGestureDetector detector) {
+ if (constantFocalPoint != null) {
// User provided focal point
- rotateFocalPoint = focalPoint;
+ return constantFocalPoint;
} else {
// around gesture
- rotateFocalPoint = detector.getFocalPoint();
+ return detector.getFocalPoint();
}
}
- private Animator createRotateAnimator(float angularVelocity, long animationTime) {
+ private Animator createRotateAnimator(float angularVelocity, long animationTime,
+ @NonNull final PointF animationFocalPoint) {
ValueAnimator animator = ValueAnimator.ofFloat(angularVelocity, 0f);
animator.setDuration(animationTime);
animator.setInterpolator(new DecelerateInterpolator());
@@ -710,7 +687,7 @@ final class MapGestureDetector {
public void onAnimationUpdate(@NonNull ValueAnimator animation) {
transform.setBearing(
transform.getRawBearing() + (float) animation.getAnimatedValue(),
- rotateFocalPoint.x, rotateFocalPoint.y,
+ animationFocalPoint.x, animationFocalPoint.y,
0L
);
}
@@ -802,9 +779,9 @@ final class MapGestureDetector {
PointF zoomFocalPoint;
// Single finger double tap
- if (focalPoint != null) {
+ if (constantFocalPoint != null) {
// User provided focal point
- zoomFocalPoint = focalPoint;
+ zoomFocalPoint = constantFocalPoint;
} else {
// Zoom in on gesture
zoomFocalPoint = detector.getFocalPoint();
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
index f87c6a854a..23ce2bdef0 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
@@ -911,7 +911,7 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback {
/**
* Called when the map has finished rendering.
*
- * @param fully true if map is fully rendered, false if fully rendered
+ * @param fully true if map is fully rendered, false if not fully rendered
*/
void onDidFinishRenderingMap(boolean fully);
}
@@ -1257,4 +1257,4 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback {
public static void setMapStrictModeEnabled(boolean strictModeEnabled) {
MapStrictMode.setStrictModeEnabled(strictModeEnabled);
}
-} \ No newline at end of file
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
index f0155bda58..95d5c29b61 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
@@ -128,7 +128,6 @@ public final class MapboxMap {
* Called when the hosting Activity/Fragment onStart() method is called.
*/
void onStart() {
- nativeMapView.update();
locationComponent.onStart();
}
@@ -174,6 +173,10 @@ public final class MapboxMap {
*/
void onDestroy() {
locationComponent.onDestroy();
+ if (style != null) {
+ style.clear();
+ }
+ cameraChangeDispatcher.onDestroy();
}
/**
@@ -813,7 +816,7 @@ public final class MapboxMap {
public void setStyle(Style.Builder builder, final Style.OnStyleLoaded callback) {
locationComponent.onStartLoadingMap();
if (style != null) {
- style.onWillStartLoadingMap();
+ style.clear();
}
if (callback != null) {
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMap.java
index cf5961a313..e49126531a 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMap.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMap.java
@@ -29,8 +29,6 @@ interface NativeMap {
// Lifecycle API
//
- void update();
-
void resizeView(int width, int height);
void onLowMemory();
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
index 10942d521c..a5f8be788c 100755
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
@@ -136,15 +136,6 @@ final class NativeMapView implements NativeMap {
}
@Override
- public void update() {
- if (checkState("update")) {
- return;
- }
-
- mapRenderer.requestRender();
- }
-
- @Override
public void resizeView(int width, int height) {
if (checkState("resizeView")) {
return;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Style.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Style.java
index f14e034816..5c28b55de8 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Style.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Style.java
@@ -100,8 +100,8 @@ public class Style {
*/
public void addSource(@NonNull Source source) {
validateState("addSource");
- sources.put(source.getId(), source);
nativeMap.addSource(source);
+ sources.put(source.getId(), source);
}
/**
@@ -172,8 +172,8 @@ public class Style {
*/
public void addLayer(@NonNull Layer layer) {
validateState("addLayer");
- layers.put(layer.getId(), layer);
nativeMap.addLayer(layer);
+ layers.put(layer.getId(), layer);
}
/**
@@ -184,8 +184,8 @@ public class Style {
*/
public void addLayerBelow(@NonNull Layer layer, @NonNull String below) {
validateState("addLayerBelow");
- layers.put(layer.getId(), layer);
nativeMap.addLayerBelow(layer, below);
+ layers.put(layer.getId(), layer);
}
/**
@@ -196,8 +196,8 @@ public class Style {
*/
public void addLayerAbove(@NonNull Layer layer, @NonNull String above) {
validateState("addLayerAbove");
- layers.put(layer.getId(), layer);
nativeMap.addLayerAbove(layer, above);
+ layers.put(layer.getId(), layer);
}
/**
@@ -209,8 +209,8 @@ public class Style {
*/
public void addLayerAt(@NonNull Layer layer, @IntRange(from = 0) int index) {
validateState("addLayerAbove");
- layers.put(layer.getId(), layer);
nativeMap.addLayerAt(layer, index);
+ layers.put(layer.getId(), layer);
}
/**
@@ -437,10 +437,11 @@ public class Style {
//
/**
- * Called when the underlying map will start loading a new style. This method will clean up this style
- * by setting the java sources and layers in a detached state and removing them from core.
+ * Called when the underlying map will start loading a new style or the map is destroyed.
+ * This method will clean up this style by setting the java sources and layers
+ * in a detached state and removing them from core.
*/
- void onWillStartLoadingMap() {
+ void clear() {
fullyLoaded = false;
for (Source source : sources.values()) {
if (source != null) {
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java
index 034dc63c35..c671146876 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java
@@ -10,6 +10,7 @@ import android.os.Bundle;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.annotation.Px;
import android.support.annotation.UiThread;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.res.ResourcesCompat;
@@ -344,7 +345,7 @@ public final class UiSettings {
}
/**
- * Sets the margins of the compass view. Use this to change the distance of the compass from the
+ * Sets the margins of the compass view in pixels. Use this to change the distance of the compass from the
* map view edge.
*
* @param left The left margin in pixels.
@@ -353,42 +354,46 @@ public final class UiSettings {
* @param bottom The bottom margin in pixels.
*/
@UiThread
- public void setCompassMargins(int left, int top, int right, int bottom) {
+ public void setCompassMargins(@Px int left, @Px int top, @Px int right, @Px int bottom) {
setWidgetMargins(compassView, compassMargins, left, top, right, bottom);
}
/**
- * Returns the left side margin of CompassView
+ * Returns the left side margin of CompassView in pixels.
*
* @return The left margin in pixels
*/
+ @Px
public int getCompassMarginLeft() {
return compassMargins[0];
}
/**
- * Returns the top side margin of CompassView
+ * Returns the top side margin of CompassView in pixels.
*
* @return The top margin in pixels
*/
+ @Px
public int getCompassMarginTop() {
return compassMargins[1];
}
/**
- * Returns the right side margin of CompassView
+ * Returns the right side margin of CompassView in pixels.
*
* @return The right margin in pixels
*/
+ @Px
public int getCompassMarginRight() {
return compassMargins[2];
}
/**
- * Returns the bottom side margin of CompassView
+ * Returns the bottom side margin of CompassView in pixels.
*
* @return The bottom margin in pixels
*/
+ @Px
public int getCompassMarginBottom() {
return compassMargins[3];
}
@@ -456,7 +461,7 @@ public final class UiSettings {
}
/**
- * Sets the margins of the logo view. Use this to change the distance of the Mapbox logo from the
+ * Sets the margins of the logo view in pixels. Use this to change the distance of the Mapbox logo from the
* map view edge.
*
* @param left The left margin in pixels.
@@ -464,42 +469,46 @@ public final class UiSettings {
* @param right The right margin in pixels.
* @param bottom The bottom margin in pixels.
*/
- public void setLogoMargins(int left, int top, int right, int bottom) {
+ public void setLogoMargins(@Px int left, @Px int top, @Px int right, @Px int bottom) {
setWidgetMargins(logoView, logoMargins, left, top, right, bottom);
}
/**
- * Returns the left side margin of the logo
+ * Returns the left side margin of the logo in pixels.
*
* @return The left margin in pixels
*/
+ @Px
public int getLogoMarginLeft() {
return logoMargins[0];
}
/**
- * Returns the top side margin of the logo
+ * Returns the top side margin of the logo in pixels.
*
* @return The top margin in pixels
*/
+ @Px
public int getLogoMarginTop() {
return logoMargins[1];
}
/**
- * Returns the right side margin of the logo
+ * Returns the right side margin of the logo in pixels.
*
* @return The right margin in pixels
*/
+ @Px
public int getLogoMarginRight() {
return logoMargins[2];
}
/**
- * Returns the bottom side margin of the logo
+ * Returns the bottom side margin of the logo in pixels.
*
* @return The bottom margin in pixels
*/
+ @Px
public int getLogoMarginBottom() {
return logoMargins[3];
}
@@ -570,14 +579,14 @@ public final class UiSettings {
}
/**
- * Sets the margins of the attribution view.
+ * Sets the margins of the attribution view in pixels.
*
* @param left The left margin in pixels.
* @param top The top margin in pixels.
* @param right The right margin in pixels.
* @param bottom The bottom margin in pixels.
*/
- public void setAttributionMargins(int left, int top, int right, int bottom) {
+ public void setAttributionMargins(@Px int left, @Px int top, @Px int right, @Px int bottom) {
setWidgetMargins(attributionsView, attributionsMargins, left, top, right, bottom);
}
@@ -599,37 +608,41 @@ public final class UiSettings {
}
/**
- * Returns the left side margin of the attribution view.
+ * Returns the left side margin of the attribution view in pixels.
*
* @return The left margin in pixels
*/
+ @Px
public int getAttributionMarginLeft() {
return attributionsMargins[0];
}
/**
- * Returns the top side margin of the attribution view.
+ * Returns the top side margin of the attribution view in pixels.
*
* @return The top margin in pixels
*/
+ @Px
public int getAttributionMarginTop() {
return attributionsMargins[1];
}
/**
- * Returns the right side margin of the attribution view.
+ * Returns the right side margin of the attribution view in pixels.
*
* @return The right margin in pixels
*/
+ @Px
public int getAttributionMarginRight() {
return attributionsMargins[2];
}
/**
- * Returns the bottom side margin of the logo
+ * Returns the bottom side margin of the logo in pixels.
*
* @return The bottom margin in pixels
*/
+ @Px
public int getAttributionMarginBottom() {
return attributionsMargins[3];
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/glsurfaceview/GLSurfaceViewMapRenderer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/glsurfaceview/GLSurfaceViewMapRenderer.java
index 9d9a7bd2d4..524c1a62ee 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/glsurfaceview/GLSurfaceViewMapRenderer.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/glsurfaceview/GLSurfaceViewMapRenderer.java
@@ -2,10 +2,8 @@ package com.mapbox.mapboxsdk.maps.renderer.glsurfaceview;
import android.content.Context;
import android.opengl.GLSurfaceView;
-
import android.support.annotation.NonNull;
import android.view.SurfaceHolder;
-
import com.mapbox.mapboxsdk.maps.renderer.MapRenderer;
import com.mapbox.mapboxsdk.maps.renderer.egl.EGLConfigChooser;
@@ -25,8 +23,6 @@ public class GLSurfaceViewMapRenderer extends MapRenderer implements GLSurfaceVi
@NonNull
private final GLSurfaceView glSurfaceView;
- private boolean requestDestroy;
-
public GLSurfaceViewMapRenderer(Context context,
GLSurfaceView glSurfaceView,
String localIdeographFontFamily) {
@@ -42,9 +38,8 @@ public class GLSurfaceViewMapRenderer extends MapRenderer implements GLSurfaceVi
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
- requestDestroy = true;
+ onSurfaceDestroyed();
}
-
});
}
@@ -60,9 +55,6 @@ public class GLSurfaceViewMapRenderer extends MapRenderer implements GLSurfaceVi
@Override
public void onDestroy() {
- if (requestDestroy) {
- onSurfaceDestroyed();
- }
super.onDestroy();
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/textureview/TextureViewRenderThread.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/textureview/TextureViewRenderThread.java
index 96d5e9e943..165b15a512 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/textureview/TextureViewRenderThread.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/textureview/TextureViewRenderThread.java
@@ -197,7 +197,6 @@ class TextureViewRenderThread extends Thread implements TextureView.SurfaceTextu
if (destroySurface) {
eglHolder.destroySurface();
destroySurface = false;
- mapRenderer.onSurfaceDestroyed();
break;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java
index 6262418a29..53c0c1c60f 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java
@@ -7,10 +7,10 @@ import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPropertyAnimatorCompat;
import android.support.v4.view.ViewPropertyAnimatorListenerAdapter;
-import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ImageView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
@@ -23,7 +23,7 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
* use {@link com.mapbox.mapboxsdk.maps.UiSettings}.
* </p>
*/
-public final class CompassView extends AppCompatImageView implements Runnable {
+public final class CompassView extends ImageView implements Runnable {
public static final long TIME_WAIT_IDLE = 500;
public static final long TIME_MAP_NORTH_ANIMATION = 150;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/PerformanceEvent.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/PerformanceEvent.java
index b88e1885ca..12d1fe46cf 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/PerformanceEvent.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/PerformanceEvent.java
@@ -1,20 +1,55 @@
package com.mapbox.mapboxsdk.module.telemetry;
+import com.google.gson.Gson;
+
+import com.google.gson.JsonObject;
+
+import com.google.gson.reflect.TypeToken;
import com.mapbox.android.telemetry.Event;
import android.os.Bundle;
import android.os.Parcel;
+
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Date;
+import java.util.List;
import java.util.Locale;
/**
* Generic Performance Event that can be used for performance measurements.
* Customer measurements can be added to the bundle.
+ *
+ * Bundle is expected to have following properties:
+ * "attributes", "counters", and "metadata" with String values.
+ *
+ * Attributes: a string representing an array of name/string value pair objects.
+ * Counters: a string representing an array of name/number value pair objects.
+ * Metadata is a string representation of a JsonObject with string values.
+ *
+ * Here is an example of a Performance event bundle data:
+ *
+ * "attributes": [{ "name": "style_id", "value": "mapbox://styles/mapbox/streets-v10"}]
+ *
+ * "counters": [{"name": "fps_average", "value": 90.7655486547093},
+ * {"name": "fps_deviation", "value": 29.301809631465574}]
+ * “metadata”: {
+ * “version”: “9”,
+ * “screenSize”: “1080x1794”,
+ * “country”: “US”,
+ * “device”: “Pixel 2”,
+ * “abi”: “arm64-v8a”,
+ * “brand”: “google”,
+ * “ram”: “3834167296”,
+ * “os”: “android”,
+ * “gpu”: “Qualcomm, Adreno (TM) 540, OpenGL ES 3.2 V@313.0 (GIT@7bf2852, Ie32bfa6f6f)“,
+ * “manufacturer”: “Google”
+ * }
*/
public class PerformanceEvent extends Event {
- private static final String PERFORMANCE_TRACE = "performance.trace";
+
+ private static final String PERFORMANCE_TRACE = "mobile.performance_trace";
private final String event;
@@ -22,23 +57,36 @@ public class PerformanceEvent extends Event {
private final String sessionId;
- private final Bundle data;
+ private final List<Attribute<String>> attributes;
+
+ private final List<Attribute<Double>> counters;
+
+ private final JsonObject metadata;
+
private static final SimpleDateFormat DATE_FORMAT =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US);
- PerformanceEvent(String sessionId, Bundle data) {
+ PerformanceEvent(String sessionId, Bundle bundle) {
+
this.event = PERFORMANCE_TRACE;
this.created = DATE_FORMAT.format(new Date());
this.sessionId = sessionId;
- this.data = data;
+ this.attributes = initList(bundle.getString("attributes"),
+ new TypeToken<ArrayList<Attribute<String>>>() {});
+ this.counters = initList(bundle.getString("counters"),
+ new TypeToken<ArrayList<Attribute<Double>>>() {});
+ this.metadata = initMetaData(bundle.getString("metadata"));
}
private PerformanceEvent(Parcel in) {
this.event = in.readString();
this.created = in.readString();
this.sessionId = in.readString();
- this.data = in.readBundle();
+
+ this.attributes = initList(in.readString(), new TypeToken<ArrayList<Attribute<String>>>() {});
+ this.counters = initList(in.readString(), new TypeToken<ArrayList<Attribute<Double>>>() {});
+ this.metadata = initMetaData(in.readString());
}
@Override
@@ -51,7 +99,30 @@ public class PerformanceEvent extends Event {
parcel.writeString(event);
parcel.writeString(created);
parcel.writeString(sessionId);
- parcel.writeBundle(data);
+
+ Gson gson = new Gson();
+
+ parcel.writeString(gson.toJson(attributes));
+ parcel.writeString(gson.toJson(counters));
+
+ if (metadata != null) {
+ parcel.writeString(metadata.toString());
+ }
+ }
+
+ private <T> ArrayList<Attribute<T>> initList(String fromString, TypeToken typeToken) {
+ if (fromString == null || fromString.isEmpty()) {
+ return new ArrayList<>();
+ }
+ return new Gson().fromJson(fromString, typeToken.getType());
+ }
+
+ private JsonObject initMetaData(String fromString) {
+ if (fromString == null) {
+ return new JsonObject();
+ } else {
+ return new Gson().fromJson(fromString, JsonObject.class);
+ }
}
public static final Creator<PerformanceEvent> CREATOR = new Creator<PerformanceEvent>() {
@@ -65,4 +136,15 @@ public class PerformanceEvent extends Event {
return new PerformanceEvent[size];
}
};
+
+
+ private class Attribute<T> {
+ private final String name;
+ private final T value;
+
+ Attribute(String name, T value) {
+ this.name = name;
+ this.value = value;
+ }
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/TelemetryImpl.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/TelemetryImpl.java
index 5e021f961e..697a51286f 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/TelemetryImpl.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/TelemetryImpl.java
@@ -111,8 +111,9 @@ public class TelemetryImpl implements TelemetryDefinition {
@Override
public void onPerformanceEvent(Bundle data) {
- if (data != null && !data.isEmpty()) {
- telemetry.push(new PerformanceEvent(UUID.randomUUID().toString(), data));
+ if (data == null) {
+ data = new Bundle();
}
+ telemetry.push(new PerformanceEvent(UUID.randomUUID().toString(), data));
}
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java
index 01ac098d16..8684d7c6f1 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java
@@ -26,7 +26,11 @@ import java.nio.channels.FileChannel;
/**
* The offline manager is the main entry point for offline-related functionality.
+ * <p>
* It'll help you list and create offline regions.
+ * </p>
+ *
+ * @see <a href="https://docs.mapbox.com/help/troubleshooting/mobile-offline/">Offline Maps Information/</a>
*/
public class OfflineManager {
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java
index 1c87b9004b..57cf6271c9 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java
@@ -323,6 +323,10 @@ public final class Property {
// TEXT_JUSTIFY: Text justification options.
/**
+ * The text is aligned towards the anchor position.
+ */
+ public static final String TEXT_JUSTIFY_AUTO = "auto";
+ /**
* The text is aligned to the left.
*/
public static final String TEXT_JUSTIFY_LEFT = "left";
@@ -339,6 +343,7 @@ public final class Property {
* Text justification options.
*/
@StringDef({
+ TEXT_JUSTIFY_AUTO,
TEXT_JUSTIFY_LEFT,
TEXT_JUSTIFY_CENTER,
TEXT_JUSTIFY_RIGHT,
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java
index 3d8b921a79..01908b1b0b 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java
@@ -2276,6 +2276,46 @@ public class PropertyFactory {
}
/**
+ * Radial offset of text, in the direction of the symbol's anchor. Useful in combination with {@link PropertyFactory#textVariableAnchor}, which doesn't support the two-dimensional {@link PropertyFactory#textOffset}.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static PropertyValue<Float> textRadialOffset(Float value) {
+ return new LayoutPropertyValue<>("text-radial-offset", value);
+ }
+
+ /**
+ * Radial offset of text, in the direction of the symbol's anchor. Useful in combination with {@link PropertyFactory#textVariableAnchor}, which doesn't support the two-dimensional {@link PropertyFactory#textOffset}.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static PropertyValue<Expression> textRadialOffset(Expression value) {
+ return new LayoutPropertyValue<>("text-radial-offset", value);
+ }
+
+ /**
+ * To increase the chance of placing high-priority labels on the map, you can provide an array of {@link Property.TEXT_ANCHOR} locations: the render will attempt to place the label at each location, in order, before moving onto the next label. Use `text-justify: auto` to choose justification based on anchor position. To apply an offset, use the {@link PropertyFactory#textRadialOffset} instead of the two-dimensional {@link PropertyFactory#textOffset}.
+ *
+ * @param value a String[] value
+ * @return property wrapper around String[]
+ */
+ public static PropertyValue<String[]> textVariableAnchor(String[] value) {
+ return new LayoutPropertyValue<>("text-variable-anchor", value);
+ }
+
+ /**
+ * To increase the chance of placing high-priority labels on the map, you can provide an array of {@link Property.TEXT_ANCHOR} locations: the render will attempt to place the label at each location, in order, before moving onto the next label. Use `text-justify: auto` to choose justification based on anchor position. To apply an offset, use the {@link PropertyFactory#textRadialOffset} instead of the two-dimensional {@link PropertyFactory#textOffset}.
+ *
+ * @param value a String[] value
+ * @return property wrapper around String[]
+ */
+ public static PropertyValue<Expression> textVariableAnchor(Expression value) {
+ return new LayoutPropertyValue<>("text-variable-anchor", value);
+ }
+
+ /**
* Part of the text placed closest to the anchor.
*
* @param value a String value
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java
index ab45cb04f2..75473f0f30 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java
@@ -470,6 +470,30 @@ public class SymbolLayer extends Layer {
}
/**
+ * Get the TextRadialOffset property
+ *
+ * @return property wrapper value around Float
+ */
+ @NonNull
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getTextRadialOffset() {
+ checkThread();
+ return (PropertyValue<Float>) new PropertyValue("text-radial-offset", nativeGetTextRadialOffset());
+ }
+
+ /**
+ * Get the TextVariableAnchor property
+ *
+ * @return property wrapper value around String[]
+ */
+ @NonNull
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String[]> getTextVariableAnchor() {
+ checkThread();
+ return (PropertyValue<String[]>) new PropertyValue("text-variable-anchor", nativeGetTextVariableAnchor());
+ }
+
+ /**
* Get the TextAnchor property
*
* @return property wrapper value around String
@@ -1187,6 +1211,14 @@ public class SymbolLayer extends Layer {
@NonNull
@Keep
+ private native Object nativeGetTextRadialOffset();
+
+ @NonNull
+ @Keep
+ private native Object nativeGetTextVariableAnchor();
+
+ @NonNull
+ @Keep
private native Object nativeGetTextAnchor();
@NonNull
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/Formatted.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/Formatted.java
index fb2d361bfc..b76e4f4417 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/Formatted.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/Formatted.java
@@ -58,4 +58,12 @@ public class Formatted {
public int hashCode() {
return Arrays.hashCode(formattedSections);
}
+
+ @Override
+ public String toString() {
+ return "Formatted{"
+ + "formattedSections="
+ + Arrays.toString(formattedSections)
+ + '}';
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/FormattedSection.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/FormattedSection.java
index a5b0dfbfe8..859fcff378 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/FormattedSection.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/FormattedSection.java
@@ -228,4 +228,14 @@ public class FormattedSection {
params.put("text-color", textColor);
return new Object[] {text, params};
}
+
+ @Override
+ public String toString() {
+ return "FormattedSection{"
+ + "text='" + text + '\''
+ + ", fontScale=" + fontScale
+ + ", fontStack=" + Arrays.toString(fontStack)
+ + ", textColor='" + textColor + '\''
+ + '}';
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/BitmapUtils.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/BitmapUtils.java
index 3ef8e93cae..3570aa2c0b 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/BitmapUtils.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/BitmapUtils.java
@@ -13,7 +13,6 @@ import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
-import android.support.v7.content.res.AppCompatResources;
import android.view.View;
import java.io.ByteArrayOutputStream;
@@ -152,7 +151,7 @@ public class BitmapUtils {
@Nullable
public static Drawable getDrawableFromRes(@NonNull Context context, @DrawableRes int drawableRes,
@Nullable @ColorInt Integer tintColor) {
- Drawable drawable = AppCompatResources.getDrawable(context, drawableRes);
+ Drawable drawable = context.getResources().getDrawable(drawableRes);
if (drawable == null) {
return null;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_internal.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_internal.xml
index 1adbe7e769..e5cde7e441 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_internal.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_internal.xml
@@ -7,14 +7,14 @@
android:layout_height="wrap_content"
android:contentDescription="@string/mapbox_compassContentDescription"/>
- <android.support.v7.widget.AppCompatImageView
+ <ImageView
android:visibility="gone"
android:id="@+id/logoView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"/>
- <android.support.v7.widget.AppCompatImageView
+ <ImageView
android:visibility="gone"
android:id="@+id/attributionView"
android:layout_width="wrap_content"
diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngTest.java
index 8e47f069c3..862c56a526 100644
--- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngTest.java
+++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngTest.java
@@ -175,7 +175,7 @@ public class LatLngTest {
LatLng latLng2 = new LatLng(1.0, 1.0);
assertEquals("distances should match",
latLng1.distanceTo(latLng2),
- 157425.53710839353, DELTA);
+ 157298.7453847275, DELTA);
}
@Test
@@ -186,6 +186,15 @@ public class LatLngTest {
assertEquals("distance should match", 0.0, distance, DELTA);
}
+ // Regression test for #14216
+ @Test
+ public void testDistanceToClosePointNotNaN() {
+ LatLng latLng = new LatLng(40.00599, -105.29261);
+ LatLng other = new LatLng(40.005990000000025, -105.29260999999997);
+ double distance = latLng.distanceTo(other);
+ assertNotEquals(distance, Double.NaN);
+ }
+
@Test
public void testLocationProvider() {
double latitude = 1.2;
diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationCameraControllerTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationCameraControllerTest.java
index 56a8f276a7..a3d54fe221 100644
--- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationCameraControllerTest.java
+++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationCameraControllerTest.java
@@ -408,6 +408,7 @@ public class LocationCameraControllerTest {
MapboxMap mapboxMap = mock(MapboxMap.class);
AndroidGesturesManager initialGesturesManager = mock(AndroidGesturesManager.class);
AndroidGesturesManager internalGesturesManager = mock(AndroidGesturesManager.class);
+ when(mapboxMap.getGesturesManager()).thenReturn(initialGesturesManager);
LocationCameraController camera = buildCamera(mapboxMap, initialGesturesManager, internalGesturesManager);
LocationComponentOptions options = mock(LocationComponentOptions.class);
when(options.trackingGesturesManagement()).thenReturn(true);
@@ -421,6 +422,7 @@ public class LocationCameraControllerTest {
MapboxMap mapboxMap = mock(MapboxMap.class);
AndroidGesturesManager initialGesturesManager = mock(AndroidGesturesManager.class);
AndroidGesturesManager internalGesturesManager = mock(AndroidGesturesManager.class);
+ when(mapboxMap.getGesturesManager()).thenReturn(internalGesturesManager);
LocationCameraController camera = buildCamera(mapboxMap, initialGesturesManager, internalGesturesManager);
LocationComponentOptions options = mock(LocationComponentOptions.class);
when(options.trackingGesturesManagement()).thenReturn(false);
@@ -430,6 +432,34 @@ public class LocationCameraControllerTest {
}
@Test
+ public void gesturesManagement_optionNotChangedInitial() {
+ MapboxMap mapboxMap = mock(MapboxMap.class);
+ AndroidGesturesManager initialGesturesManager = mock(AndroidGesturesManager.class);
+ AndroidGesturesManager internalGesturesManager = mock(AndroidGesturesManager.class);
+ when(mapboxMap.getGesturesManager()).thenReturn(initialGesturesManager);
+ LocationCameraController camera = buildCamera(mapboxMap, initialGesturesManager, internalGesturesManager);
+ LocationComponentOptions options = mock(LocationComponentOptions.class);
+ when(options.trackingGesturesManagement()).thenReturn(false);
+ camera.initializeOptions(options);
+
+ verify(mapboxMap, times(0)).setGesturesManager(initialGesturesManager, true, true);
+ }
+
+ @Test
+ public void gesturesManagement_optionNotChangedInternal() {
+ MapboxMap mapboxMap = mock(MapboxMap.class);
+ AndroidGesturesManager initialGesturesManager = mock(AndroidGesturesManager.class);
+ AndroidGesturesManager internalGesturesManager = mock(AndroidGesturesManager.class);
+ when(mapboxMap.getGesturesManager()).thenReturn(internalGesturesManager);
+ LocationCameraController camera = buildCamera(mapboxMap, initialGesturesManager, internalGesturesManager);
+ LocationComponentOptions options = mock(LocationComponentOptions.class);
+ when(options.trackingGesturesManagement()).thenReturn(true);
+ camera.initializeOptions(options);
+
+ verify(mapboxMap, times(0)).setGesturesManager(internalGesturesManager, true, true);
+ }
+
+ @Test
public void onMove_notCancellingTransitionWhileNone() {
MapboxMap mapboxMap = mock(MapboxMap.class);
when(mapboxMap.getUiSettings()).thenReturn(mock(UiSettings.class));
diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.java
index 10553700b3..6a44cf1f79 100644
--- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.java
+++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.java
@@ -39,6 +39,7 @@ import static com.mapbox.mapboxsdk.location.MapboxAnimator.ANIMATOR_LAYER_ACCURA
import static com.mapbox.mapboxsdk.location.MapboxAnimator.ANIMATOR_LAYER_COMPASS_BEARING;
import static com.mapbox.mapboxsdk.location.MapboxAnimator.ANIMATOR_LAYER_GPS_BEARING;
import static com.mapbox.mapboxsdk.location.MapboxAnimator.ANIMATOR_LAYER_LATLNG;
+import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
@@ -160,6 +161,24 @@ public class LocationLayerControllerTest {
}
@Test
+ public void onInitialization_numberOfCachedLayerIdsIsConstant() {
+ OnRenderModeChangedListener internalRenderModeChangedListener = mock(OnRenderModeChangedListener.class);
+ LayerSourceProvider sourceProvider = buildLayerProvider();
+ GeoJsonSource locationSource = mock(GeoJsonSource.class);
+ when(sourceProvider.generateSource(any(Feature.class))).thenReturn(locationSource);
+ LayerBitmapProvider bitmapProvider = mock(LayerBitmapProvider.class);
+ LocationComponentOptions options = mock(LocationComponentOptions.class);
+
+ LocationLayerController controller =
+ new LocationLayerController(mapboxMap, mapboxMap.getStyle(), sourceProvider, buildFeatureProvider(options),
+ bitmapProvider, options, internalRenderModeChangedListener);
+
+ controller.initializeComponents(mapboxMap.getStyle(), options);
+
+ assertEquals(5, controller.layerSet.size());
+ }
+
+ @Test
public void applyStyle_styleShadowWithValidElevation() {
OnRenderModeChangedListener internalRenderModeChangedListener = mock(OnRenderModeChangedListener.class);
LayerSourceProvider sourceProvider = buildLayerProvider();
@@ -300,22 +319,6 @@ public class LocationLayerControllerTest {
LayerSourceProvider sourceProvider = buildLayerProvider();
when(sourceProvider.generateSource(any(Feature.class))).thenReturn(mock(GeoJsonSource.class));
- Layer bearingLayer = mock(Layer.class);
- when(bearingLayer.getId()).thenReturn(BEARING_LAYER);
- when(sourceProvider.generateLayer(BEARING_LAYER)).thenReturn(bearingLayer);
- Layer foregroundLayer = mock(Layer.class);
- when(foregroundLayer.getId()).thenReturn(FOREGROUND_LAYER);
- when(sourceProvider.generateLayer(FOREGROUND_LAYER)).thenReturn(foregroundLayer);
- Layer backgroundLayer = mock(Layer.class);
- when(backgroundLayer.getId()).thenReturn(BACKGROUND_LAYER);
- when(sourceProvider.generateLayer(BACKGROUND_LAYER)).thenReturn(backgroundLayer);
- Layer shadowLayer = mock(Layer.class);
- when(shadowLayer.getId()).thenReturn(SHADOW_LAYER);
- when(sourceProvider.generateLayer(SHADOW_LAYER)).thenReturn(shadowLayer);
- Layer accuracyLayer = mock(Layer.class);
- when(accuracyLayer.getId()).thenReturn(ACCURACY_LAYER);
- when(sourceProvider.generateAccuracyLayer()).thenReturn(accuracyLayer);
-
LocationComponentOptions options = mock(LocationComponentOptions.class);
LayerBitmapProvider bitmapProvider = mock(LayerBitmapProvider.class);
Bitmap bitmap = mock(Bitmap.class);
@@ -606,18 +609,23 @@ public class LocationLayerControllerTest {
LayerSourceProvider layerSourceProvider = mock(LayerSourceProvider.class);
Layer shadowLayer = mock(Layer.class);
+ when(shadowLayer.getId()).thenReturn(SHADOW_LAYER);
when(layerSourceProvider.generateLayer(SHADOW_LAYER)).thenReturn(shadowLayer);
Layer backgroundLayer = mock(Layer.class);
+ when(backgroundLayer.getId()).thenReturn(BACKGROUND_LAYER);
when(layerSourceProvider.generateLayer(BACKGROUND_LAYER)).thenReturn(backgroundLayer);
Layer foregroundLayer = mock(Layer.class);
+ when(foregroundLayer.getId()).thenReturn(FOREGROUND_LAYER);
when(layerSourceProvider.generateLayer(FOREGROUND_LAYER)).thenReturn(foregroundLayer);
Layer bearingLayer = mock(Layer.class);
+ when(bearingLayer.getId()).thenReturn(BEARING_LAYER);
when(layerSourceProvider.generateLayer(BEARING_LAYER)).thenReturn(bearingLayer);
Layer accuracyLayer = mock(Layer.class);
+ when(accuracyLayer.getId()).thenReturn(ACCURACY_LAYER);
when(layerSourceProvider.generateAccuracyLayer()).thenReturn(accuracyLayer);
return layerSourceProvider;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.kt b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.kt
index a0873e97ff..2d68612c70 100644
--- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.kt
+++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.kt
@@ -15,31 +15,33 @@ import org.robolectric.RobolectricTestRunner
@RunWith(RobolectricTestRunner::class)
class MapboxMapTest {
- private lateinit var mapboxMap: MapboxMap
-
- private lateinit var nativeMapView: NativeMapView
-
- private lateinit var transform: Transform
-
- @Before
- fun setup() {
- val cameraChangeDispatcher = spyk<CameraChangeDispatcher>()
- nativeMapView = mockk(relaxed = true)
- transform = mockk(relaxed = true)
- mapboxMap = MapboxMap(nativeMapView, transform, mockk(relaxed = true), null, null, cameraChangeDispatcher)
- every { nativeMapView.isDestroyed } returns false
- every { nativeMapView.nativePtr } returns 5
- mapboxMap.injectLocationComponent(spyk())
- mapboxMap.setStyle(Style.MAPBOX_STREETS)
- mapboxMap.onFinishLoadingStyle()
- }
-
- @Test
- fun testTransitionOptions() {
- val expected = TransitionOptions(100, 200)
- mapboxMap.style?.transition = expected
- verify { nativeMapView.transitionOptions = expected }
- }
+ private lateinit var mapboxMap: MapboxMap
+
+ private lateinit var nativeMapView: NativeMapView
+
+ private lateinit var transform: Transform
+
+ private lateinit var cameraChangeDispatcher: CameraChangeDispatcher
+
+ @Before
+ fun setup() {
+ cameraChangeDispatcher = spyk()
+ nativeMapView = mockk(relaxed = true)
+ transform = mockk(relaxed = true)
+ mapboxMap = MapboxMap(nativeMapView, transform, mockk(relaxed = true), null, null, cameraChangeDispatcher)
+ every { nativeMapView.isDestroyed } returns false
+ every { nativeMapView.nativePtr } returns 5
+ mapboxMap.injectLocationComponent(spyk())
+ mapboxMap.setStyle(Style.MAPBOX_STREETS)
+ mapboxMap.onFinishLoadingStyle()
+ }
+
+ @Test
+ fun testTransitionOptions() {
+ val expected = TransitionOptions(100, 200)
+ mapboxMap.style?.transition = expected
+ verify { nativeMapView.transitionOptions = expected }
+ }
@Test
fun testMoveCamera() {
@@ -51,52 +53,52 @@ class MapboxMapTest {
verify { transform.moveCamera(mapboxMap, update, callback) }
}
- @Test
- fun testMinZoom() {
- mapboxMap.setMinZoomPreference(10.0)
- verify { transform.minZoom = 10.0 }
- }
-
- @Test
- fun testMaxZoom() {
- mapboxMap.setMaxZoomPreference(10.0)
- verify { transform.maxZoom = 10.0 }
- }
-
- @Test
- fun testFpsListener() {
- val fpsChangedListener = mockk<MapboxMap.OnFpsChangedListener>()
- mapboxMap.onFpsChangedListener = fpsChangedListener
- assertEquals("Listener should match", fpsChangedListener, mapboxMap.onFpsChangedListener)
- }
-
- @Test
- fun testTilePrefetch() {
- mapboxMap.prefetchesTiles = true
- verify { nativeMapView.prefetchTiles = true }
- }
-
- @Test
- fun testCameraForLatLngBounds() {
- val bounds = LatLngBounds.Builder().include(LatLng()).include(LatLng(1.0, 1.0)).build()
- mapboxMap.setLatLngBoundsForCameraTarget(bounds)
- verify { nativeMapView.setLatLngBounds(bounds) }
- }
-
- @Test(expected = IllegalArgumentException::class)
- fun testAnimateCameraChecksDurationPositive() {
- mapboxMap.animateCamera(CameraUpdateFactory.newLatLng(LatLng(30.0, 30.0)), 0, null)
- }
-
- @Test(expected = IllegalArgumentException::class)
- fun testEaseCameraChecksDurationPositive() {
- mapboxMap.easeCamera(CameraUpdateFactory.newLatLng(LatLng(30.0, 30.0)), 0, null)
- }
-
- @Test
- fun testGetNativeMapPtr() {
- assertEquals(5, mapboxMap.nativeMapPtr)
- }
+ @Test
+ fun testMinZoom() {
+ mapboxMap.setMinZoomPreference(10.0)
+ verify { transform.minZoom = 10.0 }
+ }
+
+ @Test
+ fun testMaxZoom() {
+ mapboxMap.setMaxZoomPreference(10.0)
+ verify { transform.maxZoom = 10.0 }
+ }
+
+ @Test
+ fun testFpsListener() {
+ val fpsChangedListener = mockk<MapboxMap.OnFpsChangedListener>()
+ mapboxMap.onFpsChangedListener = fpsChangedListener
+ assertEquals("Listener should match", fpsChangedListener, mapboxMap.onFpsChangedListener)
+ }
+
+ @Test
+ fun testTilePrefetch() {
+ mapboxMap.prefetchesTiles = true
+ verify { nativeMapView.prefetchTiles = true }
+ }
+
+ @Test
+ fun testCameraForLatLngBounds() {
+ val bounds = LatLngBounds.Builder().include(LatLng()).include(LatLng(1.0, 1.0)).build()
+ mapboxMap.setLatLngBoundsForCameraTarget(bounds)
+ verify { nativeMapView.setLatLngBounds(bounds) }
+ }
+
+ @Test(expected = IllegalArgumentException::class)
+ fun testAnimateCameraChecksDurationPositive() {
+ mapboxMap.animateCamera(CameraUpdateFactory.newLatLng(LatLng(30.0, 30.0)), 0, null)
+ }
+
+ @Test(expected = IllegalArgumentException::class)
+ fun testEaseCameraChecksDurationPositive() {
+ mapboxMap.easeCamera(CameraUpdateFactory.newLatLng(LatLng(30.0, 30.0)), 0, null)
+ }
+
+ @Test
+ fun testGetNativeMapPtr() {
+ assertEquals(5, mapboxMap.nativeMapPtr)
+ }
@Test
fun testNativeMapIsNotCalledOnStateSave() {
@@ -104,4 +106,10 @@ class MapboxMapTest {
mapboxMap.onSaveInstanceState(mockk(relaxed = true))
verify { nativeMapView wasNot Called }
}
+
+ @Test
+ fun testCameraChangeDispatcherCleared() {
+ mapboxMap.onDestroy()
+ verify { cameraChangeDispatcher.onDestroy() }
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
index 22222b0f50..190c279e03 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
+++ b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
@@ -9,7 +9,7 @@ android {
targetSdkVersion androidVersions.targetSdkVersion
versionCode 13
versionName "6.0.0"
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ testInstrumentationRunner "com.mapbox.mapboxsdk.InstrumentationRunner"
}
compileOptions {
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/assets/streets.json b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/assets/streets.json
new file mode 100644
index 0000000000..5ab289344a
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/assets/streets.json
@@ -0,0 +1,5331 @@
+{
+ "version": 8,
+ "name": "mapbox-gl-native-test-style",
+ "metadata": {
+ "mapbox:autocomposite": true,
+ "mapbox:type": "default",
+ "mapbox:origin": "streets-v10",
+ "mapbox:groups": {
+ "1444934828655.3389": {"name": "Aeroways", "collapsed": true},
+ "1444933322393.2852": {
+ "name": "POI labels (scalerank 1)",
+ "collapsed": true
+ },
+ "1444855786460.0557": {"name": "Roads", "collapsed": true},
+ "1444933575858.6992": {
+ "name": "Highway shields",
+ "collapsed": true
+ },
+ "1444934295202.7542": {
+ "name": "Admin boundaries",
+ "collapsed": true
+ },
+ "1444856151690.9143": {"name": "State labels", "collapsed": true},
+ "1444933721429.3076": {"name": "Road labels", "collapsed": true},
+ "1444933358918.2366": {
+ "name": "POI labels (scalerank 2)",
+ "collapsed": true
+ },
+ "1444933808272.805": {"name": "Water labels", "collapsed": true},
+ "1444933372896.5967": {
+ "name": "POI labels (scalerank 3)",
+ "collapsed": true
+ },
+ "1444855799204.86": {"name": "Bridges", "collapsed": true},
+ "1444856087950.3635": {"name": "Marine labels", "collapsed": true},
+ "1456969573402.7817": {"name": "Hillshading", "collapsed": true},
+ "1444862510685.128": {"name": "City labels", "collapsed": true},
+ "1444855769305.6016": {"name": "Tunnels", "collapsed": true},
+ "1456970288113.8113": {"name": "Landcover", "collapsed": true},
+ "1444856144497.7825": {"name": "Country labels", "collapsed": true},
+ "1444933456003.5437": {
+ "name": "POI labels (scalerank 4)",
+ "collapsed": true
+ }
+ },
+ "mapbox:sdk-support": {
+ "js": "0.49.0",
+ "android": "6.5.0",
+ "ios": "4.4.0"
+ }
+ },
+ "center": [0.0, 0.0],
+ "zoom": 0,
+ "bearing": 0,
+ "pitch": 0,
+ "sources": {
+ "composite": {
+ "url": "mapbox://mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v7",
+ "type": "vector"
+ }
+ },
+ "sprite": "mapbox://sprites/lukaspaczos/cjnkdt02b0b2p2ss40skwpvs1",
+ "glyphs": "mapbox://fonts/lukaspaczos/{fontstack}/{range}.pbf",
+ "layers": [
+ {
+ "id": "background",
+ "type": "background",
+ "layout": {},
+ "paint": {
+ "background-color": {
+ "base": 1,
+ "stops": [
+ [11, "hsl(35, 32%, 91%)"],
+ [13, "hsl(35, 12%, 89%)"]
+ ]
+ }
+ }
+ },
+ {
+ "id": "landcover_snow",
+ "type": "fill",
+ "metadata": {"mapbox:group": "1456970288113.8113"},
+ "source": "composite",
+ "source-layer": "landcover",
+ "filter": ["==", "class", "snow"],
+ "layout": {},
+ "paint": {
+ "fill-color": "hsl(0, 0%, 100%)",
+ "fill-opacity": 0.2,
+ "fill-antialias": false
+ }
+ },
+ {
+ "id": "landcover_wood",
+ "type": "fill",
+ "metadata": {"mapbox:group": "1456970288113.8113"},
+ "source": "composite",
+ "source-layer": "landcover",
+ "maxzoom": 14,
+ "filter": ["==", "class", "wood"],
+ "layout": {},
+ "paint": {
+ "fill-color": "hsl(75, 62%, 81%)",
+ "fill-opacity": {"base": 1.5, "stops": [[2, 0.3], [7, 0]]},
+ "fill-antialias": false
+ }
+ },
+ {
+ "id": "landcover_scrub",
+ "type": "fill",
+ "metadata": {"mapbox:group": "1456970288113.8113"},
+ "source": "composite",
+ "source-layer": "landcover",
+ "maxzoom": 14,
+ "filter": ["==", "class", "scrub"],
+ "layout": {},
+ "paint": {
+ "fill-color": "hsl(75, 62%, 81%)",
+ "fill-opacity": {"base": 1.5, "stops": [[2, 0.3], [7, 0]]},
+ "fill-antialias": false
+ }
+ },
+ {
+ "id": "landcover_grass",
+ "type": "fill",
+ "metadata": {"mapbox:group": "1456970288113.8113"},
+ "source": "composite",
+ "source-layer": "landcover",
+ "maxzoom": 14,
+ "filter": ["==", "class", "grass"],
+ "layout": {},
+ "paint": {
+ "fill-color": "hsl(75, 62%, 81%)",
+ "fill-opacity": {"base": 1.5, "stops": [[2, 0.3], [7, 0]]},
+ "fill-antialias": false
+ }
+ },
+ {
+ "id": "landcover_crop",
+ "type": "fill",
+ "metadata": {"mapbox:group": "1456970288113.8113"},
+ "source": "composite",
+ "source-layer": "landcover",
+ "maxzoom": 14,
+ "filter": ["==", "class", "crop"],
+ "layout": {},
+ "paint": {
+ "fill-color": "hsl(75, 62%, 81%)",
+ "fill-opacity": {"base": 1.5, "stops": [[2, 0.3], [7, 0]]},
+ "fill-antialias": false
+ }
+ },
+ {
+ "id": "national_park",
+ "type": "fill",
+ "source": "composite",
+ "source-layer": "landuse_overlay",
+ "filter": ["==", "class", "national_park"],
+ "layout": {},
+ "paint": {
+ "fill-color": "hsl(100, 58%, 76%)",
+ "fill-opacity": {"base": 1, "stops": [[5, 0], [6, 0.5]]}
+ }
+ },
+ {
+ "id": "hospital",
+ "type": "fill",
+ "source": "composite",
+ "source-layer": "landuse",
+ "filter": ["==", "class", "hospital"],
+ "layout": {},
+ "paint": {
+ "fill-color": {
+ "base": 1,
+ "stops": [
+ [15.5, "hsl(340, 37%, 87%)"],
+ [16, "hsl(340, 63%, 89%)"]
+ ]
+ }
+ }
+ },
+ {
+ "id": "school",
+ "type": "fill",
+ "source": "composite",
+ "source-layer": "landuse",
+ "filter": ["==", "class", "school"],
+ "layout": {},
+ "paint": {
+ "fill-color": {
+ "base": 1,
+ "stops": [
+ [15.5, "hsl(50, 47%, 81%)"],
+ [16, "hsl(50, 63%, 84%)"]
+ ]
+ }
+ }
+ },
+ {
+ "id": "park",
+ "type": "fill",
+ "source": "composite",
+ "source-layer": "landuse",
+ "filter": ["==", "class", "park"],
+ "layout": {},
+ "paint": {
+ "fill-color": "hsl(100, 58%, 76%)",
+ "fill-opacity": {"base": 1, "stops": [[5, 0], [6, 1]]}
+ }
+ },
+ {
+ "id": "pitch",
+ "type": "fill",
+ "source": "composite",
+ "source-layer": "landuse",
+ "filter": ["==", "class", "pitch"],
+ "layout": {},
+ "paint": {"fill-color": "hsl(100, 57%, 72%)"}
+ },
+ {
+ "id": "pitch-line",
+ "type": "line",
+ "source": "composite",
+ "source-layer": "landuse",
+ "minzoom": 15,
+ "filter": ["==", "class", "pitch"],
+ "layout": {"line-join": "miter"},
+ "paint": {"line-color": "hsl(75, 57%, 84%)"}
+ },
+ {
+ "id": "cemetery",
+ "type": "fill",
+ "source": "composite",
+ "source-layer": "landuse",
+ "filter": ["==", "class", "cemetery"],
+ "layout": {},
+ "paint": {"fill-color": "hsl(75, 37%, 81%)"}
+ },
+ {
+ "id": "industrial",
+ "type": "fill",
+ "source": "composite",
+ "source-layer": "landuse",
+ "filter": ["==", "class", "industrial"],
+ "layout": {},
+ "paint": {
+ "fill-color": {
+ "base": 1,
+ "stops": [
+ [15.5, "hsl(230, 15%, 86%)"],
+ [16, "hsl(230, 29%, 89%)"]
+ ]
+ }
+ }
+ },
+ {
+ "id": "sand",
+ "type": "fill",
+ "source": "composite",
+ "source-layer": "landuse",
+ "filter": ["==", "class", "sand"],
+ "layout": {},
+ "paint": {"fill-color": "hsl(60, 46%, 87%)"}
+ },
+ {
+ "id": "hillshade_highlight_bright",
+ "type": "fill",
+ "metadata": {"mapbox:group": "1456969573402.7817"},
+ "source": "composite",
+ "source-layer": "hillshade",
+ "maxzoom": 16,
+ "filter": ["==", "level", 94],
+ "layout": {},
+ "paint": {
+ "fill-color": "hsl(0, 0%, 100%)",
+ "fill-opacity": {"stops": [[14, 0.12], [16, 0]]},
+ "fill-antialias": false
+ }
+ },
+ {
+ "id": "hillshade_highlight_med",
+ "type": "fill",
+ "metadata": {"mapbox:group": "1456969573402.7817"},
+ "source": "composite",
+ "source-layer": "hillshade",
+ "maxzoom": 16,
+ "filter": ["==", "level", 90],
+ "layout": {},
+ "paint": {
+ "fill-color": "hsl(0, 0%, 100%)",
+ "fill-opacity": {"stops": [[14, 0.12], [16, 0]]},
+ "fill-antialias": false
+ }
+ },
+ {
+ "id": "hillshade_shadow_faint",
+ "type": "fill",
+ "metadata": {"mapbox:group": "1456969573402.7817"},
+ "source": "composite",
+ "source-layer": "hillshade",
+ "maxzoom": 16,
+ "filter": ["==", "level", 89],
+ "layout": {},
+ "paint": {
+ "fill-color": "hsl(56, 59%, 22%)",
+ "fill-opacity": {"stops": [[14, 0.05], [16, 0]]},
+ "fill-antialias": false
+ }
+ },
+ {
+ "id": "hillshade_shadow_med",
+ "type": "fill",
+ "metadata": {"mapbox:group": "1456969573402.7817"},
+ "source": "composite",
+ "source-layer": "hillshade",
+ "maxzoom": 16,
+ "filter": ["==", "level", 78],
+ "layout": {},
+ "paint": {
+ "fill-color": "hsl(56, 59%, 22%)",
+ "fill-opacity": {"stops": [[14, 0.05], [16, 0]]},
+ "fill-antialias": false
+ }
+ },
+ {
+ "id": "hillshade_shadow_dark",
+ "type": "fill",
+ "metadata": {"mapbox:group": "1456969573402.7817"},
+ "source": "composite",
+ "source-layer": "hillshade",
+ "maxzoom": 16,
+ "filter": ["==", "level", 67],
+ "layout": {},
+ "paint": {
+ "fill-color": "hsl(56, 59%, 22%)",
+ "fill-opacity": {"stops": [[14, 0.06], [16, 0]]},
+ "fill-antialias": false
+ }
+ },
+ {
+ "id": "hillshade_shadow_extreme",
+ "type": "fill",
+ "metadata": {"mapbox:group": "1456969573402.7817"},
+ "source": "composite",
+ "source-layer": "hillshade",
+ "maxzoom": 16,
+ "filter": ["==", "level", 56],
+ "layout": {},
+ "paint": {
+ "fill-color": "hsl(56, 59%, 22%)",
+ "fill-opacity": {"stops": [[14, 0.06], [16, 0]]},
+ "fill-antialias": false
+ }
+ },
+ {
+ "id": "waterway-river-canal",
+ "type": "line",
+ "source": "composite",
+ "source-layer": "waterway",
+ "minzoom": 8,
+ "filter": ["in", "class", "canal", "river"],
+ "layout": {
+ "line-cap": {"base": 1, "stops": [[0, "butt"], [11, "round"]]},
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "hsl(205, 87%, 76%)",
+ "line-width": {"base": 1.3, "stops": [[8.5, 0.1], [20, 8]]},
+ "line-opacity": {"base": 1, "stops": [[8, 0], [8.5, 1]]}
+ }
+ },
+ {
+ "id": "waterway-small",
+ "type": "line",
+ "source": "composite",
+ "source-layer": "waterway",
+ "minzoom": 13,
+ "filter": ["!in", "class", "canal", "river"],
+ "layout": {"line-join": "round", "line-cap": "round"},
+ "paint": {
+ "line-color": "hsl(205, 87%, 76%)",
+ "line-width": {"base": 1.35, "stops": [[13.5, 0.1], [20, 3]]},
+ "line-opacity": {"base": 1, "stops": [[13, 0], [13.5, 1]]}
+ }
+ },
+ {
+ "id": "water-shadow",
+ "type": "fill",
+ "source": "composite",
+ "source-layer": "water",
+ "layout": {},
+ "paint": {
+ "fill-color": "hsl(215, 84%, 69%)",
+ "fill-translate": {
+ "base": 1.2,
+ "stops": [[7, [0, 0]], [16, [-1, -1]]]
+ },
+ "fill-translate-anchor": "viewport",
+ "fill-opacity": 1
+ }
+ },
+ {
+ "id": "water",
+ "type": "fill",
+ "source": "composite",
+ "source-layer": "water",
+ "layout": {},
+ "paint": {"fill-color": "hsl(196, 80%, 70%)"}
+ },
+ {
+ "id": "barrier_line-land-polygon",
+ "type": "fill",
+ "source": "composite",
+ "source-layer": "barrier_line",
+ "filter": [
+ "all",
+ ["==", "$type", "Polygon"],
+ ["==", "class", "land"]
+ ],
+ "layout": {},
+ "paint": {"fill-color": "hsl(35, 12%, 89%)"}
+ },
+ {
+ "id": "barrier_line-land-line",
+ "type": "line",
+ "source": "composite",
+ "source-layer": "barrier_line",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ ["==", "class", "land"]
+ ],
+ "layout": {"line-cap": "round"},
+ "paint": {
+ "line-width": {"base": 1.99, "stops": [[14, 0.75], [20, 40]]},
+ "line-color": "hsl(35, 12%, 89%)"
+ }
+ },
+ {
+ "id": "aeroway-polygon",
+ "type": "fill",
+ "metadata": {"mapbox:group": "1444934828655.3389"},
+ "source": "composite",
+ "source-layer": "aeroway",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["!=", "type", "apron"],
+ ["==", "$type", "Polygon"]
+ ],
+ "layout": {},
+ "paint": {
+ "fill-color": {
+ "base": 1,
+ "stops": [
+ [15, "hsl(230, 23%, 82%)"],
+ [16, "hsl(230, 37%, 84%)"]
+ ]
+ },
+ "fill-opacity": {"base": 1, "stops": [[11, 0], [11.5, 1]]}
+ }
+ },
+ {
+ "id": "aeroway-runway",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444934828655.3389"},
+ "source": "composite",
+ "source-layer": "aeroway",
+ "minzoom": 9,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ ["==", "type", "runway"]
+ ],
+ "layout": {},
+ "paint": {
+ "line-color": {
+ "base": 1,
+ "stops": [
+ [15, "hsl(230, 23%, 82%)"],
+ [16, "hsl(230, 37%, 84%)"]
+ ]
+ },
+ "line-width": {"base": 1.5, "stops": [[9, 1], [18, 80]]}
+ }
+ },
+ {
+ "id": "aeroway-taxiway",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444934828655.3389"},
+ "source": "composite",
+ "source-layer": "aeroway",
+ "minzoom": 9,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ ["==", "type", "taxiway"]
+ ],
+ "layout": {},
+ "paint": {
+ "line-color": {
+ "base": 1,
+ "stops": [
+ [15, "hsl(230, 23%, 82%)"],
+ [16, "hsl(230, 37%, 84%)"]
+ ]
+ },
+ "line-width": {"base": 1.5, "stops": [[10, 0.5], [18, 20]]}
+ }
+ },
+ {
+ "id": "building-line",
+ "type": "line",
+ "source": "composite",
+ "source-layer": "building",
+ "minzoom": 15,
+ "filter": [
+ "all",
+ ["!=", "type", "building:part"],
+ ["==", "underground", "false"]
+ ],
+ "layout": {},
+ "paint": {
+ "line-color": "hsl(35, 6%, 79%)",
+ "line-width": {"base": 1.5, "stops": [[15, 0.75], [20, 3]]},
+ "line-opacity": {"base": 1, "stops": [[15.5, 0], [16, 1]]}
+ }
+ },
+ {
+ "id": "building",
+ "type": "fill",
+ "source": "composite",
+ "source-layer": "building",
+ "minzoom": 15,
+ "filter": [
+ "all",
+ ["!=", "type", "building:part"],
+ ["==", "underground", "false"]
+ ],
+ "layout": {},
+ "paint": {
+ "fill-color": {
+ "base": 1,
+ "stops": [
+ [15, "hsl(35, 11%, 88%)"],
+ [16, "hsl(35, 8%, 85%)"]
+ ]
+ },
+ "fill-opacity": {"base": 1, "stops": [[15.5, 0], [16, 1]]},
+ "fill-outline-color": "hsl(35, 6%, 79%)"
+ }
+ },
+ {
+ "id": "tunnel-street-low",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "street"],
+ ["==", "structure", "tunnel"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12.5, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-opacity": {
+ "stops": [[11.5, 0], [12, 1], [14, 1], [14.01, 0]]
+ }
+ }
+ },
+ {
+ "id": "tunnel-street_limited-low",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "street_limited"],
+ ["==", "structure", "tunnel"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12.5, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-opacity": {
+ "stops": [[11.5, 0], [12, 1], [14, 1], [14.01, 0]]
+ }
+ }
+ },
+ {
+ "id": "tunnel-service-link-track-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 14,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!=", "type", "trunk_link"],
+ ["==", "structure", "tunnel"],
+ ["in", "class", "link", "service", "track"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]},
+ "line-color": "hsl(230, 19%, 75%)",
+ "line-gap-width": {"base": 1.5, "stops": [[14, 0.5], [18, 12]]},
+ "line-dasharray": [3, 3]
+ }
+ },
+ {
+ "id": "tunnel-street_limited-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "street_limited"],
+ ["==", "structure", "tunnel"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]},
+ "line-color": "hsl(230, 19%, 75%)",
+ "line-gap-width": {
+ "base": 1.5,
+ "stops": [[13, 0], [14, 2], [18, 18]]
+ },
+ "line-dasharray": [3, 3],
+ "line-opacity": {"base": 1, "stops": [[13.99, 0], [14, 1]]}
+ }
+ },
+ {
+ "id": "tunnel-street-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "street"],
+ ["==", "structure", "tunnel"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]},
+ "line-color": "hsl(230, 19%, 75%)",
+ "line-gap-width": {
+ "base": 1.5,
+ "stops": [[13, 0], [14, 2], [18, 18]]
+ },
+ "line-dasharray": [3, 3],
+ "line-opacity": {"base": 1, "stops": [[13.99, 0], [14, 1]]}
+ }
+ },
+ {
+ "id": "tunnel-secondary-tertiary-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "structure", "tunnel"],
+ ["in", "class", "secondary", "tertiary"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.2, "stops": [[10, 0.75], [18, 2]]},
+ "line-dasharray": [3, 3],
+ "line-gap-width": {
+ "base": 1.5,
+ "stops": [[8.5, 0.5], [10, 0.75], [18, 26]]
+ },
+ "line-color": "hsl(230, 19%, 75%)"
+ }
+ },
+ {
+ "id": "tunnel-primary-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "primary"],
+ ["==", "structure", "tunnel"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[10, 1], [16, 2]]},
+ "line-dasharray": [3, 3],
+ "line-gap-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]},
+ "line-color": "hsl(230, 19%, 75%)"
+ }
+ },
+ {
+ "id": "tunnel-trunk_link-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "structure", "tunnel"],
+ ["==", "type", "trunk_link"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-gap-width": {
+ "base": 1.5,
+ "stops": [[12, 0.5], [14, 2], [18, 18]]
+ },
+ "line-dasharray": [3, 3]
+ }
+ },
+ {
+ "id": "tunnel-motorway_link-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "motorway_link"],
+ ["==", "structure", "tunnel"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-gap-width": {
+ "base": 1.5,
+ "stops": [[12, 0.5], [14, 2], [18, 18]]
+ },
+ "line-dasharray": [3, 3]
+ }
+ },
+ {
+ "id": "tunnel-trunk-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ ["all", ["==", "structure", "tunnel"], ["==", "type", "trunk"]]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[10, 1], [16, 2]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-gap-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]},
+ "line-opacity": 1,
+ "line-dasharray": [3, 3]
+ }
+ },
+ {
+ "id": "tunnel-motorway-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "motorway"],
+ ["==", "structure", "tunnel"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[10, 1], [16, 2]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-gap-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]},
+ "line-opacity": 1,
+ "line-dasharray": [3, 3]
+ }
+ },
+ {
+ "id": "tunnel-construction",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 14,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "construction"],
+ ["==", "structure", "tunnel"]
+ ]
+ ],
+ "layout": {"line-join": "miter"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12.5, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(230, 24%, 87%)",
+ "line-opacity": {"base": 1, "stops": [[13.99, 0], [14, 1]]},
+ "line-dasharray": {
+ "base": 1,
+ "stops": [
+ [14, [0.4, 0.8]],
+ [15, [0.3, 0.6]],
+ [16, [0.2, 0.3]],
+ [17, [0.2, 0.25]],
+ [18, [0.15, 0.15]]
+ ]
+ }
+ }
+ },
+ {
+ "id": "tunnel-path",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!=", "type", "steps"],
+ ["==", "class", "path"],
+ ["==", "structure", "tunnel"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[15, 1], [18, 4]]},
+ "line-dasharray": {
+ "base": 1,
+ "stops": [
+ [14, [1, 0]],
+ [15, [1.75, 1]],
+ [16, [1, 0.75]],
+ [17, [1, 0.5]]
+ ]
+ },
+ "line-color": "hsl(35, 26%, 95%)",
+ "line-opacity": {"base": 1, "stops": [[14, 0], [14.25, 1]]}
+ }
+ },
+ {
+ "id": "tunnel-steps",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ ["all", ["==", "structure", "tunnel"], ["==", "type", "steps"]]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[15, 1], [16, 1.6], [18, 6]]
+ },
+ "line-color": "hsl(35, 26%, 95%)",
+ "line-dasharray": {
+ "base": 1,
+ "stops": [
+ [14, [1, 0]],
+ [15, [1.75, 1]],
+ [16, [1, 0.75]],
+ [17, [0.3, 0.3]]
+ ]
+ },
+ "line-opacity": {"base": 1, "stops": [[14, 0], [14.25, 1]]}
+ }
+ },
+ {
+ "id": "tunnel-trunk_link",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "structure", "tunnel"],
+ ["==", "type", "trunk_link"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(46, 77%, 78%)",
+ "line-opacity": 1,
+ "line-dasharray": [1, 0]
+ }
+ },
+ {
+ "id": "tunnel-motorway_link",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "motorway_link"],
+ ["==", "structure", "tunnel"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(26, 100%, 78%)",
+ "line-opacity": 1,
+ "line-dasharray": [1, 0]
+ }
+ },
+ {
+ "id": "tunnel-pedestrian",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "pedestrian"],
+ ["==", "structure", "tunnel"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[14, 0.5], [18, 12]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-opacity": 1,
+ "line-dasharray": {
+ "base": 1,
+ "stops": [[14, [1, 0]], [15, [1.5, 0.4]], [16, [1, 0.2]]]
+ }
+ }
+ },
+ {
+ "id": "tunnel-service-link-track",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 14,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!=", "type", "trunk_link"],
+ ["==", "structure", "tunnel"],
+ ["in", "class", "link", "service", "track"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[14, 0.5], [18, 12]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-dasharray": [1, 0]
+ }
+ },
+ {
+ "id": "tunnel-street_limited",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "street_limited"],
+ ["==", "structure", "tunnel"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12.5, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(35, 14%, 93%)",
+ "line-opacity": {"base": 1, "stops": [[13.99, 0], [14, 1]]}
+ }
+ },
+ {
+ "id": "tunnel-street",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "street"],
+ ["==", "structure", "tunnel"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12.5, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-opacity": {"base": 1, "stops": [[13.99, 0], [14, 1]]}
+ }
+ },
+ {
+ "id": "tunnel-secondary-tertiary",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "structure", "tunnel"],
+ ["in", "class", "secondary", "tertiary"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[8.5, 0.5], [10, 0.75], [18, 26]]
+ },
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-opacity": 1,
+ "line-dasharray": [1, 0],
+ "line-blur": 0
+ }
+ },
+ {
+ "id": "tunnel-primary",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "primary"],
+ ["==", "structure", "tunnel"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-opacity": 1,
+ "line-dasharray": [1, 0],
+ "line-blur": 0
+ }
+ },
+ {
+ "id": "tunnel-oneway-arrows-blue-minor",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 16,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!=", "type", "trunk_link"],
+ ["==", "oneway", "true"],
+ ["==", "structure", "tunnel"],
+ [
+ "in",
+ "class",
+ "link",
+ "path",
+ "pedestrian",
+ "service",
+ "track"
+ ]
+ ]
+ ],
+ "layout": {
+ "symbol-placement": "line",
+ "icon-image": {
+ "base": 1,
+ "stops": [[17, "oneway-small"], [18, "oneway-large"]]
+ },
+ "symbol-spacing": 200,
+ "icon-padding": 2
+ },
+ "paint": {}
+ },
+ {
+ "id": "tunnel-oneway-arrows-blue-major",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 15,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!=", "type", "trunk_link"],
+ ["==", "oneway", "true"],
+ ["==", "structure", "tunnel"],
+ [
+ "in",
+ "class",
+ "primary",
+ "secondary",
+ "street",
+ "street_limited",
+ "tertiary"
+ ]
+ ]
+ ],
+ "layout": {
+ "symbol-placement": "line",
+ "icon-image": {
+ "base": 1,
+ "stops": [[16, "oneway-small"], [17, "oneway-large"]]
+ },
+ "symbol-spacing": 200,
+ "icon-padding": 2
+ },
+ "paint": {}
+ },
+ {
+ "id": "tunnel-trunk",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ ["all", ["==", "class", "trunk"], ["==", "structure", "tunnel"]]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]},
+ "line-color": "hsl(46, 77%, 78%)"
+ }
+ },
+ {
+ "id": "tunnel-motorway",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "motorway"],
+ ["==", "structure", "tunnel"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]},
+ "line-dasharray": [1, 0],
+ "line-opacity": 1,
+ "line-color": "hsl(26, 100%, 78%)",
+ "line-blur": 0
+ }
+ },
+ {
+ "id": "tunnel-oneway-arrows-white",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444855769305.6016"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 16,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ [
+ "!in",
+ "type",
+ "primary_link",
+ "secondary_link",
+ "tertiary_link"
+ ],
+ ["==", "oneway", "true"],
+ ["==", "structure", "tunnel"],
+ [
+ "in",
+ "class",
+ "link",
+ "motorway",
+ "motorway_link",
+ "trunk"
+ ]
+ ]
+ ],
+ "layout": {
+ "symbol-placement": "line",
+ "icon-image": {
+ "base": 1,
+ "stops": [
+ [16, "oneway-white-small"],
+ [17, "oneway-white-large"]
+ ]
+ },
+ "symbol-spacing": 200,
+ "icon-padding": 2
+ },
+ "paint": {}
+ },
+ {
+ "id": "ferry",
+ "type": "line",
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ ["==", "type", "ferry"]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-color": {
+ "base": 1,
+ "stops": [
+ [15, "hsl(205, 73%, 63%)"],
+ [17, "hsl(230, 73%, 63%)"]
+ ]
+ },
+ "line-opacity": 1,
+ "line-width": {"base": 1.5, "stops": [[14, 0.5], [20, 1]]},
+ "line-dasharray": {
+ "base": 1,
+ "stops": [[12, [1, 0]], [13, [12, 4]]]
+ }
+ }
+ },
+ {
+ "id": "ferry_auto",
+ "type": "line",
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ ["==", "type", "ferry_auto"]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-color": {
+ "base": 1,
+ "stops": [
+ [15, "hsl(205, 73%, 63%)"],
+ [17, "hsl(230, 73%, 63%)"]
+ ]
+ },
+ "line-opacity": 1,
+ "line-width": {"base": 1.5, "stops": [[14, 0.5], [20, 1]]}
+ }
+ },
+ {
+ "id": "road-path-bg",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["!in", "type", "crossing", "sidewalk", "steps"],
+ ["==", "class", "path"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[15, 2], [18, 7]]},
+ "line-dasharray": [1, 0],
+ "line-color": "hsl(230, 17%, 82%)",
+ "line-blur": 0,
+ "line-opacity": {"base": 1, "stops": [[14, 0], [14.25, 0.75]]}
+ }
+ },
+ {
+ "id": "road-steps-bg",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["==", "type", "steps"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[15, 2], [17, 4.6], [18, 7]]
+ },
+ "line-color": "hsl(230, 17%, 82%)",
+ "line-dasharray": [1, 0],
+ "line-opacity": {"base": 1, "stops": [[14, 0], [14.25, 0.75]]}
+ }
+ },
+ {
+ "id": "road-sidewalk-bg",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 16,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["in", "type", "crossing", "sidewalk"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[15, 2], [18, 7]]},
+ "line-dasharray": [1, 0],
+ "line-color": "hsl(230, 17%, 82%)",
+ "line-blur": 0,
+ "line-opacity": {"base": 1, "stops": [[16, 0], [16.25, 0.75]]}
+ }
+ },
+ {
+ "id": "turning-features-outline",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 15,
+ "filter": [
+ "all",
+ ["==", "$type", "Point"],
+ ["in", "class", "turning_circle", "turning_loop"]
+ ],
+ "layout": {
+ "icon-image": "turning-circle-outline",
+ "icon-size": {
+ "base": 1.5,
+ "stops": [[14, 0.122], [18, 0.969], [20, 1]]
+ },
+ "icon-allow-overlap": true,
+ "icon-ignore-placement": true,
+ "icon-padding": 0,
+ "icon-rotation-alignment": "map"
+ },
+ "paint": {}
+ },
+ {
+ "id": "road-pedestrian-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 12,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "pedestrian"],
+ ["==", "structure", "none"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[14, 2], [18, 14.5]]},
+ "line-color": "hsl(230, 24%, 87%)",
+ "line-gap-width": 0,
+ "line-opacity": {"base": 1, "stops": [[13.99, 0], [14, 1]]}
+ }
+ },
+ {
+ "id": "road-street-low",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ ["all", ["==", "class", "street"], ["==", "structure", "none"]]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12.5, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-opacity": {
+ "stops": [[11, 0], [11.25, 1], [14, 1], [14.01, 0]]
+ }
+ }
+ },
+ {
+ "id": "road-street_limited-low",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "street_limited"],
+ ["==", "structure", "none"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12.5, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-opacity": {
+ "stops": [[11, 0], [11.25, 1], [14, 1], [14.01, 0]]
+ }
+ }
+ },
+ {
+ "id": "road-service-link-track-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 14,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!=", "type", "trunk_link"],
+ ["!in", "structure", "bridge", "tunnel"],
+ ["in", "class", "link", "service", "track"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]},
+ "line-color": "hsl(230, 24%, 87%)",
+ "line-gap-width": {"base": 1.5, "stops": [[14, 0.5], [18, 12]]}
+ }
+ },
+ {
+ "id": "road-street_limited-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "street_limited"],
+ ["==", "structure", "none"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]},
+ "line-color": "hsl(230, 24%, 87%)",
+ "line-gap-width": {
+ "base": 1.5,
+ "stops": [[13, 0], [14, 2], [18, 18]]
+ },
+ "line-opacity": {"base": 1, "stops": [[13.99, 0], [14, 1]]}
+ }
+ },
+ {
+ "id": "road-street-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ ["all", ["==", "class", "street"], ["==", "structure", "none"]]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]},
+ "line-color": "hsl(230, 24%, 87%)",
+ "line-gap-width": {
+ "base": 1.5,
+ "stops": [[13, 0], [14, 2], [18, 18]]
+ },
+ "line-opacity": {"base": 1, "stops": [[13.99, 0], [14, 1]]}
+ }
+ },
+ {
+ "id": "road-secondary-tertiary-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["in", "class", "secondary", "tertiary"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.2, "stops": [[10, 0.75], [18, 2]]},
+ "line-color": "hsl(230, 24%, 87%)",
+ "line-gap-width": {
+ "base": 1.5,
+ "stops": [[8.5, 0.5], [10, 0.75], [18, 26]]
+ },
+ "line-opacity": {"base": 1, "stops": [[9.99, 0], [10, 1]]}
+ }
+ },
+ {
+ "id": "road-primary-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["==", "class", "primary"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[10, 1], [16, 2]]},
+ "line-color": "hsl(230, 24%, 87%)",
+ "line-gap-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]},
+ "line-opacity": {"base": 1, "stops": [[9.99, 0], [10, 1]]}
+ }
+ },
+ {
+ "id": "road-motorway_link-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 10,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["==", "class", "motorway_link"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-gap-width": {
+ "base": 1.5,
+ "stops": [[12, 0.5], [14, 2], [18, 18]]
+ },
+ "line-opacity": {"base": 1, "stops": [[10.99, 0], [11, 1]]}
+ }
+ },
+ {
+ "id": "road-trunk_link-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["==", "type", "trunk_link"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-gap-width": {
+ "base": 1.5,
+ "stops": [[12, 0.5], [14, 2], [18, 18]]
+ },
+ "line-opacity": {"base": 1, "stops": [[10.99, 0], [11, 1]]}
+ }
+ },
+ {
+ "id": "road-trunk-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["==", "class", "trunk"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[10, 1], [16, 2]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-gap-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]},
+ "line-opacity": {"base": 1, "stops": [[6, 0], [6.1, 1]]}
+ }
+ },
+ {
+ "id": "road-motorway-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["==", "class", "motorway"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[10, 1], [16, 2]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-gap-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]}
+ }
+ },
+ {
+ "id": "road-construction",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 14,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "construction"],
+ ["==", "structure", "none"]
+ ]
+ ],
+ "layout": {"line-join": "miter"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12.5, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(230, 24%, 87%)",
+ "line-opacity": {"base": 1, "stops": [[13.99, 0], [14, 1]]},
+ "line-dasharray": {
+ "base": 1,
+ "stops": [
+ [14, [0.4, 0.8]],
+ [15, [0.3, 0.6]],
+ [16, [0.2, 0.3]],
+ [17, [0.2, 0.25]],
+ [18, [0.15, 0.15]]
+ ]
+ }
+ }
+ },
+ {
+ "id": "road-sidewalks",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 16,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["in", "type", "crossing", "sidewalk"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[15, 1], [18, 4]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-dasharray": {
+ "base": 1,
+ "stops": [
+ [14, [1, 0]],
+ [15, [1.75, 1]],
+ [16, [1, 0.75]],
+ [17, [1, 0.5]]
+ ]
+ },
+ "line-opacity": {"base": 1, "stops": [[16, 0], [16.25, 1]]}
+ }
+ },
+ {
+ "id": "road-path",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["!in", "type", "crossing", "sidewalk", "steps"],
+ ["==", "class", "path"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[15, 1], [18, 4]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-dasharray": {
+ "base": 1,
+ "stops": [
+ [14, [1, 0]],
+ [15, [1.75, 1]],
+ [16, [1, 0.75]],
+ [17, [1, 0.5]]
+ ]
+ },
+ "line-opacity": {"base": 1, "stops": [[14, 0], [14.25, 1]]}
+ }
+ },
+ {
+ "id": "road-steps",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["==", "type", "steps"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[15, 1], [16, 1.6], [18, 6]]
+ },
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-dasharray": {
+ "base": 1,
+ "stops": [
+ [14, [1, 0]],
+ [15, [1.75, 1]],
+ [16, [1, 0.75]],
+ [17, [0.3, 0.3]]
+ ]
+ },
+ "line-opacity": {"base": 1, "stops": [[14, 0], [14.25, 1]]}
+ }
+ },
+ {
+ "id": "road-trunk_link",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["==", "type", "trunk_link"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(46, 85%, 67%)",
+ "line-opacity": 1
+ }
+ },
+ {
+ "id": "road-motorway_link",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 10,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["==", "class", "motorway_link"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(26, 100%, 68%)",
+ "line-opacity": 1
+ }
+ },
+ {
+ "id": "road-pedestrian",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 12,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "pedestrian"],
+ ["==", "structure", "none"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[14, 0.5], [18, 12]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-opacity": 1,
+ "line-dasharray": {
+ "base": 1,
+ "stops": [[14, [1, 0]], [15, [1.5, 0.4]], [16, [1, 0.2]]]
+ }
+ }
+ },
+ {
+ "id": "road-pedestrian-polygon-fill",
+ "type": "fill",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 12,
+ "filter": [
+ "all",
+ ["==", "$type", "Polygon"],
+ [
+ "all",
+ ["==", "structure", "none"],
+ ["in", "class", "path", "pedestrian"]
+ ]
+ ],
+ "layout": {},
+ "paint": {
+ "fill-color": {
+ "base": 1,
+ "stops": [
+ [16, "hsl(230, 16%, 94%)"],
+ [16.25, "hsl(230, 50%, 98%)"]
+ ]
+ },
+ "fill-outline-color": "hsl(230, 26%, 88%)",
+ "fill-opacity": 1
+ }
+ },
+ {
+ "id": "road-pedestrian-polygon-pattern",
+ "type": "fill",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 12,
+ "filter": [
+ "all",
+ ["==", "$type", "Polygon"],
+ [
+ "all",
+ ["==", "structure", "none"],
+ ["in", "class", "path", "pedestrian"]
+ ]
+ ],
+ "layout": {},
+ "paint": {
+ "fill-color": "hsl(0, 0%, 100%)",
+ "fill-outline-color": "hsl(35, 10%, 83%)",
+ "fill-pattern": "pedestrian-polygon",
+ "fill-opacity": {"base": 1, "stops": [[16, 0], [16.25, 1]]}
+ }
+ },
+ {
+ "id": "road-polygon",
+ "type": "fill",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 12,
+ "filter": [
+ "all",
+ ["==", "$type", "Polygon"],
+ [
+ "all",
+ ["!in", "class", "motorway", "path", "pedestrian", "trunk"],
+ ["!in", "structure", "bridge", "tunnel"]
+ ]
+ ],
+ "layout": {},
+ "paint": {
+ "fill-color": "hsl(0, 0%, 100%)",
+ "fill-outline-color": "#d6d9e6"
+ }
+ },
+ {
+ "id": "road-service-link-track",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 14,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!=", "type", "trunk_link"],
+ ["!in", "structure", "bridge", "tunnel"],
+ ["in", "class", "link", "service", "track"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[14, 0.5], [18, 12]]},
+ "line-color": "hsl(0, 0%, 100%)"
+ }
+ },
+ {
+ "id": "road-street_limited",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "street_limited"],
+ ["==", "structure", "none"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12.5, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(35, 14%, 93%)",
+ "line-opacity": {"base": 1, "stops": [[13.99, 0], [14, 1]]}
+ }
+ },
+ {
+ "id": "road-street",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ ["all", ["==", "class", "street"], ["==", "structure", "none"]]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12.5, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-opacity": {"base": 1, "stops": [[13.99, 0], [14, 1]]}
+ }
+ },
+ {
+ "id": "road-secondary-tertiary",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["in", "class", "secondary", "tertiary"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[8.5, 0.5], [10, 0.75], [18, 26]]
+ },
+ "line-color": {
+ "base": 1,
+ "stops": [[5, "hsl(35, 32%, 91%)"], [8, "hsl(0, 0%, 100%)"]]
+ },
+ "line-opacity": {"base": 1.2, "stops": [[5, 0], [5.5, 1]]}
+ }
+ },
+ {
+ "id": "road-primary",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["==", "class", "primary"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]},
+ "line-color": {
+ "base": 1,
+ "stops": [[5, "hsl(35, 32%, 91%)"], [7, "hsl(0, 0%, 100%)"]]
+ },
+ "line-opacity": 1
+ }
+ },
+ {
+ "id": "road-oneway-arrows-blue-minor",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 16,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!=", "type", "trunk_link"],
+ ["!in", "structure", "bridge", "tunnel"],
+ ["==", "oneway", "true"],
+ [
+ "in",
+ "class",
+ "link",
+ "path",
+ "pedestrian",
+ "service",
+ "track"
+ ]
+ ]
+ ],
+ "layout": {
+ "symbol-placement": "line",
+ "icon-image": {
+ "base": 1,
+ "stops": [[17, "oneway-small"], [18, "oneway-large"]]
+ },
+ "icon-rotation-alignment": "map",
+ "icon-padding": 2,
+ "symbol-spacing": 200
+ },
+ "paint": {}
+ },
+ {
+ "id": "road-oneway-arrows-blue-major",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 15,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!=", "type", "trunk_link"],
+ ["!in", "structure", "bridge", "tunnel"],
+ ["==", "oneway", "true"],
+ [
+ "in",
+ "class",
+ "primary",
+ "secondary",
+ "street",
+ "street_limited",
+ "tertiary"
+ ]
+ ]
+ ],
+ "layout": {
+ "symbol-placement": "line",
+ "icon-image": {
+ "base": 1,
+ "stops": [[16, "oneway-small"], [17, "oneway-large"]]
+ },
+ "icon-rotation-alignment": "map",
+ "icon-padding": 2,
+ "symbol-spacing": 200
+ },
+ "paint": {}
+ },
+ {
+ "id": "road-trunk",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["==", "class", "trunk"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]},
+ "line-color": {
+ "base": 1,
+ "stops": [
+ [6, "hsl(0, 0%, 100%)"],
+ [6.1, "hsl(46, 80%, 60%)"],
+ [9, "hsl(46, 85%, 67%)"]
+ ]
+ }
+ }
+ },
+ {
+ "id": "road-motorway",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["==", "class", "motorway"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]},
+ "line-color": {
+ "base": 1,
+ "stops": [
+ [8, "hsl(26, 87%, 62%)"],
+ [9, "hsl(26, 100%, 68%)"]
+ ]
+ }
+ }
+ },
+ {
+ "id": "road-rail",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["in", "class", "major_rail", "minor_rail"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-color": {
+ "stops": [
+ [13, "hsl(50, 17%, 82%)"],
+ [16, "hsl(230, 10%, 74%)"]
+ ]
+ },
+ "line-width": {"base": 1.5, "stops": [[14, 0.5], [20, 1]]}
+ }
+ },
+ {
+ "id": "road-rail-tracks",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ ["in", "class", "major_rail", "minor_rail"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-color": {
+ "stops": [
+ [13, "hsl(50, 17%, 82%)"],
+ [16, "hsl(230, 10%, 74%)"]
+ ]
+ },
+ "line-width": {"base": 1.5, "stops": [[14, 4], [20, 8]]},
+ "line-dasharray": [0.1, 15],
+ "line-opacity": {"base": 1, "stops": [[13.75, 0], [14, 1]]}
+ }
+ },
+ {
+ "id": "level-crossings",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 16,
+ "filter": [
+ "all",
+ ["==", "$type", "Point"],
+ ["==", "class", "level_crossing"]
+ ],
+ "layout": {
+ "icon-size": 1,
+ "icon-image": "level-crossing",
+ "icon-allow-overlap": true
+ },
+ "paint": {}
+ },
+ {
+ "id": "road-oneway-arrows-white",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 16,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "structure", "bridge", "tunnel"],
+ [
+ "!in",
+ "type",
+ "primary_link",
+ "secondary_link",
+ "tertiary_link"
+ ],
+ ["==", "oneway", "true"],
+ [
+ "in",
+ "class",
+ "link",
+ "motorway",
+ "motorway_link",
+ "trunk"
+ ]
+ ]
+ ],
+ "layout": {
+ "symbol-placement": "line",
+ "icon-image": {
+ "base": 1,
+ "stops": [
+ [16, "oneway-white-small"],
+ [17, "oneway-white-large"]
+ ]
+ },
+ "icon-padding": 2,
+ "symbol-spacing": 200
+ },
+ "paint": {}
+ },
+ {
+ "id": "turning-features",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444855786460.0557"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 15,
+ "filter": [
+ "all",
+ ["==", "$type", "Point"],
+ ["in", "class", "turning_circle", "turning_loop"]
+ ],
+ "layout": {
+ "icon-image": "turning-circle",
+ "icon-size": {"base": 1.5, "stops": [[14, 0.095], [18, 1]]},
+ "icon-allow-overlap": true,
+ "icon-ignore-placement": true,
+ "icon-padding": 0,
+ "icon-rotation-alignment": "map"
+ },
+ "paint": {}
+ },
+ {
+ "id": "bridge-path-bg",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!=", "type", "steps"],
+ ["==", "class", "path"],
+ ["==", "structure", "bridge"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[15, 2], [18, 7]]},
+ "line-dasharray": [1, 0],
+ "line-color": "hsl(230, 17%, 82%)",
+ "line-blur": 0,
+ "line-opacity": {"base": 1, "stops": [[15, 0], [15.25, 1]]}
+ }
+ },
+ {
+ "id": "bridge-steps-bg",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ ["all", ["==", "structure", "bridge"], ["==", "type", "steps"]]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[15, 2], [17, 4.6], [18, 7]]
+ },
+ "line-color": "hsl(230, 17%, 82%)",
+ "line-dasharray": [1, 0],
+ "line-opacity": {"base": 1, "stops": [[14, 0], [14.25, 0.75]]}
+ }
+ },
+ {
+ "id": "bridge-pedestrian-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "pedestrian"],
+ ["==", "structure", "bridge"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[14, 2], [18, 14.5]]},
+ "line-color": "hsl(230, 24%, 87%)",
+ "line-gap-width": 0,
+ "line-opacity": {"base": 1, "stops": [[13.99, 0], [14, 1]]}
+ }
+ },
+ {
+ "id": "bridge-street-low",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "street"],
+ ["==", "structure", "bridge"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12.5, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-opacity": {
+ "stops": [[11.5, 0], [12, 1], [14, 1], [14.01, 0]]
+ }
+ }
+ },
+ {
+ "id": "bridge-street_limited-low",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "street_limited"],
+ ["==", "structure", "bridge"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12.5, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-opacity": {
+ "stops": [[11.5, 0], [12, 1], [14, 1], [14.01, 0]]
+ }
+ }
+ },
+ {
+ "id": "bridge-service-link-track-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 14,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!=", "type", "trunk_link"],
+ ["==", "structure", "bridge"],
+ ["in", "class", "link", "service", "track"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]},
+ "line-color": "hsl(230, 24%, 87%)",
+ "line-gap-width": {"base": 1.5, "stops": [[14, 0.5], [18, 12]]}
+ }
+ },
+ {
+ "id": "bridge-street_limited-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "street_limited"],
+ ["==", "structure", "bridge"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]},
+ "line-color": "hsl(230, 24%, 87%)",
+ "line-gap-width": {
+ "base": 1.5,
+ "stops": [[13, 0], [14, 2], [18, 18]]
+ }
+ }
+ },
+ {
+ "id": "bridge-street-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "street"],
+ ["==", "structure", "bridge"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]},
+ "line-color": "hsl(230, 24%, 87%)",
+ "line-opacity": {"base": 1, "stops": [[13.99, 0], [14, 1]]},
+ "line-gap-width": {
+ "base": 1.5,
+ "stops": [[13, 0], [14, 2], [18, 18]]
+ }
+ }
+ },
+ {
+ "id": "bridge-secondary-tertiary-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "structure", "bridge"],
+ ["in", "class", "secondary", "tertiary"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.2, "stops": [[10, 0.75], [18, 2]]},
+ "line-color": "hsl(230, 24%, 87%)",
+ "line-gap-width": {
+ "base": 1.5,
+ "stops": [[8.5, 0.5], [10, 0.75], [18, 26]]
+ },
+ "line-translate": [0, 0]
+ }
+ },
+ {
+ "id": "bridge-primary-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "primary"],
+ ["==", "structure", "bridge"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[10, 1], [16, 2]]},
+ "line-color": "hsl(230, 24%, 87%)",
+ "line-gap-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]},
+ "line-translate": [0, 0]
+ }
+ },
+ {
+ "id": "bridge-trunk_link-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "layer", 2, 3, 4, 5],
+ ["==", "structure", "bridge"],
+ ["==", "type", "trunk_link"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-gap-width": {
+ "base": 1.5,
+ "stops": [[12, 0.5], [14, 2], [18, 18]]
+ },
+ "line-opacity": {"base": 1, "stops": [[10.99, 0], [11, 1]]}
+ }
+ },
+ {
+ "id": "bridge-motorway_link-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "layer", 2, 3, 4, 5],
+ ["==", "class", "motorway_link"],
+ ["==", "structure", "bridge"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-gap-width": {
+ "base": 1.5,
+ "stops": [[12, 0.5], [14, 2], [18, 18]]
+ },
+ "line-opacity": 1
+ }
+ },
+ {
+ "id": "bridge-trunk-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "layer", 2, 3, 4, 5],
+ ["==", "class", "trunk"],
+ ["==", "structure", "bridge"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[10, 1], [16, 2]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-gap-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]}
+ }
+ },
+ {
+ "id": "bridge-motorway-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "layer", 2, 3, 4, 5],
+ ["==", "class", "motorway"],
+ ["==", "structure", "bridge"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[10, 1], [16, 2]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-gap-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]}
+ }
+ },
+ {
+ "id": "bridge-construction",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 14,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "construction"],
+ ["==", "structure", "bridge"]
+ ]
+ ],
+ "layout": {"line-join": "miter"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12.5, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(230, 24%, 87%)",
+ "line-opacity": {"base": 1, "stops": [[13.99, 0], [14, 1]]},
+ "line-dasharray": {
+ "base": 1,
+ "stops": [
+ [14, [0.4, 0.8]],
+ [15, [0.3, 0.6]],
+ [16, [0.2, 0.3]],
+ [17, [0.2, 0.25]],
+ [18, [0.15, 0.15]]
+ ]
+ }
+ }
+ },
+ {
+ "id": "bridge-path",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!=", "type", "steps"],
+ ["==", "class", "path"],
+ ["==", "structure", "bridge"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[15, 1], [18, 4]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-dasharray": {
+ "base": 1,
+ "stops": [
+ [14, [1, 0]],
+ [15, [1.75, 1]],
+ [16, [1, 0.75]],
+ [17, [1, 0.5]]
+ ]
+ },
+ "line-opacity": {"base": 1, "stops": [[14, 0], [14.25, 1]]}
+ }
+ },
+ {
+ "id": "bridge-steps",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ ["all", ["==", "structure", "bridge"], ["==", "type", "steps"]]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[15, 1], [16, 1.6], [18, 6]]
+ },
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-dasharray": {
+ "base": 1,
+ "stops": [
+ [14, [1, 0]],
+ [15, [1.75, 1]],
+ [16, [1, 0.75]],
+ [17, [0.3, 0.3]]
+ ]
+ },
+ "line-opacity": {"base": 1, "stops": [[14, 0], [14.25, 1]]}
+ }
+ },
+ {
+ "id": "bridge-trunk_link",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "layer", 2, 3, 4, 5],
+ ["==", "structure", "bridge"],
+ ["==", "type", "trunk_link"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(46, 85%, 67%)"
+ }
+ },
+ {
+ "id": "bridge-motorway_link",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "layer", 2, 3, 4, 5],
+ ["==", "class", "motorway_link"],
+ ["==", "structure", "bridge"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(26, 100%, 68%)"
+ }
+ },
+ {
+ "id": "bridge-pedestrian",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "pedestrian"],
+ ["==", "structure", "bridge"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[14, 0.5], [18, 12]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-opacity": 1,
+ "line-dasharray": {
+ "base": 1,
+ "stops": [[14, [1, 0]], [15, [1.5, 0.4]], [16, [1, 0.2]]]
+ }
+ }
+ },
+ {
+ "id": "bridge-service-link-track",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 14,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!=", "type", "trunk_link"],
+ ["==", "structure", "bridge"],
+ ["in", "class", "link", "service", "track"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[14, 0.5], [18, 12]]},
+ "line-color": "hsl(0, 0%, 100%)"
+ }
+ },
+ {
+ "id": "bridge-street_limited",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "street_limited"],
+ ["==", "structure", "bridge"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12.5, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(35, 14%, 93%)",
+ "line-opacity": {"base": 1, "stops": [[13.99, 0], [14, 1]]}
+ }
+ },
+ {
+ "id": "bridge-street",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "street"],
+ ["==", "structure", "bridge"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12.5, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-opacity": {"base": 1, "stops": [[13.99, 0], [14, 1]]}
+ }
+ },
+ {
+ "id": "bridge-secondary-tertiary",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "structure", "bridge"],
+ ["in", "type", "secondary", "tertiary"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[8.5, 0.5], [10, 0.75], [18, 26]]
+ },
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-opacity": {"base": 1.2, "stops": [[5, 0], [5.5, 1]]}
+ }
+ },
+ {
+ "id": "bridge-primary",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "structure", "bridge"],
+ ["==", "type", "primary"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-opacity": 1
+ }
+ },
+ {
+ "id": "bridge-oneway-arrows-blue-minor",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 16,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "oneway", "true"],
+ ["==", "structure", "bridge"],
+ [
+ "in",
+ "class",
+ "link",
+ "path",
+ "pedestrian",
+ "service",
+ "track"
+ ]
+ ]
+ ],
+ "layout": {
+ "symbol-placement": "line",
+ "icon-image": {
+ "base": 1,
+ "stops": [[17, "oneway-small"], [18, "oneway-large"]]
+ },
+ "symbol-spacing": 200,
+ "icon-rotation-alignment": "map",
+ "icon-padding": 2
+ },
+ "paint": {}
+ },
+ {
+ "id": "bridge-oneway-arrows-blue-major",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 15,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "oneway", "true"],
+ ["==", "structure", "bridge"],
+ [
+ "in",
+ "class",
+ "primary",
+ "secondary",
+ "street",
+ "street_limited",
+ "tertiary"
+ ]
+ ]
+ ],
+ "layout": {
+ "symbol-placement": "line",
+ "icon-image": {
+ "base": 1,
+ "stops": [[16, "oneway-small"], [17, "oneway-large"]]
+ },
+ "symbol-spacing": 200,
+ "icon-rotation-alignment": "map",
+ "icon-padding": 2
+ },
+ "paint": {}
+ },
+ {
+ "id": "bridge-trunk",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "layer", 2, 3, 4, 5],
+ ["==", "class", "trunk"],
+ ["==", "structure", "bridge"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]},
+ "line-color": "hsl(46, 85%, 67%)"
+ }
+ },
+ {
+ "id": "bridge-motorway",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["!in", "layer", 2, 3, 4, 5],
+ ["==", "class", "motorway"],
+ ["==", "structure", "bridge"]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]},
+ "line-color": "hsl(26, 100%, 68%)"
+ }
+ },
+ {
+ "id": "bridge-rail",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "structure", "bridge"],
+ ["in", "class", "major_rail", "minor_rail"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-color": {
+ "stops": [
+ [13, "hsl(50, 17%, 82%)"],
+ [16, "hsl(230, 10%, 74%)"]
+ ]
+ },
+ "line-width": {"base": 1.5, "stops": [[14, 0.5], [20, 1]]}
+ }
+ },
+ {
+ "id": "bridge-rail-tracks",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "structure", "bridge"],
+ ["in", "class", "major_rail", "minor_rail"]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-color": {
+ "stops": [
+ [13, "hsl(50, 17%, 82%)"],
+ [16, "hsl(230, 10%, 74%)"]
+ ]
+ },
+ "line-width": {"base": 1.5, "stops": [[14, 4], [20, 8]]},
+ "line-dasharray": [0.1, 15],
+ "line-opacity": {"base": 1, "stops": [[13.75, 0], [20, 1]]}
+ }
+ },
+ {
+ "id": "bridge-trunk_link-2-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "structure", "bridge"],
+ ["==", "type", "trunk_link"],
+ [">=", "layer", 2]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-gap-width": {
+ "base": 1.5,
+ "stops": [[12, 0.5], [14, 2], [18, 18]]
+ },
+ "line-opacity": {"base": 1, "stops": [[10.99, 0], [11, 1]]}
+ }
+ },
+ {
+ "id": "bridge-motorway_link-2-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "motorway_link"],
+ ["==", "structure", "bridge"],
+ [">=", "layer", 2]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-gap-width": {
+ "base": 1.5,
+ "stops": [[12, 0.5], [14, 2], [18, 18]]
+ },
+ "line-opacity": 1
+ }
+ },
+ {
+ "id": "bridge-trunk-2-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "trunk"],
+ ["==", "structure", "bridge"],
+ [">=", "layer", 2]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[10, 1], [16, 2]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-gap-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]}
+ }
+ },
+ {
+ "id": "bridge-motorway-2-case",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "motorway"],
+ ["==", "structure", "bridge"],
+ [">=", "layer", 2]
+ ]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[10, 1], [16, 2]]},
+ "line-color": "hsl(0, 0%, 100%)",
+ "line-gap-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]}
+ }
+ },
+ {
+ "id": "bridge-trunk_link-2",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "structure", "bridge"],
+ ["==", "type", "trunk_link"],
+ [">=", "layer", 2]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(46, 85%, 67%)"
+ }
+ },
+ {
+ "id": "bridge-motorway_link-2",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "motorway_link"],
+ ["==", "structure", "bridge"],
+ [">=", "layer", 2]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {
+ "base": 1.5,
+ "stops": [[12, 0.5], [14, 2], [18, 18]]
+ },
+ "line-color": "hsl(26, 100%, 68%)"
+ }
+ },
+ {
+ "id": "bridge-trunk-2",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "trunk"],
+ ["==", "structure", "bridge"],
+ [">=", "layer", 2]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]},
+ "line-color": "hsl(46, 85%, 67%)"
+ }
+ },
+ {
+ "id": "bridge-motorway-2",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ ["==", "class", "motorway"],
+ ["==", "structure", "bridge"],
+ [">=", "layer", 2]
+ ]
+ ],
+ "layout": {"line-cap": "round", "line-join": "round"},
+ "paint": {
+ "line-width": {"base": 1.5, "stops": [[5, 0.75], [18, 32]]},
+ "line-color": "hsl(26, 100%, 68%)"
+ }
+ },
+ {
+ "id": "bridge-oneway-arrows-white",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444855799204.86"},
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 16,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "all",
+ [
+ "!in",
+ "type",
+ "primary_link",
+ "secondary_link",
+ "tertiary_link"
+ ],
+ ["==", "oneway", "true"],
+ ["==", "structure", "bridge"],
+ [
+ "in",
+ "class",
+ "link",
+ "motorway",
+ "motorway_link",
+ "trunk"
+ ]
+ ]
+ ],
+ "layout": {
+ "symbol-placement": "line",
+ "icon-image": {
+ "base": 1,
+ "stops": [
+ [16, "oneway-white-small"],
+ [17, "oneway-white-large"]
+ ]
+ },
+ "symbol-spacing": 200,
+ "icon-padding": 2
+ },
+ "paint": {}
+ },
+ {
+ "id": "aerialway",
+ "type": "line",
+ "source": "composite",
+ "source-layer": "road",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ ["==", "class", "aerialway"]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-color": "hsl(230, 10%, 74%)",
+ "line-width": {"base": 1.5, "stops": [[14, 0.5], [20, 1]]}
+ }
+ },
+ {
+ "id": "admin-3-4-boundaries-bg",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444934295202.7542"},
+ "source": "composite",
+ "source-layer": "admin",
+ "filter": ["all", ["==", "maritime", 0], [">=", "admin_level", 3]],
+ "layout": {"line-join": "bevel"},
+ "paint": {
+ "line-color": {
+ "base": 1,
+ "stops": [
+ [8, "hsl(35, 12%, 89%)"],
+ [16, "hsl(230, 49%, 90%)"]
+ ]
+ },
+ "line-width": {"base": 1, "stops": [[7, 3.75], [12, 5.5]]},
+ "line-opacity": {"base": 1, "stops": [[7, 0], [8, 0.75]]},
+ "line-dasharray": [1, 0],
+ "line-translate": [0, 0],
+ "line-blur": {"base": 1, "stops": [[3, 0], [8, 3]]}
+ }
+ },
+ {
+ "id": "admin-2-boundaries-bg",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444934295202.7542"},
+ "source": "composite",
+ "source-layer": "admin",
+ "minzoom": 1,
+ "filter": ["all", ["==", "admin_level", 2], ["==", "maritime", 0]],
+ "layout": {"line-join": "miter"},
+ "paint": {
+ "line-width": {"base": 1, "stops": [[3, 3.5], [10, 8]]},
+ "line-color": {
+ "base": 1,
+ "stops": [
+ [6, "hsl(35, 12%, 89%)"],
+ [8, "hsl(230, 49%, 90%)"]
+ ]
+ },
+ "line-opacity": {"base": 1, "stops": [[3, 0], [4, 0.5]]},
+ "line-translate": [0, 0],
+ "line-blur": {"base": 1, "stops": [[3, 0], [10, 2]]}
+ }
+ },
+ {
+ "id": "admin-3-4-boundaries",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444934295202.7542"},
+ "source": "composite",
+ "source-layer": "admin",
+ "filter": ["all", ["==", "maritime", 0], [">=", "admin_level", 3]],
+ "layout": {"line-join": "round", "line-cap": "round"},
+ "paint": {
+ "line-dasharray": {
+ "base": 1,
+ "stops": [[6, [2, 0]], [7, [2, 2, 6, 2]]]
+ },
+ "line-width": {"base": 1, "stops": [[7, 0.75], [12, 1.5]]},
+ "line-opacity": {"base": 1, "stops": [[2, 0], [3, 1]]},
+ "line-color": {
+ "base": 1,
+ "stops": [
+ [3, "hsl(230, 14%, 77%)"],
+ [7, "hsl(230, 8%, 62%)"]
+ ]
+ }
+ }
+ },
+ {
+ "id": "admin-2-boundaries",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444934295202.7542"},
+ "source": "composite",
+ "source-layer": "admin",
+ "minzoom": 1,
+ "filter": [
+ "all",
+ ["==", "admin_level", 2],
+ ["==", "disputed", 0],
+ ["==", "maritime", 0]
+ ],
+ "layout": {"line-join": "round", "line-cap": "round"},
+ "paint": {
+ "line-color": "hsl(230, 8%, 51%)",
+ "line-width": {"base": 1, "stops": [[3, 0.5], [10, 2]]}
+ }
+ },
+ {
+ "id": "admin-2-boundaries-dispute",
+ "type": "line",
+ "metadata": {"mapbox:group": "1444934295202.7542"},
+ "source": "composite",
+ "source-layer": "admin",
+ "minzoom": 1,
+ "filter": [
+ "all",
+ ["==", "admin_level", 2],
+ ["==", "disputed", 1],
+ ["==", "maritime", 0]
+ ],
+ "layout": {"line-join": "round"},
+ "paint": {
+ "line-dasharray": [1.5, 1.5],
+ "line-color": "hsl(230, 8%, 51%)",
+ "line-width": {"base": 1, "stops": [[3, 0.5], [10, 2]]}
+ }
+ },
+ {
+ "id": "housenum-label",
+ "type": "symbol",
+ "source": "composite",
+ "source-layer": "housenum_label",
+ "minzoom": 17,
+ "layout": {
+ "text-field": "{house_num}",
+ "text-font": [
+ "DIN Offc Pro Italic",
+ "Arial Unicode MS Regular"
+ ],
+ "text-padding": 4,
+ "text-max-width": 7,
+ "text-size": 9.5
+ },
+ "paint": {
+ "text-color": "hsl(35, 2%, 69%)",
+ "text-halo-color": "hsl(35, 8%, 85%)",
+ "text-halo-width": 0.5,
+ "text-halo-blur": 0
+ }
+ },
+ {
+ "id": "waterway-label",
+ "type": "symbol",
+ "source": "composite",
+ "source-layer": "waterway_label",
+ "minzoom": 12,
+ "filter": ["in", "class", "canal", "river"],
+ "layout": {
+ "text-field": "{name_en}",
+ "text-font": [
+ "DIN Offc Pro Italic",
+ "Arial Unicode MS Regular"
+ ],
+ "symbol-placement": "line",
+ "text-pitch-alignment": "viewport",
+ "text-max-angle": 30,
+ "text-size": {"base": 1, "stops": [[13, 12], [18, 16]]}
+ },
+ "paint": {
+ "text-halo-width": 0.5,
+ "text-halo-color": "hsl(196, 80%, 70%)",
+ "text-color": "hsl(230, 48%, 44%)",
+ "text-halo-blur": 0.5
+ }
+ },
+ {
+ "id": "poi-scalerank4-l15",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444933456003.5437"},
+ "source": "composite",
+ "source-layer": "poi_label",
+ "minzoom": 17,
+ "filter": [
+ "all",
+ [
+ "!in",
+ "maki",
+ "campsite",
+ "cemetery",
+ "dog-park",
+ "garden",
+ "golf",
+ "park",
+ "picnic-site",
+ "playground",
+ "zoo"
+ ],
+ ["==", "scalerank", 4],
+ [">=", "localrank", 15]
+ ],
+ "layout": {
+ "text-line-height": 1.1,
+ "text-size": {"base": 1, "stops": [[16, 11], [20, 13]]},
+ "icon-image": "{maki}-11",
+ "text-max-angle": 38,
+ "symbol-spacing": 250,
+ "text-font": [
+ "DIN Offc Pro Medium",
+ "Arial Unicode MS Regular"
+ ],
+ "text-padding": 2,
+ "text-offset": [0, 0.65],
+ "text-rotation-alignment": "viewport",
+ "text-anchor": "top",
+ "text-field": "{name_en}",
+ "text-letter-spacing": 0.01,
+ "text-max-width": 8
+ },
+ "paint": {
+ "text-color": "hsl(26, 25%, 32%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 0.5,
+ "text-halo-blur": 0.5
+ }
+ },
+ {
+ "id": "poi-scalerank4-l1",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444933456003.5437"},
+ "source": "composite",
+ "source-layer": "poi_label",
+ "minzoom": 15,
+ "filter": [
+ "all",
+ [
+ "!in",
+ "maki",
+ "campsite",
+ "cemetery",
+ "dog-park",
+ "garden",
+ "golf",
+ "park",
+ "picnic-site",
+ "playground",
+ "zoo"
+ ],
+ ["<=", "localrank", 14],
+ ["==", "scalerank", 4]
+ ],
+ "layout": {
+ "text-line-height": 1.1,
+ "text-size": {"base": 1, "stops": [[16, 11], [20, 13]]},
+ "icon-image": "{maki}-11",
+ "text-max-angle": 38,
+ "symbol-spacing": 250,
+ "text-font": [
+ "DIN Offc Pro Medium",
+ "Arial Unicode MS Regular"
+ ],
+ "text-padding": 1,
+ "text-offset": [0, 0.65],
+ "text-rotation-alignment": "viewport",
+ "text-anchor": "top",
+ "text-field": "{name_en}",
+ "text-letter-spacing": 0.01,
+ "text-max-width": 8
+ },
+ "paint": {
+ "text-color": "hsl(26, 25%, 32%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 0.5,
+ "text-halo-blur": 0.5
+ }
+ },
+ {
+ "id": "poi-parks_scalerank4",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444933456003.5437"},
+ "source": "composite",
+ "source-layer": "poi_label",
+ "minzoom": 15,
+ "filter": [
+ "all",
+ ["==", "scalerank", 4],
+ [
+ "in",
+ "maki",
+ "campsite",
+ "cemetery",
+ "dog-park",
+ "garden",
+ "golf",
+ "park",
+ "picnic-site",
+ "playground",
+ "zoo"
+ ]
+ ],
+ "layout": {
+ "text-line-height": 1.1,
+ "text-size": {"base": 1, "stops": [[16, 11], [20, 13]]},
+ "icon-image": "{maki}-11",
+ "text-max-angle": 38,
+ "symbol-spacing": 250,
+ "text-font": [
+ "DIN Offc Pro Medium",
+ "Arial Unicode MS Regular"
+ ],
+ "text-padding": 1,
+ "text-offset": [0, 0.65],
+ "text-rotation-alignment": "viewport",
+ "text-anchor": "top",
+ "text-field": "{name_en}",
+ "text-letter-spacing": 0.01,
+ "text-max-width": 8
+ },
+ "paint": {
+ "text-color": "hsl(100, 100%, 20%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 0.5,
+ "text-halo-blur": 0.5
+ }
+ },
+ {
+ "id": "poi-scalerank3",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444933372896.5967"},
+ "source": "composite",
+ "source-layer": "poi_label",
+ "filter": [
+ "all",
+ [
+ "!in",
+ "maki",
+ "campsite",
+ "cemetery",
+ "dog-park",
+ "garden",
+ "golf",
+ "park",
+ "picnic-site",
+ "playground",
+ "zoo"
+ ],
+ ["==", "scalerank", 3]
+ ],
+ "layout": {
+ "text-line-height": 1.1,
+ "text-size": {"base": 1, "stops": [[16, 11], [20, 13]]},
+ "icon-image": "{maki}-11",
+ "text-max-angle": 38,
+ "symbol-spacing": 250,
+ "text-font": [
+ "DIN Offc Pro Medium",
+ "Arial Unicode MS Regular"
+ ],
+ "text-padding": 1,
+ "text-offset": [0, 0.65],
+ "text-rotation-alignment": "viewport",
+ "text-anchor": "top",
+ "text-field": "{name_en}",
+ "text-letter-spacing": 0.01,
+ "text-max-width": 8
+ },
+ "paint": {
+ "text-color": "hsl(26, 25%, 32%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 0.5,
+ "text-halo-blur": 0.5
+ }
+ },
+ {
+ "id": "poi-parks-scalerank3",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444933372896.5967"},
+ "source": "composite",
+ "source-layer": "poi_label",
+ "filter": [
+ "all",
+ ["==", "scalerank", 3],
+ [
+ "in",
+ "maki",
+ "campsite",
+ "cemetery",
+ "dog-park",
+ "garden",
+ "golf",
+ "park",
+ "picnic-site",
+ "playground",
+ "zoo"
+ ]
+ ],
+ "layout": {
+ "text-line-height": 1.1,
+ "text-size": {"base": 1, "stops": [[16, 11], [20, 13]]},
+ "icon-image": "{maki}-11",
+ "text-max-angle": 38,
+ "symbol-spacing": 250,
+ "text-font": [
+ "DIN Offc Pro Medium",
+ "Arial Unicode MS Regular"
+ ],
+ "text-padding": 2,
+ "text-offset": [0, 0.65],
+ "text-rotation-alignment": "viewport",
+ "text-anchor": "top",
+ "text-field": "{name_en}",
+ "text-letter-spacing": 0.01,
+ "text-max-width": 8
+ },
+ "paint": {
+ "text-color": "hsl(100, 100%, 20%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 0.5,
+ "text-halo-blur": 0.5
+ }
+ },
+ {
+ "id": "road-label-small",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444933721429.3076"},
+ "source": "composite",
+ "source-layer": "road_label",
+ "minzoom": 15,
+ "filter": [
+ "all",
+ [
+ "!in",
+ "class",
+ "golf",
+ "link",
+ "motorway",
+ "pedestrian",
+ "primary",
+ "secondary",
+ "street",
+ "street_limited",
+ "tertiary",
+ "trunk"
+ ],
+ ["==", "$type", "LineString"]
+ ],
+ "layout": {
+ "text-size": {"base": 1, "stops": [[15, 10], [20, 13]]},
+ "text-max-angle": 30,
+ "symbol-spacing": 250,
+ "text-font": [
+ "DIN Offc Pro Regular",
+ "Arial Unicode MS Regular"
+ ],
+ "symbol-placement": "line",
+ "text-padding": 1,
+ "text-rotation-alignment": "map",
+ "text-pitch-alignment": "viewport",
+ "text-field": "{name_en}",
+ "text-letter-spacing": 0.01
+ },
+ "paint": {
+ "text-color": "hsl(0, 0%, 0%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 1.25,
+ "text-halo-blur": 1
+ }
+ },
+ {
+ "id": "road-label-medium",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444933721429.3076"},
+ "source": "composite",
+ "source-layer": "road_label",
+ "minzoom": 11,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [
+ "in",
+ "class",
+ "link",
+ "pedestrian",
+ "street",
+ "street_limited"
+ ]
+ ],
+ "layout": {
+ "text-size": {"base": 1, "stops": [[11, 10], [20, 14]]},
+ "text-max-angle": 30,
+ "symbol-spacing": 250,
+ "text-font": [
+ "DIN Offc Pro Regular",
+ "Arial Unicode MS Regular"
+ ],
+ "symbol-placement": "line",
+ "text-padding": 1,
+ "text-rotation-alignment": "map",
+ "text-pitch-alignment": "viewport",
+ "text-field": "{name_en}",
+ "text-letter-spacing": 0.01
+ },
+ "paint": {
+ "text-color": "hsl(0, 0%, 0%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 1
+ }
+ },
+ {
+ "id": "road-label-large",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444933721429.3076"},
+ "source": "composite",
+ "source-layer": "road_label",
+ "filter": [
+ "in",
+ "class",
+ "motorway",
+ "primary",
+ "secondary",
+ "tertiary",
+ "trunk"
+ ],
+ "layout": {
+ "text-size": {"base": 1, "stops": [[9, 10], [20, 16]]},
+ "text-max-angle": 30,
+ "symbol-spacing": 250,
+ "text-font": [
+ "DIN Offc Pro Regular",
+ "Arial Unicode MS Regular"
+ ],
+ "symbol-placement": "line",
+ "text-padding": 1,
+ "text-rotation-alignment": "map",
+ "text-pitch-alignment": "viewport",
+ "text-field": "{name_en}",
+ "text-letter-spacing": 0.01
+ },
+ "paint": {
+ "text-color": "hsl(0, 0%, 0%)",
+ "text-halo-color": "hsla(0, 0%, 100%, 0.75)",
+ "text-halo-width": 1,
+ "text-halo-blur": 1
+ }
+ },
+ {
+ "id": "road-shields-black",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444933575858.6992"},
+ "source": "composite",
+ "source-layer": "road_label",
+ "filter": [
+ "all",
+ [
+ "!in",
+ "shield",
+ "at-expressway",
+ "at-motorway",
+ "at-state-b",
+ "bg-motorway",
+ "bg-national",
+ "ch-main",
+ "ch-motorway",
+ "cz-motorway",
+ "cz-road",
+ "de-motorway",
+ "e-road",
+ "fi-main",
+ "gr-motorway",
+ "gr-national",
+ "hr-motorway",
+ "hr-state",
+ "hu-main",
+ "hu-motorway",
+ "nz-state",
+ "pl-expressway",
+ "pl-motorway",
+ "pl-national",
+ "ro-county",
+ "ro-motorway",
+ "ro-national",
+ "rs-motorway",
+ "rs-state-1b",
+ "se-main",
+ "si-expressway",
+ "si-motorway",
+ "sk-highway",
+ "sk-road",
+ "us-interstate",
+ "us-interstate-business",
+ "us-interstate-duplex",
+ "us-interstate-truck",
+ "za-metropolitan",
+ "za-national",
+ "za-provincial",
+ "za-regional"
+ ],
+ ["<=", "reflen", 6]
+ ],
+ "layout": {
+ "text-size": 9,
+ "icon-image": "{shield}-{reflen}",
+ "icon-rotation-alignment": "viewport",
+ "text-max-angle": 38,
+ "symbol-spacing": {"base": 1, "stops": [[11, 150], [14, 200]]},
+ "text-font": ["DIN Offc Pro Bold", "Arial Unicode MS Bold"],
+ "symbol-placement": {
+ "base": 1,
+ "stops": [[10, "point"], [11, "line"]]
+ },
+ "text-padding": 2,
+ "text-rotation-alignment": "viewport",
+ "text-field": "{ref}",
+ "text-letter-spacing": 0.05,
+ "icon-padding": 2
+ },
+ "paint": {
+ "text-color": "hsl(0, 0%, 7%)",
+ "icon-halo-color": "rgba(0, 0, 0, 1)",
+ "icon-halo-width": 1,
+ "text-opacity": 1,
+ "icon-color": "white",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 0
+ }
+ },
+ {
+ "id": "road-shields-white",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444933575858.6992"},
+ "source": "composite",
+ "source-layer": "road_label",
+ "filter": [
+ "all",
+ ["<=", "reflen", 6],
+ [
+ "in",
+ "shield",
+ "at-expressway",
+ "at-motorway",
+ "at-state-b",
+ "bg-motorway",
+ "bg-national",
+ "ch-main",
+ "ch-motorway",
+ "cz-motorway",
+ "cz-road",
+ "de-motorway",
+ "e-road",
+ "fi-main",
+ "gr-motorway",
+ "gr-national",
+ "hr-motorway",
+ "hr-state",
+ "hu-main",
+ "hu-motorway",
+ "nz-state",
+ "pl-expressway",
+ "pl-motorway",
+ "pl-national",
+ "ro-county",
+ "ro-motorway",
+ "ro-national",
+ "rs-motorway",
+ "rs-state-1b",
+ "se-main",
+ "si-expressway",
+ "si-motorway",
+ "sk-highway",
+ "sk-road",
+ "us-interstate",
+ "us-interstate-business",
+ "us-interstate-duplex",
+ "us-interstate-truck",
+ "za-metropolitan",
+ "za-national",
+ "za-provincial",
+ "za-regional"
+ ]
+ ],
+ "layout": {
+ "text-size": 9,
+ "icon-image": "{shield}-{reflen}",
+ "icon-rotation-alignment": "viewport",
+ "text-max-angle": 38,
+ "symbol-spacing": {"base": 1, "stops": [[11, 150], [14, 200]]},
+ "text-font": ["DIN Offc Pro Bold", "Arial Unicode MS Bold"],
+ "symbol-placement": {
+ "base": 1,
+ "stops": [[10, "point"], [11, "line"]]
+ },
+ "text-padding": 2,
+ "text-rotation-alignment": "viewport",
+ "text-field": "{ref}",
+ "text-letter-spacing": 0.05,
+ "icon-padding": 2
+ },
+ "paint": {
+ "text-color": "hsl(0, 0%, 100%)",
+ "icon-halo-color": "rgba(0, 0, 0, 1)",
+ "icon-halo-width": 1,
+ "text-opacity": 1,
+ "icon-color": "white",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 0
+ }
+ },
+ {
+ "id": "motorway-junction",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444933575858.6992"},
+ "source": "composite",
+ "source-layer": "motorway_junction",
+ "minzoom": 14,
+ "filter": ["all", ["<=", "reflen", 9], [">", "reflen", 0]],
+ "layout": {
+ "text-field": "{ref}",
+ "text-size": 9,
+ "icon-image": "motorway-exit-{reflen}",
+ "text-font": ["DIN Offc Pro Bold", "Arial Unicode MS Bold"]
+ },
+ "paint": {
+ "text-color": "hsl(0, 0%, 100%)",
+ "text-translate": [0, 0]
+ }
+ },
+ {
+ "id": "poi-scalerank2",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444933358918.2366"},
+ "source": "composite",
+ "source-layer": "poi_label",
+ "filter": [
+ "all",
+ [
+ "!in",
+ "maki",
+ "campsite",
+ "cemetery",
+ "dog-park",
+ "garden",
+ "golf",
+ "park",
+ "picnic-site",
+ "playground",
+ "zoo"
+ ],
+ ["==", "scalerank", 2]
+ ],
+ "layout": {
+ "text-line-height": 1.1,
+ "text-size": {"base": 1, "stops": [[14, 11], [20, 14]]},
+ "icon-image": {"stops": [[14, "{maki}-11"], [15, "{maki}-15"]]},
+ "text-max-angle": 38,
+ "symbol-spacing": 250,
+ "text-font": [
+ "DIN Offc Pro Medium",
+ "Arial Unicode MS Regular"
+ ],
+ "text-padding": 2,
+ "text-offset": [0, 0.65],
+ "text-rotation-alignment": "viewport",
+ "text-anchor": "top",
+ "text-field": "{name_en}",
+ "text-letter-spacing": 0.01,
+ "text-max-width": 8
+ },
+ "paint": {
+ "text-color": "hsl(26, 25%, 32%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 0.5,
+ "text-halo-blur": 0.5
+ }
+ },
+ {
+ "id": "poi-parks-scalerank2",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444933358918.2366"},
+ "source": "composite",
+ "source-layer": "poi_label",
+ "filter": [
+ "all",
+ ["==", "scalerank", 2],
+ [
+ "in",
+ "maki",
+ "campsite",
+ "cemetery",
+ "dog-park",
+ "garden",
+ "golf",
+ "park",
+ "picnic-site",
+ "playground",
+ "zoo"
+ ]
+ ],
+ "layout": {
+ "text-line-height": 1.1,
+ "text-size": {"base": 1, "stops": [[14, 11], [20, 14]]},
+ "icon-image": {"stops": [[14, "{maki}-11"], [15, "{maki}-15"]]},
+ "text-max-angle": 38,
+ "symbol-spacing": 250,
+ "text-font": [
+ "DIN Offc Pro Medium",
+ "Arial Unicode MS Regular"
+ ],
+ "text-padding": 2,
+ "text-offset": [0, 0.65],
+ "text-rotation-alignment": "viewport",
+ "text-anchor": "top",
+ "text-field": "{name_en}",
+ "text-letter-spacing": 0.01,
+ "text-max-width": 8
+ },
+ "paint": {
+ "text-color": "hsl(100, 100%, 20%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 0.5,
+ "text-halo-blur": 0.5
+ }
+ },
+ {
+ "id": "rail-label",
+ "type": "symbol",
+ "source": "composite",
+ "source-layer": "rail_station_label",
+ "minzoom": 12,
+ "filter": ["!=", "maki", "entrance"],
+ "layout": {
+ "text-line-height": 1.1,
+ "text-size": {"base": 1, "stops": [[16, 11], [20, 13]]},
+ "icon-image": "{network}",
+ "symbol-spacing": 250,
+ "text-font": [
+ "DIN Offc Pro Medium",
+ "Arial Unicode MS Regular"
+ ],
+ "text-offset": [0, 0.85],
+ "text-rotation-alignment": "viewport",
+ "text-anchor": "top",
+ "text-field": {
+ "base": 1,
+ "stops": [[0, ""], [13, "{name_en}"]]
+ },
+ "text-letter-spacing": 0.01,
+ "icon-padding": 0,
+ "text-max-width": 7
+ },
+ "paint": {
+ "text-color": "hsl(230, 48%, 44%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 0.5,
+ "icon-halo-width": 4,
+ "icon-halo-color": "#fff",
+ "text-opacity": {"base": 1, "stops": [[13.99, 0], [14, 1]]},
+ "text-halo-blur": 0.5
+ }
+ },
+ {
+ "id": "water-label-sm",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444933808272.805"},
+ "source": "composite",
+ "source-layer": "water_label",
+ "minzoom": 15,
+ "filter": ["<=", "area", 10000],
+ "layout": {
+ "text-field": "{name_en}",
+ "text-font": [
+ "DIN Offc Pro Italic",
+ "Arial Unicode MS Regular"
+ ],
+ "text-max-width": 7,
+ "text-size": {"base": 1, "stops": [[16, 13], [20, 16]]}
+ },
+ "paint": {"text-color": "hsl(230, 48%, 44%)"}
+ },
+ {
+ "id": "water-label",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444933808272.805"},
+ "source": "composite",
+ "source-layer": "water_label",
+ "minzoom": 5,
+ "filter": [">", "area", 10000],
+ "layout": {
+ "text-field": "{name_en}",
+ "text-font": [
+ "DIN Offc Pro Italic",
+ "Arial Unicode MS Regular"
+ ],
+ "text-max-width": 7,
+ "text-size": {"base": 1, "stops": [[13, 13], [18, 18]]}
+ },
+ "paint": {"text-color": "hsl(230, 48%, 44%)"}
+ },
+ {
+ "id": "place-residential",
+ "type": "symbol",
+ "source": "composite",
+ "source-layer": "place_label",
+ "maxzoom": 18,
+ "filter": [
+ "all",
+ ["all", ["<=", "localrank", 10], ["==", "type", "residential"]],
+ ["in", "$type", "LineString", "Point", "Polygon"]
+ ],
+ "layout": {
+ "text-line-height": 1.2,
+ "text-size": {"base": 1, "stops": [[10, 11], [18, 14]]},
+ "text-max-angle": 38,
+ "symbol-spacing": 250,
+ "text-font": [
+ "DIN Offc Pro Regular",
+ "Arial Unicode MS Regular"
+ ],
+ "text-padding": 2,
+ "text-offset": [0, 0],
+ "text-rotation-alignment": "viewport",
+ "text-field": "{name_en}",
+ "text-max-width": 7
+ },
+ "paint": {
+ "text-color": "hsl(26, 25%, 32%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 1,
+ "text-halo-blur": 0.5
+ }
+ },
+ {
+ "id": "poi-parks-scalerank1",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444933322393.2852"},
+ "source": "composite",
+ "source-layer": "poi_label",
+ "filter": [
+ "all",
+ ["<=", "scalerank", 1],
+ [
+ "in",
+ "maki",
+ "campsite",
+ "cemetery",
+ "dog-park",
+ "garden",
+ "golf",
+ "park",
+ "picnic-site",
+ "playground",
+ "zoo"
+ ]
+ ],
+ "layout": {
+ "text-line-height": 1.1,
+ "text-size": {"base": 1, "stops": [[10, 11], [18, 14]]},
+ "icon-image": {"stops": [[13, "{maki}-11"], [14, "{maki}-15"]]},
+ "text-max-angle": 38,
+ "symbol-spacing": 250,
+ "text-font": [
+ "DIN Offc Pro Medium",
+ "Arial Unicode MS Regular"
+ ],
+ "text-padding": 2,
+ "text-offset": [0, 0.65],
+ "text-rotation-alignment": "viewport",
+ "text-anchor": "top",
+ "text-field": "{name_en}",
+ "text-letter-spacing": 0.01,
+ "text-max-width": 8
+ },
+ "paint": {
+ "text-color": "hsl(100, 100%, 20%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 0.5,
+ "text-halo-blur": 0.5
+ }
+ },
+ {
+ "id": "poi-scalerank1",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444933322393.2852"},
+ "source": "composite",
+ "source-layer": "poi_label",
+ "filter": [
+ "all",
+ [
+ "!in",
+ "maki",
+ "campsite",
+ "cemetery",
+ "dog-park",
+ "garden",
+ "golf",
+ "park",
+ "picnic-site",
+ "playground",
+ "zoo"
+ ],
+ ["<=", "scalerank", 1]
+ ],
+ "layout": {
+ "text-line-height": 1.1,
+ "text-size": {"base": 1, "stops": [[10, 11], [18, 14]]},
+ "icon-image": {"stops": [[13, "{maki}-11"], [14, "{maki}-15"]]},
+ "text-max-angle": 38,
+ "symbol-spacing": 250,
+ "text-font": [
+ "DIN Offc Pro Medium",
+ "Arial Unicode MS Regular"
+ ],
+ "text-padding": 2,
+ "text-offset": [0, 0.65],
+ "text-rotation-alignment": "viewport",
+ "text-anchor": "top",
+ "text-field": "{name_en}",
+ "text-letter-spacing": 0.01,
+ "text-max-width": 8
+ },
+ "paint": {
+ "text-color": "hsl(26, 25%, 32%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 0.5,
+ "text-halo-blur": 0.5
+ }
+ },
+ {
+ "id": "airport-label",
+ "type": "symbol",
+ "source": "composite",
+ "source-layer": "airport_label",
+ "minzoom": 9,
+ "filter": ["<=", "scalerank", 2],
+ "layout": {
+ "text-line-height": 1.1,
+ "text-size": {"base": 1, "stops": [[10, 12], [18, 18]]},
+ "icon-image": {"stops": [[12, "{maki}-11"], [13, "{maki}-15"]]},
+ "symbol-spacing": 250,
+ "text-font": [
+ "DIN Offc Pro Medium",
+ "Arial Unicode MS Regular"
+ ],
+ "text-padding": 2,
+ "text-offset": [0, 0.75],
+ "text-rotation-alignment": "viewport",
+ "text-anchor": "top",
+ "text-field": {"stops": [[11, "{ref}"], [12, "{name_en}"]]},
+ "text-letter-spacing": 0.01,
+ "text-max-width": 9
+ },
+ "paint": {
+ "text-color": "hsl(230, 48%, 44%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 0.5,
+ "text-halo-blur": 0.5
+ }
+ },
+ {
+ "id": "place-islet-archipelago-aboriginal",
+ "type": "symbol",
+ "source": "composite",
+ "source-layer": "place_label",
+ "maxzoom": 16,
+ "filter": [
+ "in",
+ "type",
+ "aboriginal_lands",
+ "archipelago",
+ "islet"
+ ],
+ "layout": {
+ "text-line-height": 1.2,
+ "text-size": {"base": 1, "stops": [[10, 11], [18, 16]]},
+ "text-max-angle": 38,
+ "symbol-spacing": 250,
+ "text-font": [
+ "DIN Offc Pro Regular",
+ "Arial Unicode MS Regular"
+ ],
+ "text-padding": 2,
+ "text-offset": [0, 0],
+ "text-rotation-alignment": "viewport",
+ "text-field": "{name_en}",
+ "text-letter-spacing": 0.01,
+ "text-max-width": 8
+ },
+ "paint": {
+ "text-color": "hsl(230, 29%, 35%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 1
+ }
+ },
+ {
+ "id": "place-neighbourhood",
+ "type": "symbol",
+ "source": "composite",
+ "source-layer": "place_label",
+ "minzoom": 10,
+ "maxzoom": 16,
+ "filter": ["==", "type", "neighbourhood"],
+ "layout": {
+ "text-field": "{name_en}",
+ "text-transform": "uppercase",
+ "text-letter-spacing": 0.1,
+ "text-max-width": 7,
+ "text-font": [
+ "DIN Offc Pro Regular",
+ "Arial Unicode MS Regular"
+ ],
+ "text-padding": 3,
+ "text-size": {"base": 1, "stops": [[12, 11], [16, 16]]}
+ },
+ "paint": {
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 1,
+ "text-color": "hsl(230, 29%, 35%)",
+ "text-halo-blur": 0.5
+ }
+ },
+ {
+ "id": "place-suburb",
+ "type": "symbol",
+ "source": "composite",
+ "source-layer": "place_label",
+ "minzoom": 10,
+ "maxzoom": 16,
+ "filter": ["==", "type", "suburb"],
+ "layout": {
+ "text-field": "{name_en}",
+ "text-transform": "uppercase",
+ "text-font": [
+ "DIN Offc Pro Regular",
+ "Arial Unicode MS Regular"
+ ],
+ "text-letter-spacing": 0.15,
+ "text-max-width": 7,
+ "text-padding": 3,
+ "text-size": {"base": 1, "stops": [[11, 11], [15, 18]]}
+ },
+ "paint": {
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 1,
+ "text-color": "hsl(230, 29%, 35%)",
+ "text-halo-blur": 0.5
+ }
+ },
+ {
+ "id": "place-hamlet",
+ "type": "symbol",
+ "source": "composite",
+ "source-layer": "place_label",
+ "minzoom": 10,
+ "maxzoom": 16,
+ "filter": ["==", "type", "hamlet"],
+ "layout": {
+ "text-field": "{name_en}",
+ "text-font": [
+ "DIN Offc Pro Regular",
+ "Arial Unicode MS Regular"
+ ],
+ "text-size": {"base": 1, "stops": [[12, 11.5], [15, 16]]}
+ },
+ "paint": {
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 1.25,
+ "text-color": "hsl(0, 0%, 0%)"
+ }
+ },
+ {
+ "id": "place-village",
+ "type": "symbol",
+ "source": "composite",
+ "source-layer": "place_label",
+ "minzoom": 8,
+ "maxzoom": 15,
+ "filter": ["==", "type", "village"],
+ "layout": {
+ "text-field": "{name_en}",
+ "text-font": [
+ "DIN Offc Pro Regular",
+ "Arial Unicode MS Regular"
+ ],
+ "text-max-width": 7,
+ "text-size": {"base": 1, "stops": [[10, 11.5], [16, 18]]}
+ },
+ "paint": {
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 1.25,
+ "text-color": "hsl(0, 0%, 0%)"
+ }
+ },
+ {
+ "id": "place-town",
+ "type": "symbol",
+ "source": "composite",
+ "source-layer": "place_label",
+ "minzoom": 6,
+ "maxzoom": 15,
+ "filter": ["==", "type", "town"],
+ "layout": {
+ "icon-image": "dot-9",
+ "text-font": {
+ "base": 1,
+ "stops": [
+ [
+ 11,
+ ["DIN Offc Pro Regular", "Arial Unicode MS Regular"]
+ ],
+ [
+ 12,
+ ["DIN Offc Pro Medium", "Arial Unicode MS Regular"]
+ ]
+ ]
+ },
+ "text-offset": {
+ "base": 1,
+ "stops": [[7, [0, -0.15]], [8, [0, 0]]]
+ },
+ "text-anchor": {
+ "base": 1,
+ "stops": [[7, "bottom"], [8, "center"]]
+ },
+ "text-field": "{name_en}",
+ "text-max-width": 7,
+ "text-size": {"base": 1, "stops": [[7, 11.5], [15, 20]]}
+ },
+ "paint": {
+ "text-color": "hsl(0, 0%, 0%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 1.25,
+ "icon-opacity": {"base": 1, "stops": [[7.99, 1], [8, 0]]}
+ }
+ },
+ {
+ "id": "place-island",
+ "type": "symbol",
+ "source": "composite",
+ "source-layer": "place_label",
+ "maxzoom": 16,
+ "filter": ["==", "type", "island"],
+ "layout": {
+ "text-line-height": 1.2,
+ "text-size": {"base": 1, "stops": [[10, 11], [18, 16]]},
+ "text-max-angle": 38,
+ "symbol-spacing": 250,
+ "text-font": [
+ "DIN Offc Pro Regular",
+ "Arial Unicode MS Regular"
+ ],
+ "text-padding": 2,
+ "text-offset": [0, 0],
+ "text-rotation-alignment": "viewport",
+ "text-field": "{name_en}",
+ "text-letter-spacing": 0.01,
+ "text-max-width": 7
+ },
+ "paint": {
+ "text-color": "hsl(230, 29%, 35%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 1
+ }
+ },
+ {
+ "id": "place-city-sm",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444862510685.128"},
+ "source": "composite",
+ "source-layer": "place_label",
+ "maxzoom": 14,
+ "filter": [
+ "all",
+ ["!in", "scalerank", 0, 1, 2, 3, 4, 5],
+ ["==", "type", "city"]
+ ],
+ "layout": {
+ "text-size": {"base": 1, "stops": [[6, 12], [14, 22]]},
+ "icon-image": "dot-9",
+ "text-font": {
+ "base": 1,
+ "stops": [
+ [
+ 7,
+ ["DIN Offc Pro Regular", "Arial Unicode MS Regular"]
+ ],
+ [8, ["DIN Offc Pro Medium", "Arial Unicode MS Regular"]]
+ ]
+ },
+ "text-offset": {
+ "base": 1,
+ "stops": [[7.99, [0, -0.2]], [8, [0, 0]]]
+ },
+ "text-anchor": {
+ "base": 1,
+ "stops": [[7, "bottom"], [8, "center"]]
+ },
+ "text-field": "{name_en}",
+ "text-max-width": 7
+ },
+ "paint": {
+ "text-color": "hsl(0, 0%, 0%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 1.25,
+ "icon-opacity": {"base": 1, "stops": [[7.99, 1], [8, 0]]}
+ }
+ },
+ {
+ "id": "place-city-md-s",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444862510685.128"},
+ "source": "composite",
+ "source-layer": "place_label",
+ "maxzoom": 14,
+ "filter": [
+ "all",
+ ["==", "type", "city"],
+ ["in", "ldir", "E", "S", "SE", "SW"],
+ ["in", "scalerank", 3, 4, 5]
+ ],
+ "layout": {
+ "text-field": "{name_en}",
+ "icon-image": "dot-10",
+ "text-anchor": {
+ "base": 1,
+ "stops": [[7, "top"], [8, "center"]]
+ },
+ "text-offset": {
+ "base": 1,
+ "stops": [[7.99, [0, 0.1]], [8, [0, 0]]]
+ },
+ "text-font": {
+ "base": 1,
+ "stops": [
+ [
+ 7,
+ ["DIN Offc Pro Regular", "Arial Unicode MS Regular"]
+ ],
+ [8, ["DIN Offc Pro Medium", "Arial Unicode MS Regular"]]
+ ]
+ },
+ "text-size": {"base": 0.9, "stops": [[5, 12], [12, 22]]}
+ },
+ "paint": {
+ "text-halo-width": 1,
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-color": "hsl(0, 0%, 0%)",
+ "text-halo-blur": 1,
+ "icon-opacity": {"base": 1, "stops": [[7.99, 1], [8, 0]]}
+ }
+ },
+ {
+ "id": "place-city-md-n",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444862510685.128"},
+ "source": "composite",
+ "source-layer": "place_label",
+ "maxzoom": 14,
+ "filter": [
+ "all",
+ ["==", "type", "city"],
+ ["in", "ldir", "N", "NE", "NW", "W"],
+ ["in", "scalerank", 3, 4, 5]
+ ],
+ "layout": {
+ "icon-image": "dot-10",
+ "text-font": {
+ "base": 1,
+ "stops": [
+ [
+ 7,
+ ["DIN Offc Pro Regular", "Arial Unicode MS Regular"]
+ ],
+ [8, ["DIN Offc Pro Medium", "Arial Unicode MS Regular"]]
+ ]
+ },
+ "text-offset": {
+ "base": 1,
+ "stops": [[7.99, [0, -0.25]], [8, [0, 0]]]
+ },
+ "text-anchor": {
+ "base": 1,
+ "stops": [[7, "bottom"], [8, "center"]]
+ },
+ "text-field": "{name_en}",
+ "text-max-width": 7,
+ "text-size": {"base": 0.9, "stops": [[5, 12], [12, 22]]}
+ },
+ "paint": {
+ "text-color": "hsl(0, 0%, 0%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 1,
+ "icon-opacity": {"base": 1, "stops": [[7.99, 1], [8, 0]]},
+ "text-halo-blur": 1
+ }
+ },
+ {
+ "id": "place-city-lg-s",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444862510685.128"},
+ "source": "composite",
+ "source-layer": "place_label",
+ "minzoom": 1,
+ "maxzoom": 14,
+ "filter": [
+ "all",
+ ["<=", "scalerank", 2],
+ ["==", "type", "city"],
+ ["in", "ldir", "E", "S", "SE", "SW"]
+ ],
+ "layout": {
+ "icon-image": "dot-11",
+ "text-font": {
+ "base": 1,
+ "stops": [
+ [
+ 7,
+ ["DIN Offc Pro Regular", "Arial Unicode MS Regular"]
+ ],
+ [8, ["DIN Offc Pro Medium", "Arial Unicode MS Regular"]]
+ ]
+ },
+ "text-offset": {
+ "base": 1,
+ "stops": [[7.99, [0, 0.15]], [8, [0, 0]]]
+ },
+ "text-anchor": {
+ "base": 1,
+ "stops": [[7, "top"], [8, "center"]]
+ },
+ "text-field": "{name_en}",
+ "text-max-width": 7,
+ "text-size": {"base": 0.9, "stops": [[4, 12], [10, 22]]}
+ },
+ "paint": {
+ "text-color": "hsl(0, 0%, 0%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 1,
+ "icon-opacity": {"base": 1, "stops": [[7.99, 1], [8, 0]]},
+ "text-halo-blur": 1
+ }
+ },
+ {
+ "id": "place-city-lg-n",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444862510685.128"},
+ "source": "composite",
+ "source-layer": "place_label",
+ "minzoom": 1,
+ "maxzoom": 14,
+ "filter": [
+ "all",
+ ["<=", "scalerank", 2],
+ ["==", "type", "city"],
+ ["in", "ldir", "N", "NE", "NW", "W"]
+ ],
+ "layout": {
+ "icon-image": "dot-11",
+ "text-font": {
+ "base": 1,
+ "stops": [
+ [
+ 7,
+ ["DIN Offc Pro Regular", "Arial Unicode MS Regular"]
+ ],
+ [8, ["DIN Offc Pro Medium", "Arial Unicode MS Regular"]]
+ ]
+ },
+ "text-offset": {
+ "base": 1,
+ "stops": [[7.99, [0, -0.25]], [8, [0, 0]]]
+ },
+ "text-anchor": {
+ "base": 1,
+ "stops": [[7, "bottom"], [8, "center"]]
+ },
+ "text-field": "{name_en}",
+ "text-max-width": 7,
+ "text-size": {"base": 0.9, "stops": [[4, 12], [10, 22]]}
+ },
+ "paint": {
+ "text-color": "hsl(0, 0%, 0%)",
+ "text-opacity": 1,
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 1,
+ "icon-opacity": {"base": 1, "stops": [[7.99, 1], [8, 0]]},
+ "text-halo-blur": 1
+ }
+ },
+ {
+ "id": "marine-label-sm-ln",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444856087950.3635"},
+ "source": "composite",
+ "source-layer": "marine_label",
+ "minzoom": 3,
+ "maxzoom": 10,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ [">=", "labelrank", 4]
+ ],
+ "layout": {
+ "text-line-height": 1.1,
+ "text-size": {"base": 1, "stops": [[3, 12], [6, 16]]},
+ "symbol-spacing": {"base": 1, "stops": [[4, 100], [6, 400]]},
+ "text-font": [
+ "DIN Offc Pro Italic",
+ "Arial Unicode MS Regular"
+ ],
+ "symbol-placement": "line",
+ "text-pitch-alignment": "viewport",
+ "text-field": "{name_en}",
+ "text-letter-spacing": 0.1,
+ "text-max-width": 5
+ },
+ "paint": {"text-color": "hsl(205, 83%, 88%)"}
+ },
+ {
+ "id": "marine-label-sm-pt",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444856087950.3635"},
+ "source": "composite",
+ "source-layer": "marine_label",
+ "minzoom": 3,
+ "maxzoom": 10,
+ "filter": ["all", ["==", "$type", "Point"], [">=", "labelrank", 4]],
+ "layout": {
+ "text-field": "{name_en}",
+ "text-max-width": 5,
+ "text-letter-spacing": 0.1,
+ "text-line-height": 1.5,
+ "text-font": [
+ "DIN Offc Pro Italic",
+ "Arial Unicode MS Regular"
+ ],
+ "text-size": {"base": 1, "stops": [[3, 12], [6, 16]]}
+ },
+ "paint": {"text-color": "hsl(205, 83%, 88%)"}
+ },
+ {
+ "id": "marine-label-md-ln",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444856087950.3635"},
+ "source": "composite",
+ "source-layer": "marine_label",
+ "minzoom": 2,
+ "maxzoom": 8,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ ["in", "labelrank", 2, 3]
+ ],
+ "layout": {
+ "text-line-height": 1.1,
+ "text-size": {"base": 1.1, "stops": [[2, 12], [5, 20]]},
+ "symbol-spacing": 250,
+ "text-font": [
+ "DIN Offc Pro Italic",
+ "Arial Unicode MS Regular"
+ ],
+ "symbol-placement": "line",
+ "text-pitch-alignment": "viewport",
+ "text-field": "{name_en}",
+ "text-letter-spacing": 0.15,
+ "text-max-width": 5
+ },
+ "paint": {"text-color": "hsl(205, 83%, 88%)"}
+ },
+ {
+ "id": "marine-label-md-pt",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444856087950.3635"},
+ "source": "composite",
+ "source-layer": "marine_label",
+ "minzoom": 2,
+ "maxzoom": 8,
+ "filter": [
+ "all",
+ ["==", "$type", "Point"],
+ ["in", "labelrank", 2, 3]
+ ],
+ "layout": {
+ "text-field": "{name_en}",
+ "text-max-width": 5,
+ "text-letter-spacing": 0.15,
+ "text-line-height": 1.5,
+ "text-font": [
+ "DIN Offc Pro Italic",
+ "Arial Unicode MS Regular"
+ ],
+ "text-size": {"base": 1.1, "stops": [[2, 14], [5, 20]]}
+ },
+ "paint": {"text-color": "hsl(205, 83%, 88%)"}
+ },
+ {
+ "id": "marine-label-lg-ln",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444856087950.3635"},
+ "source": "composite",
+ "source-layer": "marine_label",
+ "minzoom": 1,
+ "maxzoom": 4,
+ "filter": [
+ "all",
+ ["==", "$type", "LineString"],
+ ["==", "labelrank", 1]
+ ],
+ "layout": {
+ "text-field": "{name_en}",
+ "text-max-width": 4,
+ "text-letter-spacing": 0.25,
+ "text-line-height": 1.1,
+ "symbol-placement": "line",
+ "text-pitch-alignment": "viewport",
+ "text-font": [
+ "DIN Offc Pro Italic",
+ "Arial Unicode MS Regular"
+ ],
+ "text-size": {"base": 1, "stops": [[1, 14], [4, 30]]}
+ },
+ "paint": {"text-color": "hsl(205, 83%, 88%)"}
+ },
+ {
+ "id": "marine-label-lg-pt",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444856087950.3635"},
+ "source": "composite",
+ "source-layer": "marine_label",
+ "minzoom": 1,
+ "maxzoom": 4,
+ "filter": ["all", ["==", "$type", "Point"], ["==", "labelrank", 1]],
+ "layout": {
+ "text-field": "{name_en}",
+ "text-max-width": 4,
+ "text-letter-spacing": 0.25,
+ "text-line-height": 1.5,
+ "text-font": [
+ "DIN Offc Pro Italic",
+ "Arial Unicode MS Regular"
+ ],
+ "text-size": {"base": 1, "stops": [[1, 14], [4, 30]]}
+ },
+ "paint": {"text-color": "hsl(205, 83%, 88%)"}
+ },
+ {
+ "id": "state-label-sm",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444856151690.9143"},
+ "source": "composite",
+ "source-layer": "state_label",
+ "minzoom": 3,
+ "maxzoom": 9,
+ "filter": ["<", "area", 20000],
+ "layout": {
+ "text-size": {"base": 1, "stops": [[6, 10], [9, 14]]},
+ "text-transform": "uppercase",
+ "text-font": ["DIN Offc Pro Bold", "Arial Unicode MS Bold"],
+ "text-field": {
+ "base": 1,
+ "stops": [[0, "{abbr}"], [6, "{name_en}"]]
+ },
+ "text-letter-spacing": 0.15,
+ "text-max-width": 5
+ },
+ "paint": {
+ "text-opacity": 1,
+ "text-color": "hsl(0, 0%, 0%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 1
+ }
+ },
+ {
+ "id": "state-label-md",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444856151690.9143"},
+ "source": "composite",
+ "source-layer": "state_label",
+ "minzoom": 3,
+ "maxzoom": 8,
+ "filter": ["all", ["<", "area", 80000], [">=", "area", 20000]],
+ "layout": {
+ "text-size": {"base": 1, "stops": [[5, 10], [8, 16]]},
+ "text-transform": "uppercase",
+ "text-font": ["DIN Offc Pro Bold", "Arial Unicode MS Bold"],
+ "text-field": {
+ "base": 1,
+ "stops": [[0, "{abbr}"], [5, "{name_en}"]]
+ },
+ "text-letter-spacing": 0.15,
+ "text-max-width": 6
+ },
+ "paint": {
+ "text-opacity": 1,
+ "text-color": "hsl(0, 0%, 0%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 1
+ }
+ },
+ {
+ "id": "state-label-lg",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444856151690.9143"},
+ "source": "composite",
+ "source-layer": "state_label",
+ "minzoom": 3,
+ "maxzoom": 7,
+ "filter": [">=", "area", 80000],
+ "layout": {
+ "text-size": {"base": 1, "stops": [[4, 10], [7, 18]]},
+ "text-transform": "uppercase",
+ "text-font": ["DIN Offc Pro Bold", "Arial Unicode MS Bold"],
+ "text-padding": 1,
+ "text-field": {
+ "base": 1,
+ "stops": [[0, "{abbr}"], [4, "{name_en}"]]
+ },
+ "text-letter-spacing": 0.15,
+ "text-max-width": 6
+ },
+ "paint": {
+ "text-opacity": 1,
+ "text-color": "hsl(0, 0%, 0%)",
+ "text-halo-color": "hsl(0, 0%, 100%)",
+ "text-halo-width": 1
+ }
+ },
+ {
+ "id": "country-label-sm",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444856144497.7825"},
+ "source": "composite",
+ "source-layer": "country_label",
+ "minzoom": 1,
+ "maxzoom": 10,
+ "filter": [">=", "scalerank", 5],
+ "layout": {
+ "text-field": "{name_en}",
+ "text-max-width": 6,
+ "text-font": [
+ "DIN Offc Pro Medium",
+ "Arial Unicode MS Regular"
+ ],
+ "text-size": {"base": 0.9, "stops": [[5, 14], [9, 22]]}
+ },
+ "paint": {
+ "text-color": "hsl(0, 0%, 0%)",
+ "text-halo-color": {
+ "base": 1,
+ "stops": [
+ [2, "rgba(255,255,255,0.75)"],
+ [3, "hsl(0, 0%, 100%)"]
+ ]
+ },
+ "text-halo-width": 1.25
+ }
+ },
+ {
+ "id": "country-label-md",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444856144497.7825"},
+ "source": "composite",
+ "source-layer": "country_label",
+ "minzoom": 1,
+ "maxzoom": 8,
+ "filter": ["in", "scalerank", 3, 4],
+ "layout": {
+ "text-field": {
+ "base": 1,
+ "stops": [[0, "{code}"], [2, "{name_en}"]]
+ },
+ "text-max-width": 6,
+ "text-font": [
+ "DIN Offc Pro Medium",
+ "Arial Unicode MS Regular"
+ ],
+ "text-size": {"base": 1, "stops": [[3, 10], [8, 24]]}
+ },
+ "paint": {
+ "text-color": "hsl(0, 0%, 0%)",
+ "text-halo-color": {
+ "base": 1,
+ "stops": [
+ [2, "rgba(255,255,255,0.75)"],
+ [3, "hsl(0, 0%, 100%)"]
+ ]
+ },
+ "text-halo-width": 1.25
+ }
+ },
+ {
+ "id": "country-label-lg",
+ "type": "symbol",
+ "metadata": {"mapbox:group": "1444856144497.7825"},
+ "source": "composite",
+ "source-layer": "country_label",
+ "minzoom": 1,
+ "maxzoom": 7,
+ "filter": ["in", "scalerank", 1, 2],
+ "layout": {
+ "text-field": "{name_en}",
+ "text-max-width": {"base": 1, "stops": [[0, 5], [3, 6]]},
+ "text-font": [
+ "DIN Offc Pro Medium",
+ "Arial Unicode MS Regular"
+ ],
+ "text-size": {"base": 1, "stops": [[1, 10], [6, 24]]}
+ },
+ "paint": {
+ "text-color": "hsl(0, 0%, 0%)",
+ "text-halo-color": {
+ "base": 1,
+ "stops": [
+ [2, "rgba(255,255,255,0.75)"],
+ [3, "hsl(0, 0%, 100%)"]
+ ]
+ },
+ "text-halo-width": 1.25
+ }
+ }
+ ],
+ "created": "2018-10-22T14:13:43.210Z",
+ "id": "cjnkdt02b0b2p2ss40skwpvs1",
+ "modified": "2018-10-22T14:14:35.211Z",
+ "owner": "lukaspaczos",
+ "visibility": "public",
+ "draft": false
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/InstrumentationApplication.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/InstrumentationApplication.kt
new file mode 100644
index 0000000000..ea48bdc00f
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/InstrumentationApplication.kt
@@ -0,0 +1,10 @@
+package com.mapbox.mapboxsdk
+
+import com.mapbox.mapboxsdk.testapp.MapboxApplication
+
+class InstrumentationApplication : MapboxApplication() {
+ override fun initializeLeakCanary(): Boolean {
+ // do not initialize leak canary during instrumentation tests
+ return true
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/InstrumentationRunner.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/InstrumentationRunner.kt
new file mode 100644
index 0000000000..6873b33262
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/InstrumentationRunner.kt
@@ -0,0 +1,11 @@
+package com.mapbox.mapboxsdk
+
+import android.app.Application
+import android.content.Context
+import android.support.test.runner.AndroidJUnitRunner
+
+class InstrumentationRunner : AndroidJUnitRunner() {
+ override fun newApplication(cl: ClassLoader?, className: String?, context: Context?): Application {
+ return super.newApplication(cl, InstrumentationApplication::class.java.name, context)
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/BaseIntegrationTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/BaseIntegrationTest.kt
new file mode 100644
index 0000000000..aeb8863790
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/BaseIntegrationTest.kt
@@ -0,0 +1,39 @@
+package com.mapbox.mapboxsdk.integration
+
+import android.content.Context
+import android.content.Intent
+import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
+import android.support.test.InstrumentationRegistry
+import android.support.test.uiautomator.*
+import org.junit.Before
+
+const val TIMEOUT_UI_SEARCH_WAIT = 5000L
+
+abstract class BaseIntegrationTest {
+
+ protected lateinit var device: UiDevice
+
+ @Before
+ open fun beforeTest() {
+ device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ }
+}
+
+/**
+ * Launches an activity with FLAG_ACTIVITY_NEW_TASK.
+ * <p>
+ * To resume an activity, you need to add a single instance launchmode to your manifest configuration.
+ * <p>
+ */
+fun UiDevice.launchActivity(context: Context, clazz: Class<*>) {
+ val applicationPackage = InstrumentationRegistry.getTargetContext().packageName
+ val intent = Intent(context, clazz)
+ intent.addFlags(FLAG_ACTIVITY_NEW_TASK)
+ InstrumentationRegistry.getContext().startActivity(intent)
+ wait(Until.hasObject(By.pkg(applicationPackage).depth(0)), TIMEOUT_UI_SEARCH_WAIT)
+}
+
+fun UiDevice.scrollRecyclerViewTo(recycleItem: String) {
+ val appView = UiScrollable(UiSelector().scrollable(true))
+ appView.scrollIntoView(UiSelector().text(recycleItem))
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/FragmentBackStackTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/FragmentBackStackTest.kt
new file mode 100644
index 0000000000..b0f6436bdd
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/FragmentBackStackTest.kt
@@ -0,0 +1,52 @@
+package com.mapbox.mapboxsdk.integration
+
+import android.support.test.filters.LargeTest
+import android.support.test.rule.ActivityTestRule
+import android.support.test.runner.AndroidJUnit4
+import android.support.test.uiautomator.By
+import android.support.test.uiautomator.SearchCondition
+import android.support.test.uiautomator.UiSelector
+import android.support.test.uiautomator.Until
+import com.mapbox.mapboxsdk.testapp.R
+import com.mapbox.mapboxsdk.testapp.activity.fragment.FragmentBackStackActivity
+import com.mapbox.mapboxsdk.testapp.activity.maplayout.SimpleMapActivity
+import kotlinx.android.synthetic.main.activity_backstack_fragment.view.*
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Regression test that validates MapFragment integration on the backstack
+ */
+@RunWith(AndroidJUnit4::class)
+class FragmentBackStackTest : BaseIntegrationTest() {
+
+ @get:Rule
+ var activityRule: ActivityTestRule<FragmentBackStackActivity> = ActivityTestRule(FragmentBackStackActivity::class.java)
+
+ @Test
+ @LargeTest
+ fun backPressedOnBackStackResumed() {
+ device.waitForIdle()
+ clickReplaceFragmentButton()
+ device.pressHome()
+ device.waitForIdle()
+ device.launchActivity(activityRule.activity.applicationContext, FragmentBackStackActivity::class.java)
+ backPressBackStack()
+ device.waitForIdle()
+ }
+
+ private fun clickReplaceFragmentButton() {
+ device.findObject(UiSelector().description(textDescription)).click()
+ }
+
+ private fun backPressBackStack() {
+ device.pressBack() // pops fragment, showing map
+ device.pressBack() // finish activity
+ }
+
+ private companion object {
+ const val textDescription = "btn_change_fragment"
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/GLSurfaceViewReopenTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/GLSurfaceViewReopenTest.kt
new file mode 100644
index 0000000000..f22b5f7c9d
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/GLSurfaceViewReopenTest.kt
@@ -0,0 +1,30 @@
+package com.mapbox.mapboxsdk.integration
+
+import android.support.test.filters.LargeTest
+import android.support.test.rule.ActivityTestRule
+import android.support.test.runner.AndroidJUnit4
+import com.mapbox.mapboxsdk.testapp.activity.maplayout.SimpleMapActivity
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+
+/**
+ * Regression test that validates reopening an Activity with a GLSurfaceView
+ */
+@RunWith(AndroidJUnit4::class)
+class GLSurfaceViewReopenTest : BaseIntegrationTest() {
+
+ @get:Rule
+ var activityRule: ActivityTestRule<SimpleMapActivity> = ActivityTestRule(SimpleMapActivity::class.java)
+
+ @Test
+ @LargeTest
+ fun reopenSimpleMapActivity() {
+ device.waitForIdle()
+ device.pressHome()
+ device.waitForIdle()
+ device.launchActivity(activityRule.activity, SimpleMapActivity::class.java)
+ device.waitForIdle()
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/GLSurfaceViewReuseTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/GLSurfaceViewReuseTest.kt
new file mode 100644
index 0000000000..945fac677e
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/GLSurfaceViewReuseTest.kt
@@ -0,0 +1,31 @@
+package com.mapbox.mapboxsdk.integration
+
+import android.support.test.filters.LargeTest
+import android.support.test.rule.ActivityTestRule
+import android.support.test.runner.AndroidJUnit4
+import com.mapbox.mapboxsdk.testapp.activity.maplayout.GLSurfaceRecyclerViewActivity
+import com.mapbox.mapboxsdk.testapp.activity.maplayout.SimpleMapActivity
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Regression test that validates if a GLSurfaceView surface can be recreated without crashing.
+ */
+@RunWith(AndroidJUnit4::class)
+class GLSurfaceViewReuseTest : BaseIntegrationTest() {
+
+ @get:Rule
+ var activityRule: ActivityTestRule<GLSurfaceRecyclerViewActivity> = ActivityTestRule(GLSurfaceRecyclerViewActivity::class.java)
+
+ @Test
+ @LargeTest
+ fun scrollRecyclerView() {
+ device.waitForIdle()
+ device.scrollRecyclerViewTo("Twenty-one")
+ device.waitForIdle()
+ device.scrollRecyclerViewTo("One")
+ device.waitForIdle()
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/OrientationChangeTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/OrientationChangeTest.kt
new file mode 100644
index 0000000000..941b7ea8dc
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/OrientationChangeTest.kt
@@ -0,0 +1,34 @@
+package com.mapbox.mapboxsdk.integration
+
+import android.support.test.filters.LargeTest
+import android.support.test.rule.ActivityTestRule
+import android.support.test.runner.AndroidJUnit4
+import com.mapbox.mapboxsdk.testapp.activity.maplayout.GLSurfaceRecyclerViewActivity
+import com.mapbox.mapboxsdk.testapp.activity.maplayout.SimpleMapActivity
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class OrientationChangeTest : BaseIntegrationTest() {
+
+ @get:Rule
+ var activityRule: ActivityTestRule<SimpleMapActivity> = ActivityTestRule(SimpleMapActivity::class.java)
+
+ @Test
+ @LargeTest
+ fun rotateSimpleMap() {
+ device.setOrientationLeft()
+ device.waitForIdle()
+ device.setOrientationNatural()
+ device.waitForIdle()
+ device.setOrientationRight()
+ device.waitForIdle()
+ device.setOrientationNatural()
+ device.setOrientationLeft()
+ device.setOrientationNatural()
+ device.setOrientationRight()
+ device.setOrientationNatural()
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/TextureViewReopenTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/TextureViewReopenTest.kt
new file mode 100644
index 0000000000..44da557904
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/TextureViewReopenTest.kt
@@ -0,0 +1,33 @@
+package com.mapbox.mapboxsdk.integration
+
+import android.support.test.filters.LargeTest
+import android.support.test.rule.ActivityTestRule
+import android.support.test.runner.AndroidJUnit4
+import com.mapbox.mapboxsdk.testapp.activity.maplayout.GLSurfaceRecyclerViewActivity
+import com.mapbox.mapboxsdk.testapp.activity.maplayout.SimpleMapActivity
+import com.mapbox.mapboxsdk.testapp.activity.textureview.TextureViewDebugModeActivity
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import java.lang.Thread.sleep
+
+/**
+ * Regression test that validates reopening an Activity with a TextureView
+ */
+@RunWith(AndroidJUnit4::class)
+class TextureViewReopenTest : BaseIntegrationTest() {
+
+ @get:Rule
+ var activityRule: ActivityTestRule<TextureViewDebugModeActivity> = ActivityTestRule(TextureViewDebugModeActivity::class.java)
+
+ @Test
+ @LargeTest
+ fun reopenTextureViewDebugActivity() {
+ device.waitForIdle()
+ device.pressHome()
+ device.waitForIdle()
+ device.launchActivity(activityRule.activity, TextureViewDebugModeActivity::class.java)
+ device.waitForIdle()
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/TextureViewReuseTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/TextureViewReuseTest.kt
new file mode 100644
index 0000000000..5c3d66c462
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/TextureViewReuseTest.kt
@@ -0,0 +1,31 @@
+package com.mapbox.mapboxsdk.integration
+
+import android.support.test.filters.LargeTest
+import android.support.test.rule.ActivityTestRule
+import android.support.test.runner.AndroidJUnit4
+import com.mapbox.mapboxsdk.testapp.activity.maplayout.GLSurfaceRecyclerViewActivity
+import com.mapbox.mapboxsdk.testapp.activity.maplayout.TextureRecyclerViewActivity
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Regression test that validates if a GLSurfaceView surface can be recreated without crashing.
+ */
+@RunWith(AndroidJUnit4::class)
+class TextureViewReuseTest : BaseIntegrationTest() {
+
+ @get:Rule
+ var activityRule: ActivityTestRule<TextureRecyclerViewActivity> = ActivityTestRule(TextureRecyclerViewActivity::class.java)
+
+ @Test
+ @LargeTest
+ fun scrollRecyclerView() {
+ device.waitForIdle()
+ device.scrollRecyclerViewTo("Twenty-one")
+ device.waitForIdle()
+ device.scrollRecyclerViewTo("One")
+ device.waitForIdle()
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/ViewPagerScrollTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/ViewPagerScrollTest.kt
new file mode 100644
index 0000000000..b918801296
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/integration/ViewPagerScrollTest.kt
@@ -0,0 +1,38 @@
+package com.mapbox.mapboxsdk.integration
+
+import android.support.test.filters.LargeTest
+import android.support.test.rule.ActivityTestRule
+import android.support.test.runner.AndroidJUnit4
+import android.support.test.uiautomator.UiSelector
+import com.mapbox.mapboxsdk.testapp.activity.fragment.ViewPagerActivity
+import com.mapbox.mapboxsdk.testapp.activity.maplayout.GLSurfaceRecyclerViewActivity
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Regression test that validates MapFragment integration with a ViewPager
+ */
+@RunWith(AndroidJUnit4::class)
+class ViewPagerScrollTest : BaseIntegrationTest() {
+
+ @get:Rule
+ var activityRule: ActivityTestRule<ViewPagerActivity> = ActivityTestRule(ViewPagerActivity::class.java)
+
+ @Test
+ @LargeTest
+ fun scrollViewPager() {
+ for (i in 1..4) {
+ clickTab(i)
+ }
+
+ for (i in 3 downTo 0) {
+ clickTab(i)
+ }
+ }
+
+ private fun clickTab(index: Int) {
+ device.findObject(UiSelector().text("Page $index")).click()
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt
index dde03d8a14..f9827c767e 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt
@@ -82,7 +82,7 @@ class LocationComponentTest : EspressoTest() {
val locationEngine = component.locationEngine
assertThat(locationEngine, notNullValue())
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
}
}
@@ -118,7 +118,7 @@ class LocationComponentTest : EspressoTest() {
assertThat(locationEngine, notNullValue())
assertThat(componentOptions, notNullValue())
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(componentOptions?.accuracyAlpha(), `is`(.5f))
assertThat(componentOptions?.accuracyColor(), `is`(Color.BLUE))
}
@@ -157,7 +157,7 @@ class LocationComponentTest : EspressoTest() {
assertThat(locationEngine, nullValue())
assertThat(componentOptions, notNullValue())
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(componentOptions?.accuracyAlpha(), `is`(.5f))
assertThat(componentOptions?.accuracyColor(), `is`(Color.BLUE))
}
@@ -205,7 +205,7 @@ class LocationComponentTest : EspressoTest() {
// Force the first location update
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
// Check if the puck is visible
assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(false))
@@ -240,7 +240,7 @@ class LocationComponentTest : EspressoTest() {
component.isLocationComponentEnabled = true
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
uiController.loopMainThreadForAtLeast(300) // waiting for stale state
mapboxMap.querySourceFeatures(LOCATION_SOURCE).also { feature ->
@@ -287,7 +287,7 @@ class LocationComponentTest : EspressoTest() {
}
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
val feature = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0]
assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(false))
@@ -329,7 +329,7 @@ class LocationComponentTest : EspressoTest() {
mapboxMap.addImageFromDrawable("custom-foreground-bitmap", it)
mapboxMap.addImageFromDrawable("custom-gps-bitmap", it)
}
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
val foregroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON)
assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap")))
@@ -360,13 +360,13 @@ class LocationComponentTest : EspressoTest() {
component.renderMode = RenderMode.GPS
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
val foregroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON)
assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap")))
component.applyStyle(LocationComponentOptions.builder(context).build())
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertEquals(FOREGROUND_ICON, mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON))
}
@@ -395,13 +395,13 @@ class LocationComponentTest : EspressoTest() {
component.renderMode = RenderMode.GPS
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
val foregroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON)
assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap")))
component.renderMode = RenderMode.NORMAL
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertEquals(FOREGROUND_ICON, mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON))
}
@@ -430,14 +430,14 @@ class LocationComponentTest : EspressoTest() {
component.isLocationComponentEnabled = true
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
uiController.loopMainThreadForAtLeast(250) // engaging stale state
assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true))
component.onStop()
component.onStart()
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true))
assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(false))
@@ -461,13 +461,13 @@ class LocationComponentTest : EspressoTest() {
component.isLocationComponentEnabled = true
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(false))
component.onStop()
component.onStart()
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(false))
assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true))
@@ -499,7 +499,7 @@ class LocationComponentTest : EspressoTest() {
component.isLocationComponentEnabled = true
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
mapboxMap.querySourceFeatures(LOCATION_SOURCE).also { feature ->
feature.forEach {
@@ -526,7 +526,7 @@ class LocationComponentTest : EspressoTest() {
component.isLocationComponentEnabled = true
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
val point: Point = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].geometry() as Point
assertThat(component.locationEngine, nullValue())
@@ -550,14 +550,14 @@ class LocationComponentTest : EspressoTest() {
.build())
component.isLocationComponentEnabled = true
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
val point: Point = mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER)[0].geometry() as Point
assertEquals(point.latitude(), location.latitude, 0.1)
assertEquals(point.longitude(), location.longitude, 0.1)
component.isLocationComponentEnabled = false
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(true))
}
}
@@ -580,7 +580,7 @@ class LocationComponentTest : EspressoTest() {
component.isLocationComponentEnabled = false
mapboxMap.setStyle(Style.Builder().fromUrl(Style.LIGHT))
component.isLocationComponentEnabled = true
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true))
}
@@ -675,7 +675,7 @@ class LocationComponentTest : EspressoTest() {
component.onStart()
mapboxMap.setStyle(Style.Builder().fromUrl(Style.DARK))
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
}
}
executeComponentTest(componentAction)
@@ -695,7 +695,7 @@ class LocationComponentTest : EspressoTest() {
mapboxMap.setStyle(Style.Builder().fromUrl(Style.DARK))
component.onStop()
component.onStart()
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
}
}
executeComponentTest(componentAction)
@@ -714,7 +714,7 @@ class LocationComponentTest : EspressoTest() {
component.isLocationComponentEnabled = true
component.onStop()
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE).isEmpty(), `is`(true))
}
@@ -736,7 +736,7 @@ class LocationComponentTest : EspressoTest() {
component.onStop()
component.forceLocationUpdate(location)
component.onStart()
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
val point: Point = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].geometry() as Point
assertEquals(point.latitude(), location.latitude, 0.1)
@@ -760,9 +760,9 @@ class LocationComponentTest : EspressoTest() {
component.forceLocationUpdate(location)
mapboxMap.setStyle(Style.Builder().fromUrl(Style.LIGHT))
component.onStop()
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
component.onStart()
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
val point: Point = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].geometry() as Point
assertEquals(point.latitude(), location.latitude, 0.1)
@@ -797,7 +797,7 @@ class LocationComponentTest : EspressoTest() {
component.applyStyle(options)
}
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
}
}
executeComponentTest(componentAction)
@@ -823,7 +823,7 @@ class LocationComponentTest : EspressoTest() {
component.forceLocationUpdate(location)
}
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
}
}
executeComponentTest(componentAction)
@@ -839,7 +839,7 @@ class LocationComponentTest : EspressoTest() {
override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap,
style: Style, uiController: UiController, context: Context) {
styleChangeIdlingResource.waitForStyle(mapboxMap, MAPBOX_HEAVY_STYLE)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
locationComponentActivationOptions = LocationComponentActivationOptions
.builder(context, mapboxMap.style!!)
@@ -878,13 +878,13 @@ class LocationComponentTest : EspressoTest() {
component.renderMode = RenderMode.GPS
location.bearing = 77f
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS)
assertEquals(77f, mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getNumberProperty(PROPERTY_GPS_BEARING).toFloat(), 0.1f)
location.bearing = 92f
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS) // Waiting for the animation to finish
assertEquals(92.0f, mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getNumberProperty(PROPERTY_GPS_BEARING).toFloat(), 0.1f)
}
@@ -906,7 +906,7 @@ class LocationComponentTest : EspressoTest() {
component.cameraMode = CameraMode.TRACKING_GPS
location.bearing = 77f
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS)
assertEquals(77.0, mapboxMap.cameraPosition.bearing, 0.1)
@@ -917,7 +917,7 @@ class LocationComponentTest : EspressoTest() {
location.latitude = 30.0
location.longitude = 35.0
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS) // Waiting for the animation to finish
assertEquals(92.0, mapboxMap.cameraPosition.bearing, 0.1)
@@ -945,7 +945,7 @@ class LocationComponentTest : EspressoTest() {
location.bearing = 77f
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS)
assertEquals(77.0, mapboxMap.cameraPosition.bearing, 0.1)
@@ -956,7 +956,7 @@ class LocationComponentTest : EspressoTest() {
location.latitude = 30.0
location.longitude = 35.0
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS)
assertEquals(92.0, mapboxMap.cameraPosition.bearing, 0.1)
@@ -985,7 +985,7 @@ class LocationComponentTest : EspressoTest() {
location.bearing = 77f
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS)
assertEquals(bearing, mapboxMap.cameraPosition.bearing, 0.1)
@@ -996,7 +996,7 @@ class LocationComponentTest : EspressoTest() {
location.latitude = 30.0
location.longitude = 35.0
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS)
assertEquals(bearing, mapboxMap.cameraPosition.bearing, 0.1)
@@ -1021,7 +1021,7 @@ class LocationComponentTest : EspressoTest() {
component.cameraMode = CameraMode.TRACKING
component.cameraMode = CameraMode.NONE
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(mapboxMap.uiSettings.focalPoint, nullValue())
}
@@ -1044,7 +1044,7 @@ class LocationComponentTest : EspressoTest() {
val zoom = mapboxMap.cameraPosition.zoom
component.zoomWhileTracking(10.0)
uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertEquals(zoom, mapboxMap.cameraPosition.zoom, 0.1)
}
@@ -1066,7 +1066,7 @@ class LocationComponentTest : EspressoTest() {
component.cameraMode = CameraMode.TRACKING
component.zoomWhileTracking(10.0)
uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertEquals(10.0, mapboxMap.cameraPosition.zoom, 0.1)
}
@@ -1091,7 +1091,7 @@ class LocationComponentTest : EspressoTest() {
uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION / 2)
component.cameraMode = CameraMode.NONE
uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION / 2)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertEquals(15.0 / 2.0, mapboxMap.cameraPosition.zoom, 3.0)
}
@@ -1117,7 +1117,7 @@ class LocationComponentTest : EspressoTest() {
component.onStop()
component.zoomWhileTracking(10.0)
uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertEquals(zoom, mapboxMap.cameraPosition.zoom, 0.1)
}
@@ -1142,7 +1142,7 @@ class LocationComponentTest : EspressoTest() {
uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION / 2)
component.cancelZoomWhileTrackingAnimation()
uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIM_DURATION / 2)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertEquals(15.0 / 2.0, mapboxMap.cameraPosition.zoom, 3.0)
}
@@ -1165,7 +1165,7 @@ class LocationComponentTest : EspressoTest() {
val tilt = mapboxMap.cameraPosition.tilt
component.tiltWhileTracking(30.0)
uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertEquals(tilt, mapboxMap.cameraPosition.tilt, 0.1)
}
@@ -1187,7 +1187,7 @@ class LocationComponentTest : EspressoTest() {
component.cameraMode = CameraMode.TRACKING
component.tiltWhileTracking(30.0)
uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertEquals(30.0, mapboxMap.cameraPosition.tilt, 0.1)
}
@@ -1212,7 +1212,7 @@ class LocationComponentTest : EspressoTest() {
uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION / 2)
component.cameraMode = CameraMode.NONE
uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION / 2)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertEquals(30.0 / 2.0, mapboxMap.cameraPosition.tilt, 3.0)
}
@@ -1237,7 +1237,7 @@ class LocationComponentTest : EspressoTest() {
component.onStop()
component.tiltWhileTracking(30.0)
uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIM_DURATION)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertEquals(tilt, mapboxMap.cameraPosition.tilt, 0.1)
}
@@ -1286,7 +1286,7 @@ class LocationComponentTest : EspressoTest() {
mapboxMap.moveCamera(CameraUpdateFactory.newLatLng(LatLng(51.0, 17.0)))
mapboxMap.moveCamera(CameraUpdateFactory.bearingTo(90.0))
component.isLocationComponentEnabled = true
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
uiController.loopMainThreadForAtLeast(MAX_ANIMATION_DURATION_MS)
assertEquals(location.bearing.toDouble(), mapboxMap.cameraPosition.bearing, 0.1)
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.kt
index 37b3e8b802..fb450de527 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.kt
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.kt
@@ -75,7 +75,7 @@ class LocationLayerControllerTest : EspressoTest() {
.build())
component.isLocationComponentEnabled = true
component.renderMode = RenderMode.NORMAL
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(style.getSource(LOCATION_SOURCE), notNullValue())
}
@@ -99,7 +99,7 @@ class LocationLayerControllerTest : EspressoTest() {
component.isLocationComponentEnabled = true
component.renderMode = RenderMode.NORMAL
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true))
assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true))
@@ -123,7 +123,7 @@ class LocationLayerControllerTest : EspressoTest() {
component.isLocationComponentEnabled = true
component.renderMode = RenderMode.COMPASS
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true))
assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true))
@@ -147,7 +147,7 @@ class LocationLayerControllerTest : EspressoTest() {
component.isLocationComponentEnabled = true
component.renderMode = RenderMode.GPS
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true))
assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true))
@@ -171,7 +171,7 @@ class LocationLayerControllerTest : EspressoTest() {
component.isLocationComponentEnabled = true
component.forceLocationUpdate(location)
component.isLocationComponentEnabled = false
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
component.renderMode = RenderMode.GPS
assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(false))
@@ -197,7 +197,7 @@ class LocationLayerControllerTest : EspressoTest() {
component.renderMode = RenderMode.NORMAL
component.forceLocationUpdate(location)
component.isLocationComponentEnabled = false
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
// Check that all layers visibilities are set to none
assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(false))
@@ -223,7 +223,7 @@ class LocationLayerControllerTest : EspressoTest() {
component.renderMode = RenderMode.NORMAL
component.forceLocationUpdate(location)
styleChangeIdlingResource.waitForStyle(mapboxMap, Style.LIGHT)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(component.renderMode, `is`(equalTo(RenderMode.NORMAL)))
@@ -254,13 +254,13 @@ class LocationLayerControllerTest : EspressoTest() {
component.isLocationComponentEnabled = true
component.applyStyle(LocationComponentOptions.builder(context).staleStateTimeout(100).build())
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
uiController.loopMainThreadForAtLeast(150)
assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true))
mapboxMap.setStyle(Style.Builder().fromUrl(Style.LIGHT))
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true))
}
@@ -279,9 +279,9 @@ class LocationLayerControllerTest : EspressoTest() {
.build())
component.isLocationComponentEnabled = true
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
component.isLocationComponentEnabled = false
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(true))
val options =
@@ -291,7 +291,7 @@ class LocationLayerControllerTest : EspressoTest() {
.build()
component.applyStyle(options)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(true))
}
}
@@ -338,7 +338,7 @@ class LocationLayerControllerTest : EspressoTest() {
show = !show
}
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
}
}
executeComponentTest(componentAction)
@@ -359,7 +359,7 @@ class LocationLayerControllerTest : EspressoTest() {
component.isLocationComponentEnabled = true
mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0))
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
uiController.loopMainThreadForAtLeast(ACCURACY_RADIUS_ANIMATION_DURATION)
assertEquals(Utils.calculateZoomLevelRadius(mapboxMap, location) /*meters projected to radius on zoom 16*/,
@@ -386,7 +386,7 @@ class LocationLayerControllerTest : EspressoTest() {
val zoom = 16.0
mapboxMap.easeCamera(CameraUpdateFactory.newLatLngZoom(target, zoom), 300)
uiController.loopMainThreadForAtLeast(300)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(Math.abs(zoom - mapboxMap.cameraPosition.zoom) < 0.1
@@ -418,7 +418,7 @@ class LocationLayerControllerTest : EspressoTest() {
val target = LatLng(location)
val zoom = 16.0
mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(target, zoom))
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(Math.abs(zoom - mapboxMap.cameraPosition.zoom) < 0.1
&& Math.abs(target.latitude - mapboxMap.cameraPosition.target.latitude) < 0.1
@@ -445,7 +445,7 @@ class LocationLayerControllerTest : EspressoTest() {
.build())
component.isLocationComponentEnabled = true
component.forceLocationUpdate(location)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
component.applyStyle(LocationComponentOptions.builder(context).layerBelow("road-label").build())
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/GLSurfaceViewReopenTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/GLSurfaceViewReopenTest.kt
deleted file mode 100644
index 98b251027f..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/GLSurfaceViewReopenTest.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.mapbox.mapboxsdk.maps
-
-import android.content.Intent
-import android.support.test.InstrumentationRegistry
-import android.support.test.filters.SdkSuppress
-import android.support.test.runner.AndroidJUnit4
-import android.support.test.uiautomator.*
-import org.hamcrest.CoreMatchers.notNullValue
-import org.hamcrest.MatcherAssert.assertThat
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import java.lang.Thread.sleep
-
-private const val BASIC_SAMPLE_PACKAGE = "com.mapbox.mapboxsdk.testapp"
-private const val LAUNCH_TIMEOUT = 5000L
-
-@RunWith(AndroidJUnit4::class)
-@SdkSuppress(minSdkVersion = 18)
-class GLSurfaceViewReopenTest {
-
- private lateinit var device: UiDevice
-
- @Before
- fun startSimpleMapActivityFromHomeScreen() {
- // Initialize UiDevice instance
- device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
-
- // Start from the home screen
- device.pressHome()
-
- // Wait for launcher
- val launcherPackage: String = device.launcherPackageName
- assertThat(launcherPackage, notNullValue())
- device.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), LAUNCH_TIMEOUT)
-
- // Launch the app
- val context = InstrumentationRegistry.getInstrumentation().context
- val intent = context.packageManager.getLaunchIntentForPackage(BASIC_SAMPLE_PACKAGE).apply {
- // Clear out any previous instances
- addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
- }
- context.startActivity(intent)
-
- // Wait for the app to appear
- device.wait(
- Until.hasObject(By.pkg(BASIC_SAMPLE_PACKAGE).depth(0)),
- LAUNCH_TIMEOUT
- )
-
- // open SimpleMapActivity
- device.findObject(UiSelector().text("Simple Map")).clickAndWaitForNewWindow()
-
- // wait for idle
- device.waitForIdle(LAUNCH_TIMEOUT)
- }
-
- @Test
- fun reopenSimpleMapActivity() {
- // return to home screen
- device.pressHome()
-
- // press recents apps button
- device.pressRecentApps()
-
- // click to reopen app
- device.findObject(UiSelector().description("Mapbox Android SDK TestApp")).click()
-
- // wait for idle
- device.waitForIdle(LAUNCH_TIMEOUT)
- sleep(LAUNCH_TIMEOUT)
- }
-} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxTest.java
index b56d267b81..c8737e2802 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxTest.java
@@ -1,5 +1,6 @@
package com.mapbox.mapboxsdk.maps;
+import android.support.test.annotation.UiThreadTest;
import android.support.test.runner.AndroidJUnit4;
import com.mapbox.mapboxsdk.Mapbox;
import org.junit.Test;
@@ -16,6 +17,7 @@ public class MapboxTest {
private static final String ACCESS_TOKEN_2 = "pk.0000000002";
@Test
+ @UiThreadTest
public void testConnected() {
assertTrue(Mapbox.isConnected());
@@ -31,6 +33,7 @@ public class MapboxTest {
}
@Test
+ @UiThreadTest
public void setAccessToken() {
String realToken = Mapbox.getAccessToken();
Mapbox.setAccessToken(ACCESS_TOKEN);
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/OrientationTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/OrientationTest.java
deleted file mode 100644
index 14a2c3bdbf..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/OrientationTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.mapbox.mapboxsdk.maps;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseTest;
-import com.mapbox.mapboxsdk.testapp.activity.camera.CameraAnimationTypeActivity;
-import org.junit.Test;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.matcher.ViewMatchers.isRoot;
-import static com.mapbox.mapboxsdk.testapp.action.OrientationChangeAction.orientationLandscape;
-import static com.mapbox.mapboxsdk.testapp.action.OrientationChangeAction.orientationLandscapeReverse;
-import static com.mapbox.mapboxsdk.testapp.action.OrientationChangeAction.orientationPortrait;
-import static com.mapbox.mapboxsdk.testapp.action.OrientationChangeAction.orientationPortraitReverse;
-
-public class OrientationTest extends BaseTest {
-
- @Test
- public void testChangeDeviceOrientation() {
- onView(isRoot()).perform(orientationLandscape());
- waitAction(2200);
- onView(isRoot()).perform(orientationPortrait());
- waitAction(2500);
- onView(isRoot()).perform(orientationLandscapeReverse());
- waitAction(500);
- onView(isRoot()).perform(orientationPortraitReverse());
- waitAction(1250);
- onView(isRoot()).perform(orientationLandscape());
- waitAction(750);
- onView(isRoot()).perform(orientationPortrait());
- waitAction(950);
- onView(isRoot()).perform(orientationLandscapeReverse());
- onView(isRoot()).perform(orientationPortraitReverse());
- onView(isRoot()).perform(orientationLandscape());
- onView(isRoot()).perform(orientationPortrait());
- }
-
- @Override
- protected Class getActivityClass() {
- return CameraAnimationTypeActivity.class;
- }
-
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/TextureViewReopenTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/TextureViewReopenTest.kt
deleted file mode 100644
index cd139ccc40..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/TextureViewReopenTest.kt
+++ /dev/null
@@ -1,77 +0,0 @@
-package com.mapbox.mapboxsdk.maps
-
-import android.content.Intent
-import android.support.test.InstrumentationRegistry
-import android.support.test.filters.SdkSuppress
-import android.support.test.runner.AndroidJUnit4
-import android.support.test.uiautomator.*
-import org.hamcrest.CoreMatchers.notNullValue
-import org.hamcrest.MatcherAssert.assertThat
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import java.lang.Thread.sleep
-import android.support.test.uiautomator.UiSelector
-import android.support.test.uiautomator.UiScrollable
-
-private const val BASIC_SAMPLE_PACKAGE = "com.mapbox.mapboxsdk.testapp"
-private const val LAUNCH_TIMEOUT = 5000L
-
-@RunWith(AndroidJUnit4::class)
-@SdkSuppress(minSdkVersion = 18)
-class TextureViewReopenTest {
-
- private lateinit var device: UiDevice
-
- @Before
- fun startSimpleMapActivityFromHomeScreen() {
- // Initialize UiDevice instance
- device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
-
- // Start from the home screen
- device.pressHome()
-
- // Wait for launcher
- val launcherPackage: String = device.launcherPackageName
- assertThat(launcherPackage, notNullValue())
- device.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), LAUNCH_TIMEOUT)
-
- // Launch the app
- val context = InstrumentationRegistry.getInstrumentation().context
- val intent = context.packageManager.getLaunchIntentForPackage(BASIC_SAMPLE_PACKAGE).apply {
- // Clear out any previous instances
- addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
- }
- context.startActivity(intent)
-
- // Wait for the app to appear
- device.wait(
- Until.hasObject(By.pkg(BASIC_SAMPLE_PACKAGE).depth(0)),
- LAUNCH_TIMEOUT
- )
-
- // open TextureView debug activity
- val appView = UiScrollable(UiSelector().scrollable(true))
- appView.scrollIntoView(UiSelector().text("TextureView debug"))
- device.findObject(UiSelector().text("TextureView debug")).clickAndWaitForNewWindow()
-
- // wait for idle
- device.waitForIdle(LAUNCH_TIMEOUT)
- }
-
- @Test
- fun reopenTextureViewDebugActivity() {
- // return to home screen
- device.pressHome()
-
- // press recent apps button
- device.pressRecentApps()
-
- // click to reopen app
- device.findObject(UiSelector().description("Mapbox Android SDK TestApp")).click()
-
- // wait for idle
- device.waitForIdle(LAUNCH_TIMEOUT)
- sleep(LAUNCH_TIMEOUT)
- }
-} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/VisibleRegionTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/VisibleRegionTest.kt
index 4866812e67..139695461d 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/VisibleRegionTest.kt
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/VisibleRegionTest.kt
@@ -1,25 +1,27 @@
-package com.mapbox.mapboxsdk.testapp.maps
+package com.mapbox.mapboxsdk.maps
import android.graphics.PointF
import android.support.test.espresso.UiController
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
import com.mapbox.mapboxsdk.geometry.LatLng
-import com.mapbox.mapboxsdk.maps.MapView
-import com.mapbox.mapboxsdk.maps.MapboxMap
import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke
-import com.mapbox.mapboxsdk.testapp.activity.EspressoTest
-import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity
+
+import com.mapbox.mapboxsdk.testapp.activity.BaseTest
+import com.mapbox.mapboxsdk.testapp.activity.espresso.PixelTestActivity
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
-class VisibleRegionTest : EspressoTest() {
+class VisibleRegionTest : BaseTest() {
- private lateinit var mapView: MapView
+ override fun getActivityClass(): Class<*> {
+ return PixelTestActivity::class.java
+ }
- override fun beforeTest() {
+ override
+ fun beforeTest() {
super.beforeTest()
- mapView = (rule.activity as EspressoTestActivity).mapView
+ mapView = (rule.activity as PixelTestActivity).mapView
}
@Test
@@ -263,9 +265,9 @@ class VisibleRegionTest : EspressoTest() {
@Test
fun paddedTopVisibleRegionOverDatelineTest() {
validateTestSetup()
- invoke(mapboxMap) { _: UiController, mapboxMap: MapboxMap ->
+ invoke(mapboxMap) { ui: UiController, mapboxMap: MapboxMap ->
mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 180.0), 8.0))
-
+ ui.loopMainThreadForAtLeast(5000)
val latLngs = listOf(
mapboxMap.getLatLngFromScreenCoords(0f, 0f),
mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f),
@@ -299,7 +301,7 @@ class VisibleRegionTest : EspressoTest() {
mapboxMap.getLatLngFromScreenCoords(0f, 0f),
mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f),
mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f)
- .also { it.longitude += 360 },
+ .also { it.longitude += 360 },
mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f)
.also { it.longitude += 360 },
mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat())
@@ -355,11 +357,11 @@ class VisibleRegionTest : EspressoTest() {
mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 0.0), 8.0))
val d = Math.min(mapboxMap.width, mapboxMap.height) / 4;
val latLngs = listOf(
- mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f),
- mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f - d / 2f, mapView.height / 2f),
- mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f + d / 2f, mapView.height / 2f),
- mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f - d / 2f),
- mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f + d / 2f)
+ mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f),
+ mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f - d / 2f, mapView.height / 2f),
+ mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f + d / 2f, mapView.height / 2f),
+ mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f - d / 2f),
+ mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f + d / 2f)
)
@@ -371,29 +373,29 @@ class VisibleRegionTest : EspressoTest() {
}
}
- @Test
- fun visibleRotatedRegionOverDatelineTest() {
- validateTestSetup()
- invoke(mapboxMap) { _: UiController, mapboxMap: MapboxMap ->
- mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 180.0), 8.0))
- val d = Math.min(mapboxMap.width, mapboxMap.height) / 4;
- val latLngs = listOf(
- mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f),
- mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f - d / 2f, mapView.height / 2f),
- mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f + d / 2f, mapView.height / 2f)
- .also { it.longitude += 360 },
- mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f - d / 2f),
- mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f + d / 2f)
- )
-
-
- for (bearing in 45 until 360 step 45) {
- mapboxMap.moveCamera(CameraUpdateFactory.bearingTo(bearing.toDouble()));
- val visibleRegion = mapboxMap.projection.visibleRegion
- assertTrue(latLngs.all { visibleRegion.latLngBounds.contains(it) })
- }
- }
+ @Test
+ fun visibleRotatedRegionOverDatelineTest() {
+ validateTestSetup()
+ invoke(mapboxMap) { _: UiController, mapboxMap: MapboxMap ->
+ mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 180.0), 8.0))
+ val d = Math.min(mapboxMap.width, mapboxMap.height) / 4;
+ val latLngs = listOf(
+ mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f),
+ mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f - d / 2f, mapView.height / 2f),
+ mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f + d / 2f, mapView.height / 2f)
+ .also { it.longitude += 360 },
+ mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f - d / 2f),
+ mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f + d / 2f)
+ )
+
+
+ for (bearing in 45 until 360 step 45) {
+ mapboxMap.moveCamera(CameraUpdateFactory.bearingTo(bearing.toDouble()));
+ val visibleRegion = mapboxMap.projection.visibleRegion
+ assertTrue(latLngs.all { visibleRegion.latLngBounds.contains(it) })
+ }
}
+ }
private fun MapboxMap.getLatLngFromScreenCoords(x: Float, y: Float): LatLng {
return this.projection.fromScreenLocation(PointF(x, y))
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/module/telemetry/PerformanceEventTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/module/telemetry/PerformanceEventTest.java
new file mode 100644
index 0000000000..6f256b4e56
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/module/telemetry/PerformanceEventTest.java
@@ -0,0 +1,188 @@
+package com.mapbox.mapboxsdk.module.telemetry;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.WindowManager;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.mapbox.mapboxsdk.Mapbox;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.UUID;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@RunWith(AndroidJUnit4.class)
+public class PerformanceEventTest {
+
+ @Test
+ public void checksPerformanceEventWithMetaData() throws Exception {
+ PerformanceEvent event = obtainPerformanceEvent();
+ assertNotNull(event);
+
+ Parcel parcel = Parcel.obtain();
+
+ event.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+
+ PerformanceEvent newPerfEvent = PerformanceEvent.CREATOR.createFromParcel(parcel);
+ assertNotNull(newPerfEvent);
+
+ compare(event, newPerfEvent, "attributes", "style_id");
+ compare(event, newPerfEvent, "counters", "int_value");
+ compare(event, newPerfEvent, "counters", "long_value");
+ compare(event, newPerfEvent, "counters", "double_value");
+ assertEquals(getMetadata(event), getMetadata(newPerfEvent));
+ }
+
+ @Test
+ public void checksPerformanceEventOnlyRequiredData() throws Exception {
+ Bundle bundle = new Bundle();
+ bundle.putString("property ignored", "value will be ignored");
+ PerformanceEvent event = new PerformanceEvent(UUID.randomUUID().toString(), bundle);
+ assertNotNull(event);
+
+ Parcel parcel = Parcel.obtain();
+ event.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+
+ PerformanceEvent newPerfEvent = PerformanceEvent.CREATOR.createFromParcel(parcel);
+ assertNotNull(newPerfEvent);
+
+ assertEquals(getAttributes(event).size(), 0);
+ assertEquals(getCounters(event).size(), 0);
+ assertEquals(getAttributes(newPerfEvent).size(), 0);
+ assertEquals(getCounters(newPerfEvent).size(), 0);
+ assertEquals(getMetadata(event), getMetadata(newPerfEvent));
+ }
+
+
+ private PerformanceEvent obtainPerformanceEvent() {
+ String styleStr = "mapbox://styles/mapbox/streets-v11";
+ boolean testPerfEvent = true;
+ Double doubleValue = 40.5;
+ Long longValue = 40L;
+ Integer intValue = 40;
+
+ List<Attribute<String>> attributes = new ArrayList<>();
+ attributes.add(
+ new Attribute<>("style_id", styleStr));
+ attributes.add(
+ new Attribute<>("test_perf_event", String.valueOf(testPerfEvent)));
+
+ List<Attribute<? extends Number>> counters = new ArrayList();
+ counters.add(new Attribute<>("long_value", longValue));
+ counters.add(new Attribute<>("double_value", doubleValue));
+ counters.add(new Attribute<>("int_value", intValue));
+
+ Gson gson = new Gson();
+
+ Bundle bundle = new Bundle();
+ bundle.putString("attributes", gson.toJson(attributes));
+ bundle.putString("counters", gson.toJson(counters));
+
+ JsonObject metaData = new JsonObject();
+ metaData.addProperty("os", "android");
+ metaData.addProperty("manufacturer", Build.MANUFACTURER);
+ metaData.addProperty("brand", Build.BRAND);
+ metaData.addProperty("device", Build.MODEL);
+ metaData.addProperty("version", Build.VERSION.RELEASE);
+ metaData.addProperty("abi", Build.CPU_ABI);
+ metaData.addProperty("country", Locale.getDefault().getISO3Country());
+ metaData.addProperty("ram", getRam());
+ metaData.addProperty("screenSize", getWindowSize());
+ bundle.putString("metadata", metaData.toString());
+
+ return new PerformanceEvent(UUID.randomUUID().toString(), bundle);
+ }
+
+ private void compare(PerformanceEvent event1, PerformanceEvent event2, String listFieldName, String name)
+ throws NoSuchFieldException, IllegalAccessException {
+ Object value1 = getValue(event1, listFieldName, name);
+ Object value2 = getValue(event2, listFieldName, name);
+
+ if (value1 instanceof Double && value2 instanceof Double) {
+ assertEquals((Double)value1, (Double)value2, 0.00006);
+ } else {
+ assertEquals(value1, value2);
+ }
+ }
+
+ private Object getPrivateFieldValue(Object object, String fieldName)
+ throws NoSuchFieldException, IllegalAccessException {
+ Field field = object.getClass().getDeclaredField(fieldName);
+ field.setAccessible(true);
+ return field.get(object);
+ }
+
+ private Object getValue(PerformanceEvent event, String listFieldName, String name)
+ throws NoSuchFieldException, IllegalAccessException {
+ ArrayList list = (ArrayList)getPrivateFieldValue(event, listFieldName);
+ for (Object element : list) {
+ Object elementName = getPrivateFieldValue(element, "name");
+ if (elementName != null && elementName.equals((String)name)) {
+ return getPrivateFieldValue(element, "value");
+ }
+ }
+ return null;
+ }
+
+ private JsonObject getMetadata(PerformanceEvent event)
+ throws NoSuchFieldException, IllegalAccessException {
+ return (JsonObject)getPrivateFieldValue(event, "metadata");
+ }
+
+ private ArrayList getAttributes(PerformanceEvent event)
+ throws NoSuchFieldException, IllegalAccessException {
+ return (ArrayList)getPrivateFieldValue(event, "attributes");
+ }
+
+ private ArrayList getCounters(PerformanceEvent event)
+ throws NoSuchFieldException, IllegalAccessException {
+ return (ArrayList)getPrivateFieldValue(event, "counters");
+ }
+
+ private static String getRam() {
+ ActivityManager actManager =
+ (ActivityManager) Mapbox.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
+ ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
+ actManager.getMemoryInfo(memInfo);
+ return String.valueOf(memInfo.totalMem);
+ }
+
+ private static String getWindowSize() {
+ WindowManager windowManager =
+ (WindowManager) Mapbox.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
+ Display display = windowManager.getDefaultDisplay();
+ DisplayMetrics metrics = new DisplayMetrics();
+ display.getMetrics(metrics);
+ int width = metrics.widthPixels;
+ int height = metrics.heightPixels;
+
+ return "{" + width + "," + height + "}";
+ }
+
+ private class Attribute<T> {
+ private String name;
+ private T value;
+
+ Attribute(String name, T value) {
+ this.name = name;
+ this.value = value;
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/OrientationChangeAction.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/OrientationAction.java
index 7f73d6a7f3..1bf5a87970 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/OrientationChangeAction.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/OrientationAction.java
@@ -1,6 +1,5 @@
package com.mapbox.mapboxsdk.testapp.action;
-
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
@@ -11,30 +10,31 @@ import android.view.View;
import android.view.ViewGroup;
import org.hamcrest.Matcher;
+import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.matcher.ViewMatchers.isRoot;
-public class OrientationChangeAction implements ViewAction {
+public class OrientationAction implements ViewAction {
private final int orientation;
- private OrientationChangeAction(int orientation) {
+ private OrientationAction(int orientation) {
this.orientation = orientation;
}
public static ViewAction orientationLandscape() {
- return new OrientationChangeAction(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+ return new OrientationAction(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
public static ViewAction orientationPortrait() {
- return new OrientationChangeAction(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+ return new OrientationAction(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
public static ViewAction orientationLandscapeReverse() {
- return new OrientationChangeAction(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
+ return new OrientationAction(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
}
public static ViewAction orientationPortraitReverse() {
- return new OrientationChangeAction(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
+ return new OrientationAction(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
}
@Override
@@ -61,6 +61,10 @@ public class OrientationChangeAction implements ViewAction {
activity.setRequestedOrientation(orientation);
}
+ public static void invoke(ViewAction action) {
+ onView(isRoot()).perform(action);
+ }
+
private Activity getActivity(Context context) {
while (context instanceof ContextWrapper) {
if (context instanceof Activity) {
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/WaitAction.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/WaitAction.java
index 5d98ccb7f8..e3741f3d42 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/WaitAction.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/WaitAction.java
@@ -3,10 +3,11 @@ package com.mapbox.mapboxsdk.testapp.action;
import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
import android.view.View;
-
import org.hamcrest.Matcher;
+import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.isRoot;
public final class WaitAction implements ViewAction {
@@ -30,5 +31,9 @@ public final class WaitAction implements ViewAction {
public void perform(UiController uiController, View view) {
uiController.loopMainThreadForAtLeast(loopTime);
}
+
+ public static void invoke(long loopTime) {
+ onView(isRoot()).perform(new WaitAction(loopTime));
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseTest.java
index ea69f8adae..c91afe9b60 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseTest.java
@@ -1,116 +1,96 @@
package com.mapbox.mapboxsdk.testapp.activity;
-import android.app.Activity;
-import android.support.test.espresso.Espresso;
-import android.support.test.espresso.IdlingRegistry;
-import android.support.test.espresso.IdlingResource;
-import android.support.test.espresso.IdlingResourceTimeoutException;
-import android.support.test.espresso.ViewInteraction;
+import android.support.annotation.CallSuper;
+import android.support.annotation.UiThread;
import android.support.test.rule.ActivityTestRule;
-
import com.mapbox.mapboxsdk.Mapbox;
+import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction;
-import com.mapbox.mapboxsdk.testapp.action.WaitAction;
-import com.mapbox.mapboxsdk.testapp.utils.FinishLoadingStyleIdlingResource;
-
-import com.mapbox.mapboxsdk.testapp.utils.MapboxIdlingResource;
-import junit.framework.Assert;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.TestName;
-
import timber.log.Timber;
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import static junit.framework.TestCase.assertNotNull;
+import static junit.framework.TestCase.assertTrue;
/**
* Base class for all Activity test hooking into an existing Activity that will load style.
*/
public abstract class BaseTest {
+ private static final int WAIT_TIMEOUT = 30; //seconds
+
@Rule
- public ActivityTestRule<Activity> rule = new ActivityTestRule<>(getActivityClass());
+ public ActivityTestRule rule = new ActivityTestRule<>(getActivityClass());
@Rule
- public TestName testNameRule = new TestName();
+ public TestName testName = new TestName();
protected MapboxMap mapboxMap;
- protected MapboxIdlingResource idlingResource;
+ protected MapView mapView;
+ private final CountDownLatch latch = new CountDownLatch(1);
@Before
+ @CallSuper
public void beforeTest() {
- try {
- Timber.e(String.format(
- "%s - %s - %s",
- getClass().getSimpleName(),
- testNameRule.getMethodName(),
- "@Before test: register idle resource"
- ));
- idlingResource = (MapboxIdlingResource) generateIdlingResource();
- IdlingRegistry.getInstance().register(idlingResource);
- Espresso.onIdle();
- mapboxMap = idlingResource.getMapboxMap();
- } catch (IdlingResourceTimeoutException idlingResourceTimeoutException) {
- throw new RuntimeException(
- String.format(
- "Could not start %s test for %s.",
- testNameRule.getMethodName(),
- getActivityClass().getSimpleName()
- )
- );
- }
+ initialiseMap();
+ holdTestRunnerForStyleLoad();
}
- protected IdlingResource generateIdlingResource() {
- return new FinishLoadingStyleIdlingResource(rule.getActivity());
+ @After
+ @CallSuper
+ public void afterTest() {
+ // override to add logic
+ }
+
+ @UiThread
+ @CallSuper
+ protected void initMap(MapboxMap mapboxMap) {
+ this.mapboxMap = mapboxMap;
+ mapboxMap.getStyle(style -> latch.countDown());
}
protected void validateTestSetup() {
if (!Mapbox.isConnected()) {
Timber.e("Not connected to the internet while running test");
}
-
- checkViewIsDisplayed(R.id.mapView);
- Assert.assertNotNull(mapboxMap);
- }
-
- protected MapboxMap getMapboxMap() {
- return mapboxMap;
+ assertNotNull("MapView isn't initialised", mapView);
+ assertNotNull("MapboxMap isn't initialised", mapboxMap);
+ assertNotNull("Style isn't initialised", mapboxMap.getStyle());
+ assertTrue("Style isn't fully loaded", mapboxMap.getStyle().isFullyLoaded());
}
protected abstract Class getActivityClass();
- protected void checkViewIsDisplayed(int id) {
- onView(withId(id)).check(matches(isDisplayed()));
- }
-
- protected void waitAction() {
- waitAction(500);
- }
-
- protected void waitAction(long waitTime) {
- onView(withId(R.id.mapView)).perform(new WaitAction(waitTime));
- }
-
- protected ViewInteraction onMapView() {
- return onView(withId(R.id.mapView));
+ private void initialiseMap() {
+ try {
+ rule.runOnUiThread(() -> {
+ mapView = rule.getActivity().findViewById(R.id.mapView);
+ mapView.getMapAsync(this::initMap);
+ });
+ } catch (Throwable throwable) {
+ throwable.printStackTrace();
+ }
}
- protected MapboxMapAction getMapboxMapAction(MapboxMapAction.OnInvokeActionListener onInvokeActionListener) {
- return new MapboxMapAction(onInvokeActionListener, mapboxMap);
- }
+ private void holdTestRunnerForStyleLoad() {
+ boolean interrupted;
+ try {
+ interrupted = latch.await(WAIT_TIMEOUT, TimeUnit.SECONDS);
+ } catch (InterruptedException ignore) {
+ interrupted = true;
+ }
- @After
- public void afterTest() {
- Timber.e(String.format("%s - %s", testNameRule.getMethodName(), "@After test: unregister idle resource"));
- IdlingRegistry.getInstance().unregister(idlingResource);
+ if (!interrupted) {
+ Timber.e("Timeout occurred for %s", testName.getMethodName());
+ validateTestSetup();
+ }
}
-}
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/EspressoTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/EspressoTest.java
index dfb4a46180..97a73ba1cb 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/EspressoTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/EspressoTest.java
@@ -1,24 +1,28 @@
package com.mapbox.mapboxsdk.testapp.activity;
-import android.support.test.espresso.IdlingResource;
+import android.support.annotation.UiThread;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity;
-import com.mapbox.mapboxsdk.testapp.utils.LoadStyleIdlingResource;
+
/**
* Base class for all tests using EspressoTestActivity as wrapper.
* <p>
- * Uses {@link LoadStyleIdlingResource} to load "assets/streets.json" as style.
+ * Loads "assets/streets.json" as style.
* </p>
*/
public class EspressoTest extends BaseTest {
@Override
- protected IdlingResource generateIdlingResource() {
- return new LoadStyleIdlingResource(rule.getActivity());
+ protected final Class getActivityClass() {
+ return EspressoTestActivity.class;
}
+ @UiThread
@Override
- protected final Class getActivityClass() {
- return EspressoTestActivity.class;
+ protected void initMap(MapboxMap mapboxMap) {
+ mapboxMap.setStyle(new Style.Builder().fromUrl("asset://streets.json"));
+ super.initMap(mapboxMap);
}
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/IconTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/IconTest.java
index 9fb823a377..559213af3d 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/IconTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/IconTest.java
@@ -1,6 +1,7 @@
package com.mapbox.mapboxsdk.testapp.annotations;
import android.app.Activity;
+import android.support.test.annotation.UiThreadTest;
import android.support.v4.content.res.ResourcesCompat;
import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.IconFactory;
@@ -31,117 +32,107 @@ public class IconTest extends EspressoTest {
@Before
public void beforeTest() {
super.beforeTest();
- iconMap = new IconManagerResolver(getMapboxMap()).getIconMap();
- }
-
- @Test
- public void testEmpty() {
- assertTrue(iconMap.isEmpty());
+ iconMap = new IconManagerResolver(mapboxMap).getIconMap();
}
@Test
+ @UiThreadTest
public void testAddSameIconMarker() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- Icon defaultMarker = IconFactory.getInstance(rule.getActivity()).defaultMarker();
- mapboxMap.addMarker(new MarkerOptions().position(new LatLng()));
- mapboxMap.addMarker(new MarkerOptions().position(new LatLng(1, 1)));
- assertEquals(1, iconMap.size());
- assertEquals(2, iconMap.get(defaultMarker), 0);
- }));
+ Icon defaultMarker = IconFactory.getInstance(rule.getActivity()).defaultMarker();
+ mapboxMap.addMarker(new MarkerOptions().position(new LatLng()));
+ mapboxMap.addMarker(new MarkerOptions().position(new LatLng(1, 1)));
+ assertEquals(1, iconMap.size());
+ assertEquals(2, iconMap.get(defaultMarker), 0);
}
@Test
+ @UiThreadTest
public void testAddDifferentIconMarker() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- Icon icon = IconFactory.getInstance(rule.getActivity()).fromResource(R.drawable.mapbox_logo_icon);
- getMapboxMap().addMarker(new MarkerOptions().icon(icon).position(new LatLng()));
- getMapboxMap().addMarker(new MarkerOptions().position(new LatLng(1, 1)));
- assertEquals(iconMap.size(), 2);
- assertTrue(iconMap.containsKey(icon));
- assertTrue(iconMap.get(icon) == 1);
- }));
+ Icon icon = IconFactory.getInstance(rule.getActivity()).fromResource(R.drawable.mapbox_logo_icon);
+ mapboxMap.addMarker(new MarkerOptions().icon(icon).position(new LatLng()));
+ mapboxMap.addMarker(new MarkerOptions().position(new LatLng(1, 1)));
+ assertEquals(iconMap.size(), 2);
+ assertTrue(iconMap.containsKey(icon));
+ assertTrue(iconMap.get(icon) == 1);
}
@Test
+ @UiThreadTest
public void testAddRemoveIconMarker() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- Icon icon = IconFactory.getInstance(rule.getActivity()).fromResource(R.drawable.mapbox_logo_icon);
- Marker marker = mapboxMap.addMarker(new MarkerOptions().icon(icon).position(new LatLng()));
- mapboxMap.addMarker(new MarkerOptions().position(new LatLng(1, 1)));
- assertEquals(iconMap.size(), 2);
- assertTrue(iconMap.containsKey(icon));
- assertTrue(iconMap.get(icon) == 1);
-
- mapboxMap.removeMarker(marker);
- assertEquals(iconMap.size(), 1);
- assertFalse(iconMap.containsKey(icon));
- }));
+ Icon icon = IconFactory.getInstance(rule.getActivity()).fromResource(R.drawable.mapbox_logo_icon);
+ Marker marker = mapboxMap.addMarker(new MarkerOptions().icon(icon).position(new LatLng()));
+ mapboxMap.addMarker(new MarkerOptions().position(new LatLng(1, 1)));
+ assertEquals(iconMap.size(), 2);
+ assertTrue(iconMap.containsKey(icon));
+ assertTrue(iconMap.get(icon) == 1);
+
+ mapboxMap.removeMarker(marker);
+ assertEquals(iconMap.size(), 1);
+ assertFalse(iconMap.containsKey(icon));
}
@Test
+ @UiThreadTest
public void testAddRemoveDefaultMarker() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- Marker marker = mapboxMap.addMarker(new MarkerOptions().position(new LatLng(1, 1)));
- assertEquals(iconMap.size(), 1);
+ Marker marker = mapboxMap.addMarker(new MarkerOptions().position(new LatLng(1, 1)));
+ assertEquals(iconMap.size(), 1);
- mapboxMap.removeMarker(marker);
- assertEquals(iconMap.size(), 0);
+ mapboxMap.removeMarker(marker);
+ assertEquals(iconMap.size(), 0);
- mapboxMap.addMarker(new MarkerOptions().position(new LatLng()));
- assertEquals(iconMap.size(), 1);
- }));
+ mapboxMap.addMarker(new MarkerOptions().position(new LatLng()));
+ assertEquals(iconMap.size(), 1);
}
@Test
+ @UiThreadTest
public void testAddRemoveMany() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- Activity activity = rule.getActivity();
- IconFactory iconFactory = IconFactory.getInstance(activity);
-
- // add 2 default icon markers
- Marker defaultMarkerOne = mapboxMap.addMarker(new MarkerOptions().position(new LatLng(1, 1)));
- Marker defaultMarkerTwo = mapboxMap.addMarker(new MarkerOptions().position(new LatLng(2, 1)));
-
- // add 4 unique icon markers
- mapboxMap.addMarker(new MarkerOptions()
- .icon(iconFactory.fromResource(R.drawable.mapbox_logo_icon))
- .position(new LatLng(3, 1))
- );
- mapboxMap.addMarker(new MarkerOptions()
- .icon(iconFactory.fromResource(R.drawable.mapbox_compass_icon))
- .position(new LatLng(4, 1))
- );
- mapboxMap.addMarker(new MarkerOptions()
- .icon(IconUtils.drawableToIcon(activity, R.drawable.ic_stars,
- ResourcesCompat.getColor(activity.getResources(),
- R.color.blueAccent, activity.getTheme())))
- .position(new LatLng(5, 1))
- );
- mapboxMap.addMarker(new MarkerOptions()
- .icon(iconFactory.fromResource(R.drawable.ic_android))
- .position(new LatLng(6, 1))
- );
-
- assertEquals("Amount of icons should match 5", 5, iconMap.size());
- assertEquals("Refcounter of default marker should match 2", 2, iconMap.get(iconFactory.defaultMarker()), 0);
-
- mapboxMap.removeMarker(defaultMarkerOne);
-
- assertEquals("Amount of icons should match 5", 5, iconMap.size());
- assertEquals("Refcounter of default marker should match 1", 1, iconMap.get(iconFactory.defaultMarker()), 0);
-
- mapboxMap.removeMarker(defaultMarkerTwo);
-
- assertEquals("Amount of icons should match 4", 4, iconMap.size());
- assertNull("DefaultMarker shouldn't exist anymore", iconMap.get(iconFactory.defaultMarker()));
-
- mapboxMap.clear();
- assertEquals("Amount of icons should match 0", 0, iconMap.size());
- }));
+ Activity activity = rule.getActivity();
+ IconFactory iconFactory = IconFactory.getInstance(activity);
+
+ // add 2 default icon markers
+ Marker defaultMarkerOne = mapboxMap.addMarker(new MarkerOptions().position(new LatLng(1, 1)));
+ Marker defaultMarkerTwo = mapboxMap.addMarker(new MarkerOptions().position(new LatLng(2, 1)));
+
+ // add 4 unique icon markers
+ mapboxMap.addMarker(new MarkerOptions()
+ .icon(iconFactory.fromResource(R.drawable.mapbox_logo_icon))
+ .position(new LatLng(3, 1))
+ );
+ mapboxMap.addMarker(new MarkerOptions()
+ .icon(iconFactory.fromResource(R.drawable.mapbox_compass_icon))
+ .position(new LatLng(4, 1))
+ );
+ mapboxMap.addMarker(new MarkerOptions()
+ .icon(IconUtils.drawableToIcon(activity, R.drawable.ic_stars,
+ ResourcesCompat.getColor(activity.getResources(),
+ R.color.blueAccent, activity.getTheme())))
+ .position(new LatLng(5, 1))
+ );
+ mapboxMap.addMarker(new MarkerOptions()
+ .icon(iconFactory.fromResource(R.drawable.ic_android))
+ .position(new LatLng(6, 1))
+ );
+
+ assertEquals("Amount of icons should match 5", 5, iconMap.size());
+ assertEquals("Refcounter of default marker should match 2", 2, iconMap.get(iconFactory.defaultMarker()), 0);
+
+ mapboxMap.removeMarker(defaultMarkerOne);
+
+ assertEquals("Amount of icons should match 5", 5, iconMap.size());
+ assertEquals("Refcounter of default marker should match 1", 1, iconMap.get(iconFactory.defaultMarker()), 0);
+
+ mapboxMap.removeMarker(defaultMarkerTwo);
+
+ assertEquals("Amount of icons should match 4", 4, iconMap.size());
+ assertNull("DefaultMarker shouldn't exist anymore", iconMap.get(iconFactory.defaultMarker()));
+
+ mapboxMap.clear();
+ assertEquals("Amount of icons should match 0", 0, iconMap.size());
}
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraForTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraForTest.java
index eb38bddf84..4365ea95ff 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraForTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraForTest.java
@@ -1,6 +1,7 @@
package com.mapbox.mapboxsdk.testapp.camera;
import android.support.annotation.NonNull;
+import android.support.test.annotation.UiThreadTest;
import com.mapbox.geojson.Point;
import com.mapbox.geojson.Polygon;
import com.mapbox.mapboxsdk.camera.CameraPosition;
@@ -18,123 +19,117 @@ import static org.junit.Assert.assertEquals;
public class CameraForTest extends BaseTest {
@Test
+ @UiThreadTest
public void testGetCameraForLatLngBounds() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- CameraPosition actualPosition = mapboxMap.getCameraForLatLngBounds(
- LatLngBounds.from(10, 10, -10, -10));
- CameraPosition expectedPosition = new CameraPosition.Builder()
- .target(new LatLng()).zoom(4.16).tilt(0).bearing(0).build();
- assertEquals("Latitude should match",
- expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
- assertEquals("Longitude should match",
- expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
- assertEquals("Bearing should match",
- expectedPosition.zoom, actualPosition.zoom, 0.01f);
- assertEquals("Tilt should match", expectedPosition.tilt, actualPosition.tilt, 0.01f);
- }));
+ CameraPosition actualPosition = mapboxMap.getCameraForLatLngBounds(
+ LatLngBounds.from(10, 10, -10, -10));
+ CameraPosition expectedPosition = new CameraPosition.Builder()
+ .target(new LatLng()).zoom(4.16).tilt(0).bearing(0).build();
+ assertEquals("Latitude should match",
+ expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
+ assertEquals("Longitude should match",
+ expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
+ assertEquals("Bearing should match",
+ expectedPosition.zoom, actualPosition.zoom, 0.01f);
+ assertEquals("Tilt should match", expectedPosition.tilt, actualPosition.tilt, 0.01f);
}
@Test
+ @UiThreadTest
public void testGetCameraForLatLngBoundsPadding() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- CameraPosition actualPosition = mapboxMap.getCameraForLatLngBounds(
- LatLngBounds.from(10, 10, -10, -10), new int[] {5, 5, 5, 5});
- CameraPosition expectedPosition = new CameraPosition.Builder()
- .target(new LatLng()).zoom(4.13).tilt(0).bearing(0).build();
- assertEquals("Latitude should match",
- expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
- assertEquals("Longitude should match",
- expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
- assertEquals("Zoom should match",
- expectedPosition.zoom, actualPosition.zoom, 0.01f);
- assertEquals("Tilt should match",
- expectedPosition.tilt, actualPosition.tilt, 0.01f);
- assertEquals("Bearing should match",
- expectedPosition.bearing, actualPosition.bearing, 0.01f);
- }));
+ CameraPosition actualPosition = mapboxMap.getCameraForLatLngBounds(
+ LatLngBounds.from(10, 10, -10, -10), new int[] {5, 5, 5, 5});
+ CameraPosition expectedPosition = new CameraPosition.Builder()
+ .target(new LatLng()).zoom(4.13).tilt(0).bearing(0).build();
+ assertEquals("Latitude should match",
+ expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
+ assertEquals("Longitude should match",
+ expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
+ assertEquals("Zoom should match",
+ expectedPosition.zoom, actualPosition.zoom, 0.01f);
+ assertEquals("Tilt should match",
+ expectedPosition.tilt, actualPosition.tilt, 0.01f);
+ assertEquals("Bearing should match",
+ expectedPosition.bearing, actualPosition.bearing, 0.01f);
}
@Test
+ @UiThreadTest
public void testGetCameraForLatLngBoundsBearing() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- CameraPosition actualPosition = mapboxMap.getCameraForLatLngBounds(
- LatLngBounds.from(10, 10, -10, -10), 45, 0);
- CameraPosition expectedPosition = new CameraPosition.Builder()
- .target(new LatLng()).zoom(3.66).tilt(0).bearing(45).build();
- assertEquals("Latitude should match",
- expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
- assertEquals("Longitude should match",
- expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
- assertEquals("Zoom should match",
- expectedPosition.zoom, actualPosition.zoom, 0.01f);
- assertEquals("Tilt should match",
- expectedPosition.tilt, actualPosition.tilt, 0.01f);
- assertEquals("Bearing should match",
- expectedPosition.bearing, actualPosition.bearing, 0.01f);
- }));
+ CameraPosition actualPosition = mapboxMap.getCameraForLatLngBounds(
+ LatLngBounds.from(10, 10, -10, -10), 45, 0);
+ CameraPosition expectedPosition = new CameraPosition.Builder()
+ .target(new LatLng()).zoom(3.66).tilt(0).bearing(45).build();
+ assertEquals("Latitude should match",
+ expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
+ assertEquals("Longitude should match",
+ expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
+ assertEquals("Zoom should match",
+ expectedPosition.zoom, actualPosition.zoom, 0.01f);
+ assertEquals("Tilt should match",
+ expectedPosition.tilt, actualPosition.tilt, 0.01f);
+ assertEquals("Bearing should match",
+ expectedPosition.bearing, actualPosition.bearing, 0.01f);
}
@Test
+ @UiThreadTest
public void testGetCameraForLatLngBoundsTilt() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- CameraPosition actualPosition = mapboxMap.getCameraForLatLngBounds(
- LatLngBounds.from(10, 10, -10, -10), 0, 45);
- CameraPosition expectedPosition = new CameraPosition.Builder()
- .target(new LatLng(-0.264576975267, 0)).zoom(4.13).tilt(45).bearing(0).build();
- assertEquals("Latitude should match",
- expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
- assertEquals("Longitude should match",
- expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
- assertEquals("Zoom should match",
- expectedPosition.zoom, actualPosition.zoom, 0.01f);
- assertEquals("Tilt should match",
- expectedPosition.tilt, actualPosition.tilt, 0.01f);
- assertEquals("Bearing should match",
- expectedPosition.bearing, actualPosition.bearing, 0.01f);
- }));
+ CameraPosition actualPosition = mapboxMap.getCameraForLatLngBounds(
+ LatLngBounds.from(10, 10, -10, -10), 0, 45);
+ CameraPosition expectedPosition = new CameraPosition.Builder()
+ .target(new LatLng(-0.264576975267, 0)).zoom(4.13).tilt(45).bearing(0).build();
+ assertEquals("Latitude should match",
+ expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
+ assertEquals("Longitude should match",
+ expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
+ assertEquals("Zoom should match",
+ expectedPosition.zoom, actualPosition.zoom, 0.01f);
+ assertEquals("Tilt should match",
+ expectedPosition.tilt, actualPosition.tilt, 0.01f);
+ assertEquals("Bearing should match",
+ expectedPosition.bearing, actualPosition.bearing, 0.01f);
}
@Test
+ @UiThreadTest
public void testGetCameraForLatLngBoundsAll() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- CameraPosition actualPosition = mapboxMap.getCameraForLatLngBounds(
- LatLngBounds.from(10, 10, -10, -10), new int[] {5, 5, 5, 5}, 45, 45);
- CameraPosition expectedPosition = new CameraPosition.Builder()
- .target(new LatLng(-0.3732134634, -0.3713191053)).zoom(3.63).tilt(45).bearing(45).build();
- assertEquals("Latitude should match",
- expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
- assertEquals("Longitude should match",
- expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
- assertEquals("Zoom should match",
- expectedPosition.zoom, actualPosition.zoom, 0.01f);
- assertEquals("Tilt should match",
- expectedPosition.tilt, actualPosition.tilt, 0.01f);
- assertEquals("Bearing should match",
- expectedPosition.bearing, actualPosition.bearing, 0.01f);
- }));
+ CameraPosition actualPosition = mapboxMap.getCameraForLatLngBounds(
+ LatLngBounds.from(10, 10, -10, -10), new int[] {5, 5, 5, 5}, 45, 45);
+ CameraPosition expectedPosition = new CameraPosition.Builder()
+ .target(new LatLng(-0.3732134634, -0.3713191053)).zoom(3.63).tilt(45).bearing(45).build();
+ assertEquals("Latitude should match",
+ expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
+ assertEquals("Longitude should match",
+ expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
+ assertEquals("Zoom should match",
+ expectedPosition.zoom, actualPosition.zoom, 0.01f);
+ assertEquals("Tilt should match",
+ expectedPosition.tilt, actualPosition.tilt, 0.01f);
+ assertEquals("Bearing should match",
+ expectedPosition.bearing, actualPosition.bearing, 0.01f);
}
@Test
+ @UiThreadTest
public void testGetCameraForGeometry() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- List<List<Point>> polygonDefinition = getPolygonDefinition();
- CameraPosition actualPosition = mapboxMap.getCameraForGeometry(Polygon.fromLngLats(polygonDefinition));
- CameraPosition expectedPosition = new CameraPosition.Builder()
- .target(new LatLng()).zoom(4.16).tilt(0).bearing(0).build();
- assertEquals("Latitude should match",
- expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
- assertEquals("Longitude should match",
- expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
- assertEquals("Bearing should match",
- expectedPosition.zoom, actualPosition.zoom, 0.01f);
- assertEquals("Tilt should match", expectedPosition.tilt, actualPosition.tilt, 0.01f);
- }));
+ List<List<Point>> polygonDefinition = getPolygonDefinition();
+ CameraPosition actualPosition = mapboxMap.getCameraForGeometry(Polygon.fromLngLats(polygonDefinition));
+ CameraPosition expectedPosition = new CameraPosition.Builder()
+ .target(new LatLng()).zoom(4.16).tilt(0).bearing(0).build();
+ assertEquals("Latitude should match",
+ expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
+ assertEquals("Longitude should match",
+ expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
+ assertEquals("Bearing should match",
+ expectedPosition.zoom, actualPosition.zoom, 0.01f);
+ assertEquals("Tilt should match", expectedPosition.tilt, actualPosition.tilt, 0.01f);
}
@NonNull
@@ -154,113 +149,108 @@ public class CameraForTest extends BaseTest {
}
@Test
+ @UiThreadTest
public void testGetCameraForGeometryPadding() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- List<List<Point>> polygonDefinition = getPolygonDefinition();
- CameraPosition actualPosition = mapboxMap.getCameraForGeometry(Polygon.fromLngLats(polygonDefinition),
- new int[] {5, 5, 5, 5});
- CameraPosition expectedPosition = new CameraPosition.Builder()
- .target(new LatLng()).zoom(4.13).tilt(0).bearing(0).build();
- assertEquals("Latitude should match",
- expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
- assertEquals("Longitude should match",
- expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
- assertEquals("Zoom should match",
- expectedPosition.zoom, actualPosition.zoom, 0.01f);
- assertEquals("Tilt should match",
- expectedPosition.tilt, actualPosition.tilt, 0.01f);
- assertEquals("Bearing should match",
- expectedPosition.bearing, actualPosition.bearing, 0.01f);
- }));
+ List<List<Point>> polygonDefinition = getPolygonDefinition();
+ CameraPosition actualPosition = mapboxMap.getCameraForGeometry(Polygon.fromLngLats(polygonDefinition),
+ new int[] {5, 5, 5, 5});
+ CameraPosition expectedPosition = new CameraPosition.Builder()
+ .target(new LatLng()).zoom(4.13).tilt(0).bearing(0).build();
+ assertEquals("Latitude should match",
+ expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
+ assertEquals("Longitude should match",
+ expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
+ assertEquals("Zoom should match",
+ expectedPosition.zoom, actualPosition.zoom, 0.01f);
+ assertEquals("Tilt should match",
+ expectedPosition.tilt, actualPosition.tilt, 0.01f);
+ assertEquals("Bearing should match",
+ expectedPosition.bearing, actualPosition.bearing, 0.01f);
}
@Test
+ @UiThreadTest
public void testGetCameraForGeometryBearing() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- List<List<Point>> polygonDefinition = getPolygonDefinition();
- CameraPosition actualPosition = mapboxMap.getCameraForGeometry(Polygon.fromLngLats(polygonDefinition), 45, 0);
- CameraPosition expectedPosition = new CameraPosition.Builder()
- .target(new LatLng()).zoom(3.66).tilt(0).bearing(45).build();
- assertEquals("Latitude should match",
- expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
- assertEquals("Longitude should match",
- expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
- assertEquals("Zoom should match",
- expectedPosition.zoom, actualPosition.zoom, 0.01f);
- assertEquals("Tilt should match",
- expectedPosition.tilt, actualPosition.tilt, 0.01f);
- assertEquals("Bearing should match",
- expectedPosition.bearing, actualPosition.bearing, 0.01f);
- }));
+ List<List<Point>> polygonDefinition = getPolygonDefinition();
+ CameraPosition actualPosition = mapboxMap.getCameraForGeometry(Polygon.fromLngLats(polygonDefinition), 45, 0);
+ CameraPosition expectedPosition = new CameraPosition.Builder()
+ .target(new LatLng()).zoom(3.66).tilt(0).bearing(45).build();
+ assertEquals("Latitude should match",
+ expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
+ assertEquals("Longitude should match",
+ expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
+ assertEquals("Zoom should match",
+ expectedPosition.zoom, actualPosition.zoom, 0.01f);
+ assertEquals("Tilt should match",
+ expectedPosition.tilt, actualPosition.tilt, 0.01f);
+ assertEquals("Bearing should match",
+ expectedPosition.bearing, actualPosition.bearing, 0.01f);
}
@Test
+ @UiThreadTest
public void testGetCameraForGeometryTilt() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- List<List<Point>> polygonDefinition = getPolygonDefinition();
- CameraPosition actualPosition = mapboxMap.getCameraForGeometry(Polygon.fromLngLats(polygonDefinition), 0, 45);
- CameraPosition expectedPosition = new CameraPosition.Builder()
- .target(new LatLng(-0.2645769752, 0)).zoom(4.13).tilt(45).bearing(0).build();
- assertEquals("Latitude should match",
- expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
- assertEquals("Longitude should match",
- expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
- assertEquals("Zoom should match",
- expectedPosition.zoom, actualPosition.zoom, 0.01f);
- assertEquals("Tilt should match",
- expectedPosition.tilt, actualPosition.tilt, 0.01f);
- assertEquals("Bearing should match",
- expectedPosition.bearing, actualPosition.bearing, 0.01f);
- }));
+ List<List<Point>> polygonDefinition = getPolygonDefinition();
+ CameraPosition actualPosition = mapboxMap.getCameraForGeometry(Polygon.fromLngLats(polygonDefinition), 0, 45);
+ CameraPosition expectedPosition = new CameraPosition.Builder()
+ .target(new LatLng(-0.2645769752, 0)).zoom(4.13).tilt(45).bearing(0).build();
+ assertEquals("Latitude should match",
+ expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
+ assertEquals("Longitude should match",
+ expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
+ assertEquals("Zoom should match",
+ expectedPosition.zoom, actualPosition.zoom, 0.01f);
+ assertEquals("Tilt should match",
+ expectedPosition.tilt, actualPosition.tilt, 0.01f);
+ assertEquals("Bearing should match",
+ expectedPosition.bearing, actualPosition.bearing, 0.01f);
}
@Test
+ @UiThreadTest
public void testGetCameraForGeometryAll() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- List<List<Point>> polygonDefinition = getPolygonDefinition();
- CameraPosition actualPosition = mapboxMap.getCameraForGeometry(Polygon.fromLngLats(polygonDefinition),
- new int[] {5, 5, 5, 5}, 45, 45);
- CameraPosition expectedPosition = new CameraPosition.Builder()
- .target(new LatLng(-0.373213463, -0.37131910534)).zoom(3.63).tilt(45).bearing(45).build();
- assertEquals("Latitude should match",
- expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
- assertEquals("Longitude should match",
- expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
- assertEquals("Zoom should match",
- expectedPosition.zoom, actualPosition.zoom, 0.01f);
- assertEquals("Tilt should match",
- expectedPosition.tilt, actualPosition.tilt, 0.01f);
- assertEquals("Bearing should match",
- expectedPosition.bearing, actualPosition.bearing, 0.01f);
- }));
+ List<List<Point>> polygonDefinition = getPolygonDefinition();
+ CameraPosition actualPosition = mapboxMap.getCameraForGeometry(Polygon.fromLngLats(polygonDefinition),
+ new int[] {5, 5, 5, 5}, 45, 45);
+ CameraPosition expectedPosition = new CameraPosition.Builder()
+ .target(new LatLng(-0.373213463, -0.37131910534)).zoom(3.63).tilt(45).bearing(45).build();
+ assertEquals("Latitude should match",
+ expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
+ assertEquals("Longitude should match",
+ expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
+ assertEquals("Zoom should match",
+ expectedPosition.zoom, actualPosition.zoom, 0.01f);
+ assertEquals("Tilt should match",
+ expectedPosition.tilt, actualPosition.tilt, 0.01f);
+ assertEquals("Bearing should match",
+ expectedPosition.bearing, actualPosition.bearing, 0.01f);
}
@Test
+ @UiThreadTest
public void testGetCameraForGeometryDeprecatedApi() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- List<List<Point>> polygonDefinition = getPolygonDefinition();
- CameraPosition actualPosition = mapboxMap.getCameraForGeometry(
- Polygon.fromLngLats(polygonDefinition),
- new int[] {5, 5, 5, 5},
- 45, 0);
- CameraPosition expectedPosition = new CameraPosition.Builder()
- .target(new LatLng()).zoom(3.63).tilt(0).bearing(45).build();
- assertEquals("Latitude should match",
- expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
- assertEquals("Longitude should match",
- expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
- assertEquals("Zoom should match",
- expectedPosition.zoom, actualPosition.zoom, 0.01f);
- assertEquals("Tilt should match",
- expectedPosition.tilt, actualPosition.tilt, 0.01f);
- assertEquals("Bearing should match",
- expectedPosition.bearing, actualPosition.bearing, 0.01f);
- }));
+ List<List<Point>> polygonDefinition = getPolygonDefinition();
+ CameraPosition actualPosition = mapboxMap.getCameraForGeometry(
+ Polygon.fromLngLats(polygonDefinition),
+ new int[] {5, 5, 5, 5},
+ 45, 0);
+ CameraPosition expectedPosition = new CameraPosition.Builder()
+ .target(new LatLng()).zoom(3.63).tilt(0).bearing(45).build();
+ assertEquals("Latitude should match",
+ expectedPosition.target.getLatitude(), actualPosition.target.getLatitude(), 0.00001f);
+ assertEquals("Longitude should match",
+ expectedPosition.target.getLongitude(), actualPosition.target.getLongitude(), 0.00001f);
+ assertEquals("Zoom should match",
+ expectedPosition.zoom, actualPosition.zoom, 0.01f);
+ assertEquals("Tilt should match",
+ expectedPosition.tilt, actualPosition.tilt, 0.01f);
+ assertEquals("Bearing should match",
+ expectedPosition.bearing, actualPosition.bearing, 0.01f);
}
@Override
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/fragment/MapDialogFragmentTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/fragment/MapDialogFragmentTest.kt
index 418191e91a..2731b20db7 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/fragment/MapDialogFragmentTest.kt
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/fragment/MapDialogFragmentTest.kt
@@ -10,6 +10,7 @@ import android.support.test.runner.AndroidJUnit4
import com.mapbox.mapboxsdk.testapp.R
import com.mapbox.mapboxsdk.testapp.action.WaitAction
import com.mapbox.mapboxsdk.testapp.activity.maplayout.MapInDialogActivity
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -25,9 +26,10 @@ class MapDialogFragmentTest {
var activityRule: ActivityTestRule<MapInDialogActivity> = ActivityTestRule(MapInDialogActivity::class.java)
@Test
+ @Ignore
fun openCloseDialog() {
onView(withId(R.id.button_open_dialog)).perform(click())
- onView(withId(R.id.mapView)).perform(WaitAction(2500))
+ Thread.sleep(2500)
Espresso.pressBack()
}
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/geometry/GeoJsonConversionTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/geometry/GeoJsonConversionTest.java
index c34e76a6e5..f30b3aa8cf 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/geometry/GeoJsonConversionTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/geometry/GeoJsonConversionTest.java
@@ -1,5 +1,6 @@
package com.mapbox.mapboxsdk.testapp.geometry;
+import android.support.test.annotation.UiThreadTest;
import com.google.gson.JsonArray;
import com.mapbox.geojson.Feature;
import com.mapbox.geojson.FeatureCollection;
@@ -13,11 +14,13 @@ import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
import com.mapbox.mapboxsdk.style.sources.CustomGeometrySource;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
import com.mapbox.mapboxsdk.style.sources.GeometryTileProvider;
+import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction;
import com.mapbox.mapboxsdk.testapp.activity.EspressoTest;
import com.mapbox.mapboxsdk.testapp.utils.TestingAsyncUtils;
-
import org.junit.Test;
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.matcher.ViewMatchers.isRoot;
import static com.mapbox.geojson.Feature.fromGeometry;
import static com.mapbox.geojson.FeatureCollection.fromFeatures;
import static com.mapbox.geojson.GeometryCollection.fromGeometries;
@@ -35,101 +38,94 @@ public class GeoJsonConversionTest extends EspressoTest {
// Regression test for #12343
@Test
+ @UiThreadTest
public void testEmptyFeatureCollection() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- mapboxMap.getStyle().addSource(
- new CustomGeometrySource("test-id",
- new CustomProvider(fromFeatures(singletonList(fromGeometry(fromGeometries(emptyList())))))
- )
- );
- mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id"));
- }));
+ mapboxMap.getStyle().addSource(
+ new CustomGeometrySource("test-id",
+ new CustomProvider(fromFeatures(singletonList(fromGeometry(fromGeometries(emptyList())))))
+ )
+ );
+ mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id"));
}
@Test
+ @UiThreadTest
public void testPointFeatureCollection() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- mapboxMap.getStyle().addSource(
- new CustomGeometrySource("test-id",
- new CustomProvider(fromFeatures(singletonList(fromGeometry(Point.fromLngLat(0.0, 0.0)))))
- )
- );
- mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id"));
- }));
+ mapboxMap.getStyle().addSource(
+ new CustomGeometrySource("test-id",
+ new CustomProvider(fromFeatures(singletonList(fromGeometry(Point.fromLngLat(0.0, 0.0)))))
+ )
+ );
+ mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id"));
}
@Test
+ @UiThreadTest
public void testMultiPointFeatureCollection() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- mapboxMap.getStyle().addSource(
- new CustomGeometrySource("test-id",
- new CustomProvider(fromFeatures(singletonList(fromGeometry(fromLngLats(emptyList())))))
- )
- );
- mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id"));
- }));
+ mapboxMap.getStyle().addSource(
+ new CustomGeometrySource("test-id",
+ new CustomProvider(fromFeatures(singletonList(fromGeometry(fromLngLats(emptyList())))))
+ )
+ );
+ mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id"));
}
-
@Test
+ @UiThreadTest
public void testPolygonFeatureCollection() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- mapboxMap.getStyle().addSource(
- new CustomGeometrySource("test-id",
- new CustomProvider(fromFeatures(singletonList(fromGeometry(Polygon.fromLngLats(emptyList())))))
- )
- );
- mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id"));
- }));
+ mapboxMap.getStyle().addSource(
+ new CustomGeometrySource("test-id",
+ new CustomProvider(fromFeatures(singletonList(fromGeometry(Polygon.fromLngLats(emptyList())))))
+ )
+ );
+ mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id"));
}
@Test
+ @UiThreadTest
public void testMultiPolygonFeatureCollection() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- mapboxMap.getStyle().addSource(
- new CustomGeometrySource("test-id",
- new CustomProvider(fromFeatures(singletonList(fromGeometry(fromPolygon(Polygon.fromLngLats(emptyList()))))))
- )
- );
- mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id"));
- }));
+ mapboxMap.getStyle().addSource(
+ new CustomGeometrySource("test-id",
+ new CustomProvider(fromFeatures(singletonList(fromGeometry(fromPolygon(Polygon.fromLngLats(emptyList()))))))
+ )
+ );
+ mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id"));
}
@Test
+ @UiThreadTest
public void testLineStringFeatureCollection() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- mapboxMap.getStyle().addSource(
- new CustomGeometrySource("test-id",
- new CustomProvider(fromFeatures(singletonList(fromGeometry(fromLngLats(emptyList())))))
- )
- );
- mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id"));
- }));
+ mapboxMap.getStyle().addSource(
+ new CustomGeometrySource("test-id",
+ new CustomProvider(fromFeatures(singletonList(fromGeometry(fromLngLats(emptyList())))))
+ )
+ );
+ mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id"));
}
@Test
+ @UiThreadTest
public void testMultiLineStringFeatureCollection() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
- mapboxMap.getStyle().addSource(
- new CustomGeometrySource("test-id",
- new CustomProvider(fromFeatures(singletonList(fromGeometry(fromLineString(fromLngLats(emptyList()))))))
- )
- );
- mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id"));
- }));
+ mapboxMap.getStyle().addSource(
+ new CustomGeometrySource("test-id",
+ new CustomProvider(fromFeatures(singletonList(fromGeometry(fromLineString(fromLngLats(emptyList()))))))
+ )
+ );
+ mapboxMap.getStyle().addLayer(new SymbolLayer("test-id", "test-id"));
}
+
@Test
public void testNegativeNumberPropertyConversion() {
validateTestSetup();
- onMapView().perform(getMapboxMapAction((uiController, mapboxMap) -> {
+ onView(isRoot()).perform(new MapboxMapAction((uiController, mapboxMap) -> {
LatLng latLng = new LatLng();
Feature feature = Feature.fromGeometry(Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude()));
@@ -148,10 +144,10 @@ public class GeoJsonConversionTest extends EspressoTest {
);
mapboxMap.getStyle().addLayer(layer);
- TestingAsyncUtils.INSTANCE.waitForLayer(uiController, idlingResource.getMapView());
+ TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView);
assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng)).isEmpty());
- }));
+ }, mapboxMap));
}
class CustomProvider implements GeometryTileProvider {
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/StyleLoadTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/StyleLoadTest.kt
index 84af279bd0..ac73b028f3 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/StyleLoadTest.kt
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/StyleLoadTest.kt
@@ -18,14 +18,6 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class StyleLoadTest : EspressoTest() {
- private lateinit var mapView: MapView
-
- @Before
- override fun beforeTest() {
- super.beforeTest()
- mapView = (rule.activity as EspressoTestActivity).mapView
- }
-
@Test
fun updateSourceAfterStyleLoad() {
validateTestSetup()
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/AttributionTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/AttributionTest.java
index 0fadd33325..ca5c9adc1f 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/AttributionTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/AttributionTest.java
@@ -3,6 +3,7 @@ package com.mapbox.mapboxsdk.testapp.maps.widgets;
import android.app.Instrumentation;
import android.content.Intent;
import android.net.Uri;
+import android.os.Build;
import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
import android.support.test.espresso.intent.Intents;
@@ -31,12 +32,14 @@ import static android.support.test.espresso.intent.Intents.intended;
import static android.support.test.espresso.intent.Intents.intending;
import static android.support.test.espresso.intent.matcher.IntentMatchers.hasAction;
import static android.support.test.espresso.intent.matcher.IntentMatchers.hasData;
+import static android.support.test.espresso.matcher.RootMatchers.isDialog;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.anything;
import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assume.assumeTrue;
public class AttributionTest extends EspressoTest {
@@ -126,15 +129,20 @@ public class AttributionTest extends EspressoTest {
@Test
public void testTelemetryDialog() {
+ assumeTrue(
+ "Can only run on API Level 23 or newer because of instability",
+ Build.VERSION.SDK_INT >= 23
+ );
+
validateTestSetup();
// click on View to open dialog
onView(withId(R.id.attributionView)).perform(click());
- onView(withText(R.string.mapbox_attributionsDialogTitle)).check(matches(isDisplayed()));
+ onView(withText(R.string.mapbox_attributionsDialogTitle)).inRoot(isDialog()).check(matches(isDisplayed()));
// click on item to open second dialog
- onView(withText(R.string.mapbox_telemetrySettings)).perform(click());
- onView(withText(R.string.mapbox_attributionTelemetryTitle)).check(matches(isDisplayed()));
+ onView(withText(R.string.mapbox_telemetrySettings)).inRoot(isDialog()).perform(click());
+ onView(withText(R.string.mapbox_attributionTelemetryTitle)).inRoot(isDialog()).check(matches(isDisplayed()));
}
@After
@@ -206,4 +214,4 @@ public class AttributionTest extends EspressoTest {
interface InvokeViewAction {
void onViewAction(UiController uiController, View view);
}
-}
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/CompassViewTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/CompassViewTest.java
index 1cdf1423a3..8b62ee7612 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/CompassViewTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/CompassViewTest.java
@@ -4,6 +4,7 @@ import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.action.WaitAction;
import com.mapbox.mapboxsdk.testapp.activity.EspressoTest;
import com.mapbox.mapboxsdk.testapp.utils.TestConstants;
import org.junit.Ignore;
@@ -55,7 +56,7 @@ public class CompassViewTest extends EspressoTest {
.build()
)));
onView(withId(R.id.compassView)).perform(click());
- waitAction();
+ WaitAction.invoke(500);
onView(withId(R.id.compassView)).check(matches(not(isDisplayed())));
invoke(mapboxMap, (uiController, mapboxMap) -> {
CameraPosition cameraPosition = mapboxMap.getCameraPosition();
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/offline/OfflineManagerTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/offline/OfflineManagerTest.kt
index 144d67feee..8e5f3f7c5f 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/offline/OfflineManagerTest.kt
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/offline/OfflineManagerTest.kt
@@ -1,59 +1,43 @@
package com.mapbox.mapboxsdk.testapp.offline
import android.content.Context
-import android.support.test.espresso.Espresso
-import android.support.test.espresso.IdlingRegistry
-import android.support.test.espresso.UiController
-import android.support.test.espresso.idling.CountingIdlingResource
+import android.support.test.rule.ActivityTestRule
import android.support.test.runner.AndroidJUnit4
-import com.mapbox.mapboxsdk.maps.MapboxMap
import com.mapbox.mapboxsdk.offline.OfflineManager
import com.mapbox.mapboxsdk.offline.OfflineRegion
import com.mapbox.mapboxsdk.storage.FileSource
-import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke
-import com.mapbox.mapboxsdk.testapp.activity.EspressoTest
+import com.mapbox.mapboxsdk.testapp.activity.FeatureOverviewActivity
import com.mapbox.mapboxsdk.testapp.utils.FileUtils
+import org.junit.FixMethodOrder
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
import java.io.IOException
+import java.util.concurrent.CountDownLatch
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RunWith(AndroidJUnit4::class)
-class OfflineManagerTest : EspressoTest() {
+class OfflineManagerTest {
companion object {
private const val TEST_DB_FILE_NAME = "offline_test.db"
+ private lateinit var mergedRegion: OfflineRegion
}
- private val context: Context by lazy { rule.activity }
-
- private lateinit var offlineIdlingResource: CountingIdlingResource
-
- override fun beforeTest() {
- super.beforeTest()
- offlineIdlingResource = CountingIdlingResource("idling_resource")
- IdlingRegistry.getInstance().register(offlineIdlingResource)
- }
+ @Rule
+ @JvmField
+ var rule = ActivityTestRule(FeatureOverviewActivity::class.java)
- @Test
- fun offlineMergeListDeleteTest() {
- validateTestSetup()
+ private val context: Context by lazy { rule.activity }
- invoke(mapboxMap) { _: UiController, _: MapboxMap ->
- offlineIdlingResource.increment()
+ @Test(timeout = 30_000)
+ fun a_copyFileFromAssets() {
+ val latch = CountDownLatch(1)
+ rule.runOnUiThread {
FileUtils.CopyFileFromAssetsTask(rule.activity, object : FileUtils.OnFileCopiedFromAssetsListener {
override fun onFileCopiedFromAssets() {
- OfflineManager.getInstance(context).mergeOfflineRegions(
- FileSource.getResourcesCachePath(rule.activity) + "/" + TEST_DB_FILE_NAME,
- object : OfflineManager.MergeOfflineRegionsCallback {
- override fun onMerge(offlineRegions: Array<out OfflineRegion>?) {
- assert(offlineRegions?.size == 1)
- offlineIdlingResource.decrement()
- }
-
- override fun onError(error: String?) {
- throw RuntimeException("Unable to merge external offline database. $error")
- }
- })
+ latch.countDown()
}
override fun onError() {
@@ -61,43 +45,62 @@ class OfflineManagerTest : EspressoTest() {
}
}).execute(TEST_DB_FILE_NAME, FileSource.getResourcesCachePath(rule.activity))
}
+ latch.await()
+ }
+
+ @Test(timeout = 30_000)
+ fun b_mergeRegion() {
+ val latch = CountDownLatch(1)
+ rule.runOnUiThread {
+ OfflineManager.getInstance(context).mergeOfflineRegions(
+ FileSource.getResourcesCachePath(rule.activity) + "/" + TEST_DB_FILE_NAME,
+ object : OfflineManager.MergeOfflineRegionsCallback {
+ override fun onMerge(offlineRegions: Array<out OfflineRegion>?) {
+ assert(offlineRegions?.size == 1)
+ latch.countDown()
+ }
+
+ override fun onError(error: String?) {
+ throw RuntimeException("Unable to merge external offline database. $error")
+ }
+ })
+ }
+ latch.await()
+ }
- invoke(mapboxMap) { _: UiController, _: MapboxMap ->
- offlineIdlingResource.increment()
+ @Test(timeout = 30_000)
+ fun c_listRegion() {
+ val latch = CountDownLatch(1)
+ rule.runOnUiThread {
OfflineManager.getInstance(context).listOfflineRegions(object : OfflineManager.ListOfflineRegionsCallback {
override fun onList(offlineRegions: Array<out OfflineRegion>?) {
assert(offlineRegions?.size == 1)
- if (offlineRegions != null) {
- for (region in offlineRegions) {
- offlineIdlingResource.increment()
- region.delete(object : OfflineRegion.OfflineRegionDeleteCallback {
- override fun onDelete() {
- offlineIdlingResource.decrement()
- }
-
- override fun onError(error: String?) {
- throw RuntimeException("Unable to delete region with ID: ${region.id}. $error")
- }
- })
- }
- } else {
- throw RuntimeException("Unable to find merged region.")
- }
- offlineIdlingResource.decrement()
+ mergedRegion = offlineRegions!![0]
+ latch.countDown()
}
override fun onError(error: String?) {
- throw RuntimeException("Unable to obtain offline regions list. $error")
+ throw RuntimeException("Unable to merge external offline database. $error")
}
})
}
-
- // waiting for offline idling resource
- Espresso.onIdle()
+ latch.await()
}
- override fun afterTest() {
- super.afterTest()
- IdlingRegistry.getInstance().unregister(offlineIdlingResource)
+ @Test(timeout = 30_000)
+ fun d_deleteRegion() {
+ val latch = CountDownLatch(1)
+ rule.runOnUiThread {
+ mergedRegion.delete(object : OfflineRegion.OfflineRegionDeleteCallback {
+ override fun onDelete() {
+ latch.countDown()
+ }
+
+ override fun onError(error: String?) {
+ throw RuntimeException("Unable to delete region")
+ }
+ })
+ }
+ latch.await()
}
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CustomGeometrySourceTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CustomGeometrySourceTest.kt
index eb458ab8f5..a6238ebf14 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CustomGeometrySourceTest.kt
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CustomGeometrySourceTest.kt
@@ -6,8 +6,9 @@ import com.mapbox.mapboxsdk.style.sources.CustomGeometrySource
import com.mapbox.mapboxsdk.style.sources.CustomGeometrySource.THREAD_POOL_LIMIT
import com.mapbox.mapboxsdk.style.sources.CustomGeometrySource.THREAD_PREFIX
import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke
-import com.mapbox.mapboxsdk.testapp.action.OrientationChangeAction.orientationLandscape
-import com.mapbox.mapboxsdk.testapp.action.OrientationChangeAction.orientationPortrait
+import com.mapbox.mapboxsdk.testapp.action.OrientationAction.orientationLandscape
+import com.mapbox.mapboxsdk.testapp.action.OrientationAction.orientationPortrait
+import com.mapbox.mapboxsdk.testapp.action.WaitAction
import com.mapbox.mapboxsdk.testapp.activity.BaseTest
import com.mapbox.mapboxsdk.testapp.activity.style.GridSourceActivity
import com.mapbox.mapboxsdk.testapp.activity.style.GridSourceActivity.ID_GRID_LAYER
@@ -25,11 +26,11 @@ class CustomGeometrySourceTest : BaseTest() {
@Ignore
fun sourceNotLeakingThreadsTest() {
validateTestSetup()
- waitAction(4000)
+ WaitAction.invoke(4000)
onView(isRoot()).perform(orientationLandscape())
- waitAction(2000)
+ WaitAction.invoke(2000)
onView(isRoot()).perform(orientationPortrait())
- waitAction(2000)
+ WaitAction.invoke(2000)
Assert.assertFalse("Threads should be shutdown when the source is destroyed.",
Thread.getAllStackTraces().keys.filter {
it.name.startsWith(THREAD_PREFIX)
@@ -42,9 +43,9 @@ class CustomGeometrySourceTest : BaseTest() {
validateTestSetup()
invoke(mapboxMap) { uiController, mapboxMap ->
mapboxMap.style!!.removeLayer(ID_GRID_LAYER)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
mapboxMap.style!!.removeSource(ID_GRID_SOURCE)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
Assert.assertTrue("There should be no threads running when the source is removed.",
Thread.getAllStackTraces().keys.filter {
it.name.startsWith(CustomGeometrySource.THREAD_PREFIX)
@@ -58,12 +59,12 @@ class CustomGeometrySourceTest : BaseTest() {
validateTestSetup()
invoke(mapboxMap) { uiController, mapboxMap ->
mapboxMap.style!!.removeLayer((rule.activity as GridSourceActivity).layer)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
mapboxMap.style!!.removeSource(ID_GRID_SOURCE)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
mapboxMap.style!!.addSource((rule.activity as GridSourceActivity).source)
mapboxMap.style!!.addLayer((rule.activity as GridSourceActivity).layer)
- TestingAsyncUtils.waitForLayer(uiController, idlingResource.mapView)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
Assert.assertTrue("Threads should be restarted when the source is re-added to the map.",
Thread.getAllStackTraces().keys.filter {
it.name.startsWith(CustomGeometrySource.THREAD_PREFIX)
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ExpressionTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ExpressionTest.java
index 75dcbf1209..ff3b2a9d6d 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ExpressionTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ExpressionTest.java
@@ -252,7 +252,7 @@ public class ExpressionTest extends EspressoTest {
)
));
mapboxMap.getStyle().addLayer(layer);
- TestingAsyncUtils.INSTANCE.waitForLayer(uiController, idlingResource.getMapView());
+ TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView);
assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer")
.isEmpty());
@@ -262,7 +262,7 @@ public class ExpressionTest extends EspressoTest {
literal(ColorUtils.colorToRgbaString(Color.RED))
)
));
- TestingAsyncUtils.INSTANCE.waitForLayer(uiController, idlingResource.getMapView());
+ TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView);
assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer")
.isEmpty());
@@ -272,7 +272,7 @@ public class ExpressionTest extends EspressoTest {
literal(ColorUtils.colorToRgbaString(Color.RED))
)
));
- TestingAsyncUtils.INSTANCE.waitForLayer(uiController, idlingResource.getMapView());
+ TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView);
assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer")
.isEmpty());
});
@@ -292,7 +292,7 @@ public class ExpressionTest extends EspressoTest {
formatEntry("test")
);
layer.setProperties(textField(expression));
- TestingAsyncUtils.INSTANCE.waitForLayer(uiController, idlingResource.getMapView());
+ TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView);
assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer")
.isEmpty());
@@ -315,7 +315,7 @@ public class ExpressionTest extends EspressoTest {
formatEntry("test", formatFontScale(1.75))
);
layer.setProperties(textField(expression));
- TestingAsyncUtils.INSTANCE.waitForLayer(uiController, idlingResource.getMapView());
+ TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView);
assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer")
.isEmpty());
@@ -341,7 +341,7 @@ public class ExpressionTest extends EspressoTest {
)
);
layer.setProperties(textField(expression));
- TestingAsyncUtils.INSTANCE.waitForLayer(uiController, idlingResource.getMapView());
+ TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView);
assertFalse(
mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer").isEmpty()
@@ -371,7 +371,7 @@ public class ExpressionTest extends EspressoTest {
)
);
layer.setProperties(textField(expression));
- TestingAsyncUtils.INSTANCE.waitForLayer(uiController, idlingResource.getMapView());
+ TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView);
assertFalse(
mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer").isEmpty()
@@ -402,7 +402,7 @@ public class ExpressionTest extends EspressoTest {
)
);
layer.setProperties(textField(expression));
- TestingAsyncUtils.INSTANCE.waitForLayer(uiController, idlingResource.getMapView());
+ TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView);
assertFalse(
mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer").isEmpty()
@@ -436,7 +436,7 @@ public class ExpressionTest extends EspressoTest {
formatEntry("\ntest2", formatFontScale(2), formatTextColor(Color.BLUE))
);
layer.setProperties(textField(expression));
- TestingAsyncUtils.INSTANCE.waitForLayer(uiController, idlingResource.getMapView());
+ TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView);
assertFalse(
mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer").isEmpty()
@@ -472,7 +472,7 @@ public class ExpressionTest extends EspressoTest {
)
);
layer.setProperties(textField(expression));
- TestingAsyncUtils.INSTANCE.waitForLayer(uiController, idlingResource.getMapView());
+ TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView);
assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer")
.isEmpty());
@@ -504,7 +504,7 @@ public class ExpressionTest extends EspressoTest {
formatEntry("\ntest2", formatFontScale(2))
);
layer.setProperties(textField(expression), textColor("rgba(128, 0, 0, 1)"));
- TestingAsyncUtils.INSTANCE.waitForLayer(uiController, idlingResource.getMapView());
+ TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView);
assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer")
.isEmpty());
@@ -524,7 +524,7 @@ public class ExpressionTest extends EspressoTest {
mapboxMap.getStyle().addLayer(layer);
layer.setProperties(textField("test"));
- TestingAsyncUtils.INSTANCE.waitForLayer(uiController, idlingResource.getMapView());
+ TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView);
assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer")
.isEmpty());
@@ -550,7 +550,7 @@ public class ExpressionTest extends EspressoTest {
new FormattedSection("test", null, null, "rgba(0, 255, 0, 1)")
);
layer.setProperties(textField(formatted), textColor("rgba(128, 0, 0, 1)"));
- TestingAsyncUtils.INSTANCE.waitForLayer(uiController, idlingResource.getMapView());
+ TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView);
assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer")
.isEmpty());
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/GeoJsonSourceTests.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/GeoJsonSourceTests.java
index 92d060fee4..99e0ae4016 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/GeoJsonSourceTests.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/GeoJsonSourceTests.java
@@ -94,7 +94,7 @@ public class GeoJsonSourceTests extends EspressoTest {
}
source.setGeoJson(Point.fromLngLat(20, 55));
- TestingAsyncUtils.INSTANCE.waitForLayer(uiController, idlingResource.getMapView());
+ TestingAsyncUtils.INSTANCE.waitForLayer(uiController, mapView);
assertEquals(1, mapboxMap.queryRenderedFeatures(
mapboxMap.getProjection().toScreenLocation(
new LatLng(55, 20)), "layer").size());
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ImageTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ImageTest.java
deleted file mode 100644
index 0e4c8f3f2e..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ImageTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.mapbox.mapboxsdk.testapp.style;
-
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction;
-
-import com.mapbox.mapboxsdk.testapp.activity.EspressoTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-/**
- * CRUD tests around Image
- */
-@RunWith(AndroidJUnit4.class)
-public class ImageTest extends EspressoTest {
-
- private static final String IMAGE_ID = "test.image";
-
- @Test
- public void testAddGetImage() {
- validateTestSetup();
- MapboxMapAction.invoke(mapboxMap, (uiController, mapboxMap) -> {
- Drawable drawable = rule.getActivity().getResources().getDrawable(R.drawable.ic_launcher_round);
- assertTrue(drawable instanceof BitmapDrawable);
-
- Bitmap bitmapSet = ((BitmapDrawable) drawable).getBitmap();
- mapboxMap.getStyle().addImage(IMAGE_ID, bitmapSet);
-
- // adding an image requires converting the image with an asynctask
- uiController.loopMainThreadForAtLeast(200);
-
- Bitmap bitmapGet = mapboxMap.getStyle().getImage(IMAGE_ID);
- assertTrue(bitmapGet.sameAs(bitmapSet));
-
- mapboxMap.getStyle().removeImage(IMAGE_ID);
- assertNull(mapboxMap.getStyle().getImage(IMAGE_ID));
- });
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ImageTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ImageTest.kt
new file mode 100644
index 0000000000..9cef677e7c
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/ImageTest.kt
@@ -0,0 +1,75 @@
+package com.mapbox.mapboxsdk.testapp.style
+
+import android.graphics.Bitmap
+import android.graphics.drawable.BitmapDrawable
+import android.support.test.runner.AndroidJUnit4
+import com.mapbox.mapboxsdk.testapp.R
+import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction
+import com.mapbox.mapboxsdk.testapp.activity.EspressoTest
+import org.junit.Assert.assertNull
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+import java.util.*
+
+/**
+ * CRUD tests around Image
+ */
+@RunWith(AndroidJUnit4::class)
+class ImageTest : EspressoTest() {
+
+ companion object {
+ private const val IMAGE_ID = "test.image"
+ }
+
+ @Test
+ fun testAddGetImage() {
+ validateTestSetup()
+ MapboxMapAction.invoke(mapboxMap) { uiController, mapboxMap ->
+ val drawable = rule.activity.resources.getDrawable(R.drawable.ic_launcher_round)
+ assertTrue(drawable is BitmapDrawable)
+
+ val bitmapSet = (drawable as BitmapDrawable).bitmap
+ mapboxMap.style!!.addImage(IMAGE_ID, bitmapSet)
+
+ // adding an image requires converting the image with an asynctask
+ uiController.loopMainThreadForAtLeast(200)
+
+ val bitmapGet = mapboxMap.style!!.getImage(IMAGE_ID)
+ assertTrue(bitmapGet!!.similarTo(bitmapSet))
+
+ mapboxMap.style!!.removeImage(IMAGE_ID)
+ assertNull(mapboxMap.style!!.getImage(IMAGE_ID))
+ }
+ }
+}
+
+/**
+ * Alternative implementation of Bitmap.sameAs #14060
+ */
+fun Bitmap.similarTo(other: Bitmap): Boolean {
+ if (invalidConfig(other)) {
+ return false
+ }
+
+ // Allocate arrays
+ val argb = IntArray(width * height)
+ val argbOther = IntArray(other.width * other.height)
+ getPixels(argb, 0, width, 0, 0, width, height)
+ other.getPixels(argbOther, 0, width, 0, 0, width, height)
+
+ // Alpha channel special check
+ if (config == Bitmap.Config.ALPHA_8) {
+ // in this case we have to manually compare the alpha channel as the rest is garbage.
+ val length = width * height
+ for (i in 0 until length) {
+ if (argb[i] and -0x1000000 != argbOther[i] and -0x1000000) {
+ return false
+ }
+ }
+ return true
+ }
+ return Arrays.equals(argb, argbOther)
+}
+
+fun Bitmap.invalidConfig(other: Bitmap): Boolean = this.config != other.config || this.width != other.width || this.height != other.height \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTests.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTests.java
index ed39f36e32..a4a34e752e 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTests.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTests.java
@@ -2,12 +2,10 @@ package com.mapbox.mapboxsdk.testapp.style;
import android.graphics.Color;
import android.graphics.PointF;
-import android.support.test.espresso.Espresso;
import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
import android.support.test.runner.AndroidJUnit4;
import android.view.View;
-
import com.mapbox.mapboxsdk.style.layers.CannotAddLayerException;
import com.mapbox.mapboxsdk.style.layers.CircleLayer;
import com.mapbox.mapboxsdk.style.layers.FillLayer;
@@ -22,20 +20,16 @@ import com.mapbox.mapboxsdk.style.sources.Source;
import com.mapbox.mapboxsdk.style.sources.VectorSource;
import com.mapbox.mapboxsdk.testapp.R;
import com.mapbox.mapboxsdk.testapp.activity.EspressoTest;
-
import junit.framework.Assert;
-
import org.hamcrest.Matcher;
-import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
+import timber.log.Timber;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
-import timber.log.Timber;
-
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
@@ -366,11 +360,6 @@ public class RuntimeStyleTests extends EspressoTest {
}
}
- @After
- public void unregisterIntentServiceIdlingResource() {
- Espresso.unregisterIdlingResources(idlingResource);
- }
-
public abstract class BaseViewAction implements ViewAction {
@Override
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java
index 149064d684..ae2c6d98f6 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java
@@ -559,7 +559,7 @@ public class SymbolLayerTest extends BaseLayerTest {
assertNull(layer.getTextJustify().getValue());
// Set and Get
- String propertyValue = TEXT_JUSTIFY_LEFT;
+ String propertyValue = TEXT_JUSTIFY_AUTO;
layer.setProperties(textJustify(propertyValue));
assertEquals(layer.getTextJustify().getValue(), propertyValue);
}
@@ -579,6 +579,32 @@ public class SymbolLayerTest extends BaseLayerTest {
@Test
@UiThreadTest
+ public void testTextRadialOffsetAsConstant() {
+ Timber.i("text-radial-offset");
+ assertNotNull(layer);
+ assertNull(layer.getTextRadialOffset().getValue());
+
+ // Set and Get
+ Float propertyValue = 0.3f;
+ layer.setProperties(textRadialOffset(propertyValue));
+ assertEquals(layer.getTextRadialOffset().getValue(), propertyValue);
+ }
+
+ @Test
+ @UiThreadTest
+ public void testTextVariableAnchorAsConstant() {
+ Timber.i("text-variable-anchor");
+ assertNotNull(layer);
+ assertNull(layer.getTextVariableAnchor().getValue());
+
+ // Set and Get
+ String[] propertyValue = new String[0];
+ layer.setProperties(textVariableAnchor(propertyValue));
+ assertEquals(layer.getTextVariableAnchor().getValue(), propertyValue);
+ }
+
+ @Test
+ @UiThreadTest
public void testTextAnchorAsConstant() {
Timber.i("text-anchor");
assertNotNull(layer);
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/FinishLoadingStyleIdlingResource.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/FinishLoadingStyleIdlingResource.java
deleted file mode 100644
index 323d2c0f15..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/FinishLoadingStyleIdlingResource.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.mapbox.mapboxsdk.testapp.utils;
-
-import android.app.Activity;
-import android.os.Handler;
-import android.os.Looper;
-import android.support.annotation.WorkerThread;
-import com.mapbox.mapboxsdk.maps.MapboxMap;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-public class FinishLoadingStyleIdlingResource extends MapboxIdlingResource {
-
- @WorkerThread
- public FinishLoadingStyleIdlingResource(final Activity activity) {
- new Handler(Looper.getMainLooper()).post(() -> inflateMap(activity));
- }
-
- @Override
- public void initMap(MapboxMap mapboxMap) {
- super.initMap(mapboxMap);
- mapboxMap.getStyle(style -> {
- assertNotNull(style);
- assertTrue(style.isFullyLoaded());
- if (resourceCallback != null) {
- resourceCallback.onTransitionToIdle();
- }
- });
- }
-
- @Override
- public boolean isIdleNow() {
- return getMapboxMap() != null && getMapboxMap().getStyle() != null;
- }
-} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/LoadStyleIdlingResource.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/LoadStyleIdlingResource.java
deleted file mode 100644
index 5dead21fbb..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/LoadStyleIdlingResource.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.mapbox.mapboxsdk.testapp.utils;
-
-import android.app.Activity;
-import android.os.Handler;
-import android.os.Looper;
-import android.support.annotation.UiThread;
-import android.support.annotation.WorkerThread;
-import com.mapbox.mapboxsdk.maps.MapboxMap;
-import com.mapbox.mapboxsdk.maps.Style;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-public class LoadStyleIdlingResource extends MapboxIdlingResource {
-
- private Style style;
-
- @WorkerThread
- public LoadStyleIdlingResource(final Activity activity) {
- new Handler(Looper.getMainLooper()).post(() -> inflateMap(activity));
- }
-
- @UiThread
- public void initMap(MapboxMap mapboxMap) {
- super.initMap(mapboxMap);
- mapboxMap.setStyle("asset://streets.json", style -> {
- assertNotNull(style);
- assertTrue(style.isFullyLoaded());
- this.style = style;
- if (resourceCallback != null) {
- resourceCallback.onTransitionToIdle();
- }
- });
- }
-
- @Override
- public boolean isIdleNow() {
- return style != null;
- }
-} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/MapboxIdlingResource.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/MapboxIdlingResource.java
deleted file mode 100644
index a05221d618..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/MapboxIdlingResource.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.mapbox.mapboxsdk.testapp.utils;
-
-import android.app.Activity;
-import android.support.annotation.UiThread;
-import android.support.test.espresso.IdlingResource;
-import com.mapbox.mapboxsdk.maps.MapView;
-import com.mapbox.mapboxsdk.maps.MapboxMap;
-import com.mapbox.mapboxsdk.testapp.R;
-
-public abstract class MapboxIdlingResource implements IdlingResource {
-
- private MapView mapView;
- private MapboxMap mapboxMap;
- IdlingResource.ResourceCallback resourceCallback;
-
- @UiThread
- void inflateMap(Activity activity) {
- mapView = activity.findViewById(R.id.mapView);
- if (mapView != null) {
- mapView.getMapAsync(this::initMap);
- }
- }
-
- @UiThread
- protected void initMap(MapboxMap mapboxMap) {
- this.mapboxMap = mapboxMap;
- }
-
- @Override
- public String getName() {
- return getClass().getSimpleName();
- }
-
- @Override
- public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
- this.resourceCallback = resourceCallback;
- }
-
- public MapboxMap getMapboxMap() {
- return mapboxMap;
- }
-
- public MapView getMapView() {
- return mapView;
- }
-} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/OnMapReadyIdlingResource.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/OnMapReadyIdlingResource.java
deleted file mode 100644
index 7696447289..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/OnMapReadyIdlingResource.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.mapbox.mapboxsdk.testapp.utils;
-
-import android.app.Activity;
-import android.os.Handler;
-import android.os.Looper;
-import android.support.annotation.WorkerThread;
-import android.support.test.espresso.IdlingResource;
-
-import com.mapbox.mapboxsdk.maps.MapView;
-import com.mapbox.mapboxsdk.maps.MapboxMap;
-import com.mapbox.mapboxsdk.maps.Style;
-import com.mapbox.mapboxsdk.testapp.R;
-
-public class OnMapReadyIdlingResource implements IdlingResource {
-
- private boolean styleLoaded;
- private MapboxMap mapboxMap;
- private IdlingResource.ResourceCallback resourceCallback;
-
- @WorkerThread
- public OnMapReadyIdlingResource(final Activity activity) {
- Handler handler = new Handler(Looper.getMainLooper());
- handler.post(() -> {
- MapView mapView = activity.findViewById(R.id.mapView);
- if (mapView != null) {
- mapView.addOnDidFinishLoadingStyleListener(() -> {
- styleLoaded = true;
- if (resourceCallback != null) {
- resourceCallback.onTransitionToIdle();
- }
- });
- mapView.getMapAsync(this::initMap);
- }
- });
- }
-
- private void initMap(MapboxMap mapboxMap) {
- this.mapboxMap = mapboxMap;
- mapboxMap.setStyle(new Style.Builder().fromUrl("asset://streets.json"));
- }
-
- @Override
- public String getName() {
- return getClass().getSimpleName();
- }
-
- @Override
- public boolean isIdleNow() {
- return styleLoaded;
- }
-
- @Override
- public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
- this.resourceCallback = resourceCallback;
- }
-
- public MapboxMap getMapboxMap() {
- return mapboxMap;
- }
-} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
index 2fa26f822a..017fe3ddca 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
@@ -173,10 +173,11 @@
<activity
android:name=".activity.fragment.FragmentBackStackActivity"
android:description="@string/description_map_fragment_backstack"
- android:label="@string/activity_map_fragment_backstack">
+ android:label="@string/activity_map_fragment_backstack"
+ android:launchMode="singleInstance">
<meta-data
android:name="@string/category"
- android:value="@string/category_fragment" />
+ android:value="@string/category_integration" />
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activity.FeatureOverviewActivity" />
@@ -399,7 +400,7 @@
android:label="@string/activity_viewpager">
<meta-data
android:name="@string/category"
- android:value="@string/category_fragment" />
+ android:value="@string/category_integration" />
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activity.FeatureOverviewActivity" />
@@ -407,7 +408,8 @@
<activity
android:name=".activity.maplayout.SimpleMapActivity"
android:description="@string/description_simple_map"
- android:label="@string/activity_simple_map">
+ android:label="@string/activity_simple_map"
+ android:launchMode="singleInstance">
<meta-data
android:name="@string/category"
android:value="@string/category_basic" />
@@ -720,7 +722,8 @@
<activity
android:name=".activity.textureview.TextureViewDebugModeActivity"
android:description="@string/description_textureview_debug"
- android:label="@string/activity_textureview_debug">
+ android:label="@string/activity_textureview_debug"
+ android:launchMode="singleInstance">
<meta-data
android:name="@string/category"
android:value="@string/category_basic" />
@@ -895,27 +898,49 @@
android:value=".activity.FeatureOverviewActivity" />
</activity>
<activity
- android:name=".activity.maplayout.RecyclerViewActivity"
- android:description="@string/description_recyclerview"
- android:label="@string/activity_recyclerview">
+ android:name=".activity.maplayout.TextureRecyclerViewActivity"
+ android:description="@string/description_recyclerview_textureview"
+ android:label="@string/activity_recyclerview_textureview">
<meta-data
android:name="@string/category"
- android:value="@string/category_maplayout" />
+ android:value="@string/category_integration" />
+ <meta-data
+ android:name="android.support.PARENT_ACTIVITY"
+ android:value=".activity.FeatureOverviewActivity" />
+ </activity>
+ <activity
+ android:name=".activity.maplayout.GLSurfaceRecyclerViewActivity"
+ android:description="@string/description_recyclerview_glsurfaceview"
+ android:label="@string/activity_recyclerview_glsurfaceview">
+ <meta-data
+ android:name="@string/category"
+ android:value="@string/category_integration" />
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activity.FeatureOverviewActivity" />
</activity>
<activity
android:name=".activity.fragment.NestedViewPagerActivity"
- android:description="@string/description_recyclerview"
+ android:description="@string/description_nested_viewpager"
android:label="@string/activity_nested_viewpager">
<meta-data
android:name="@string/category"
- android:value="@string/category_fragment" />
+ android:value="@string/category_integration" />
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activity.FeatureOverviewActivity" />
</activity>
+ <activity
+ android:name=".activity.telemetry.PerformanceMeasurementActivity"
+ android:description="@string/description_performance_measurement"
+ android:label="@string/activity_performance_measurement">
+ <meta-data
+ android:name="@string/category"
+ android:value="@string/category_telemetry" />
+ <meta-data
+ android:name="android.support.PARENT_ACTIVITY"
+ android:value=".activity.FeatureOverviewActivity" />
+ </activity>
<!-- For Instrumentation tests -->
<activity
android:name=".activity.style.RuntimeStyleTimingTestActivity"
@@ -924,6 +949,9 @@
android:name=".activity.espresso.EspressoTestActivity"
android:screenOrientation="portrait" />
<activity
+ android:name=".activity.espresso.PixelTestActivity"
+ android:screenOrientation="portrait" />
+ <activity
android:name=".activity.espresso.DeviceIndependentTestActivity"
android:screenOrientation="portrait" />
<activity
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxApplication.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxApplication.java
index 9ade97f91e..d5cff301db 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxApplication.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxApplication.java
@@ -40,7 +40,7 @@ public class MapboxApplication extends Application {
initializeMapbox();
}
- private boolean initializeLeakCanary() {
+ protected boolean initializeLeakCanary() {
if (LeakCanary.isInAnalyzerProcess(this)) {
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/GestureDetectorActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/GestureDetectorActivity.java
index f4639b0f1a..ed5364655e 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/GestureDetectorActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/GestureDetectorActivity.java
@@ -267,7 +267,18 @@ public class GestureDetectorActivity extends AppCompatActivity {
if (enabled) {
focalPointLatLng = new LatLng(51.50325, -0.12968);
marker = mapboxMap.addMarker(new MarkerOptions().position(focalPointLatLng));
- mapboxMap.easeCamera(CameraUpdateFactory.newLatLngZoom(focalPointLatLng, 16));
+ mapboxMap.easeCamera(CameraUpdateFactory.newLatLngZoom(focalPointLatLng, 16),
+ new MapboxMap.CancelableCallback() {
+ @Override
+ public void onCancel() {
+ recalculateFocalPoint();
+ }
+
+ @Override
+ public void onFinish() {
+ recalculateFocalPoint();
+ }
+ });
} else {
if (marker != null) {
mapboxMap.removeMarker(marker);
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/espresso/PixelTestActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/espresso/PixelTestActivity.kt
new file mode 100644
index 0000000000..b69d1ee5ed
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/espresso/PixelTestActivity.kt
@@ -0,0 +1,66 @@
+package com.mapbox.mapboxsdk.testapp.activity.espresso
+
+import android.os.Bundle
+import android.support.v7.app.AppCompatActivity
+import com.mapbox.mapboxsdk.maps.MapView
+import com.mapbox.mapboxsdk.maps.MapboxMap
+import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
+import com.mapbox.mapboxsdk.maps.Style
+import com.mapbox.mapboxsdk.testapp.R
+
+/**
+ * Test activity used for instrumentation tests that require a specific device size.
+ */
+class PixelTestActivity : AppCompatActivity(), OnMapReadyCallback {
+
+ lateinit var mapView: MapView
+ lateinit var mapboxMap: MapboxMap
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_pixel_test)
+ mapView = findViewById(R.id.mapView)
+ mapView.onCreate(savedInstanceState)
+ mapView.getMapAsync(this)
+ }
+
+ override fun onMapReady(map: MapboxMap) {
+ mapboxMap = map
+ mapboxMap.setStyle(Style.MAPBOX_STREETS)
+ }
+
+ public override fun onResume() {
+ super.onResume()
+ mapView.onResume()
+ }
+
+ override fun onStart() {
+ super.onStart()
+ mapView.onStart()
+ }
+
+ public override fun onPause() {
+ super.onPause()
+ mapView.onPause()
+ }
+
+ override fun onStop() {
+ super.onStop()
+ mapView.onStop()
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ mapView.onSaveInstanceState(outState)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ mapView.onDestroy()
+ }
+
+ override fun onLowMemory() {
+ super.onLowMemory()
+ mapView.onLowMemory()
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java
index 472b9b7d57..c7f530b123 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java
@@ -3,16 +3,15 @@ package com.mapbox.mapboxsdk.testapp.activity.fragment;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
-
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
-import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapFragment;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
+import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.mapboxsdk.testapp.R;
/**
@@ -24,6 +23,7 @@ import com.mapbox.mapboxsdk.testapp.R;
public class MapFragmentActivity extends AppCompatActivity implements MapFragment.OnMapViewReadyCallback,
OnMapReadyCallback, MapView.OnDidFinishRenderingFrameListener {
+ private static final String TAG = "com.mapbox.map";
private MapboxMap mapboxMap;
private MapView mapView;
private boolean initialCameraAnimation = true;
@@ -32,14 +32,18 @@ public class MapFragmentActivity extends AppCompatActivity implements MapFragmen
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map_fragment);
+
+ MapFragment mapFragment;
if (savedInstanceState == null) {
- MapFragment mapFragment = MapFragment.newInstance(createFragmentOptions());
+ mapFragment = MapFragment.newInstance(createFragmentOptions());
getFragmentManager()
.beginTransaction()
- .add(R.id.fragment_container, mapFragment, "com.mapbox.map")
+ .add(R.id.fragment_container, mapFragment, TAG)
.commit();
- mapFragment.getMapAsync(this);
+ } else {
+ mapFragment = (MapFragment) getFragmentManager().findFragmentByTag(TAG);
}
+ mapFragment.getMapAsync(this);
}
private MapboxMapOptions createFragmentOptions() {
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/SupportMapFragmentActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/SupportMapFragmentActivity.java
index 4baf40d51b..7fd84bcd25 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/SupportMapFragmentActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/SupportMapFragmentActivity.java
@@ -3,16 +3,15 @@ package com.mapbox.mapboxsdk.testapp.activity.fragment;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
-
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
-import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapFragment;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
+import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.mapboxsdk.maps.SupportMapFragment;
import com.mapbox.mapboxsdk.testapp.R;
@@ -25,6 +24,7 @@ import com.mapbox.mapboxsdk.testapp.R;
public class SupportMapFragmentActivity extends AppCompatActivity implements MapFragment.OnMapViewReadyCallback,
OnMapReadyCallback, MapView.OnDidFinishRenderingFrameListener {
+ private static final String TAG = "com.mapbox.map";
private MapboxMap mapboxMap;
private MapView mapView;
private boolean initialCameraAnimation = true;
@@ -33,14 +33,18 @@ public class SupportMapFragmentActivity extends AppCompatActivity implements Map
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map_fragment);
+ SupportMapFragment mapFragment;
if (savedInstanceState == null) {
- SupportMapFragment mapFragment = SupportMapFragment.newInstance(createFragmentOptions());
+ mapFragment = SupportMapFragment.newInstance(createFragmentOptions());
getSupportFragmentManager()
.beginTransaction()
- .add(R.id.fragment_container, mapFragment, "com.mapbox.map")
+ .add(R.id.fragment_container, mapFragment, TAG)
.commit();
- mapFragment.getMapAsync(this);
+ } else {
+ mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentByTag(TAG);
}
+ mapFragment.getMapAsync(this);
+
}
private MapboxMapOptions createFragmentOptions() {
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/ViewPagerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/ViewPagerActivity.java
deleted file mode 100644
index c494842b14..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/ViewPagerActivity.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package com.mapbox.mapboxsdk.testapp.activity.fragment;
-
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentStatePagerAdapter;
-import android.support.v4.view.ViewPager;
-import android.support.v7.app.AppCompatActivity;
-
-import com.mapbox.mapboxsdk.camera.CameraPosition;
-import com.mapbox.mapboxsdk.geometry.LatLng;
-import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
-import com.mapbox.mapboxsdk.maps.Style;
-import com.mapbox.mapboxsdk.maps.SupportMapFragment;
-import com.mapbox.mapboxsdk.testapp.R;
-
-/**
- * Test activity showcasing using the Android SDK ViewPager API to show MapFragments.
- */
-public class ViewPagerActivity extends AppCompatActivity {
-
- private ViewPager viewPager;
- private MapFragmentAdapter adapter;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_viewpager);
-
- viewPager = (ViewPager) findViewById(R.id.viewpager);
- if (viewPager != null) {
- adapter = new MapFragmentAdapter(getSupportFragmentManager());
- viewPager.setAdapter(adapter);
- }
- }
-
- @Override
- protected void onRestoreInstanceState(Bundle savedInstanceState) {
- super.onRestoreInstanceState(savedInstanceState);
-
- int currentPosition = viewPager.getCurrentItem();
- SupportMapFragment mapFragment;
-
- if (Math.abs(0 - currentPosition) <= 1) {
- mapFragment = (SupportMapFragment) adapter.instantiateItem(viewPager, 0);
- mapFragment.getMapAsync(mapboxMap -> {
- mapboxMap.setStyle(Style.MAPBOX_STREETS);
- });
- }
-
- if (Math.abs(1 - currentPosition) <= 1) {
- mapFragment = (SupportMapFragment) adapter.instantiateItem(viewPager, 1);
- mapFragment.getMapAsync(mapboxMap -> {
- mapboxMap.setStyle(Style.DARK);
- });
- }
-
- if (Math.abs(2 - currentPosition) <= 1) {
- mapFragment = (SupportMapFragment) adapter.instantiateItem(viewPager, 2);
- mapFragment.getMapAsync(mapboxMap -> {
- mapboxMap.setStyle(Style.SATELLITE);
- });
- }
- }
-
- static class MapFragmentAdapter extends FragmentStatePagerAdapter {
-
- private static int NUM_ITEMS = 3;
-
- MapFragmentAdapter(FragmentManager fragmentManager) {
- super(fragmentManager);
- }
-
- @Override
- public int getCount() {
- return NUM_ITEMS;
- }
-
- @Override
- public Fragment getItem(int position) {
- SupportMapFragment fragment = null;
- MapboxMapOptions options = new MapboxMapOptions();
- options.textureMode(true);
-
- switch (position) {
- case 0:
- options.camera(new CameraPosition.Builder().target(new LatLng(34.920526, 102.634774)).zoom(3).build());
- fragment = SupportMapFragment.newInstance(options);
- fragment.getMapAsync(mapboxMap -> {
- mapboxMap.setStyle(Style.MAPBOX_STREETS);
- });
- break;
- case 1:
- options.camera(new CameraPosition.Builder().target(new LatLng(62.326440, 92.764913)).zoom(3).build());
- fragment = SupportMapFragment.newInstance(options);
- fragment.getMapAsync(mapboxMap -> {
- mapboxMap.setStyle(Style.DARK);
- });
- break;
- case 2:
- options.camera(new CameraPosition.Builder().target(new LatLng(-25.007786, 133.623852)).zoom(3).build());
- fragment = SupportMapFragment.newInstance(options);
- fragment.getMapAsync(mapboxMap -> {
- mapboxMap.setStyle(Style.SATELLITE);
- });
- break;
- }
- return fragment;
- }
-
- @Override
- public CharSequence getPageTitle(int position) {
- return "Page " + position;
- }
- }
-}
-
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/ViewPagerActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/ViewPagerActivity.kt
new file mode 100644
index 0000000000..77e2e1370d
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/ViewPagerActivity.kt
@@ -0,0 +1,109 @@
+package com.mapbox.mapboxsdk.testapp.activity.fragment
+
+import android.os.Bundle
+import android.support.v4.app.Fragment
+import android.support.v4.app.FragmentManager
+import android.support.v4.app.FragmentStatePagerAdapter
+import android.support.v7.app.AppCompatActivity
+import com.mapbox.mapboxsdk.camera.CameraPosition
+import com.mapbox.mapboxsdk.geometry.LatLng
+import com.mapbox.mapboxsdk.maps.MapboxMapOptions
+import com.mapbox.mapboxsdk.maps.Style
+import com.mapbox.mapboxsdk.maps.SupportMapFragment
+import com.mapbox.mapboxsdk.testapp.R
+import kotlinx.android.synthetic.main.activity_viewpager.*
+
+/**
+ * Test activity showcasing using the Android SDK ViewPager API to show MapFragments.
+ */
+class ViewPagerActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_viewpager)
+ viewPager.adapter = MapFragmentAdapter(supportFragmentManager)
+ }
+
+ override fun onRestoreInstanceState(savedInstanceState: Bundle) {
+ super.onRestoreInstanceState(savedInstanceState)
+
+ val currentPosition = viewPager.currentItem
+ var mapFragment: SupportMapFragment
+
+ if (Math.abs(0 - currentPosition) <= 1) {
+ mapFragment = viewPager.adapter?.instantiateItem(viewPager, 0) as SupportMapFragment
+ mapFragment.getMapAsync { mapboxMap -> mapboxMap.setStyle(Style.MAPBOX_STREETS) }
+ }
+
+ if (Math.abs(1 - currentPosition) <= 1) {
+ mapFragment = viewPager.adapter?.instantiateItem(viewPager, 1) as SupportMapFragment
+ mapFragment.getMapAsync { mapboxMap -> mapboxMap.setStyle(Style.DARK) }
+ }
+
+ if (Math.abs(2 - currentPosition) <= 1) {
+ mapFragment = viewPager.adapter?.instantiateItem(viewPager, 2) as SupportMapFragment
+ mapFragment.getMapAsync { mapboxMap -> mapboxMap.setStyle(Style.SATELLITE) }
+ }
+
+ if (Math.abs(3 - currentPosition) <= 1) {
+ mapFragment = viewPager.adapter?.instantiateItem(viewPager, 3) as SupportMapFragment
+ mapFragment.getMapAsync { mapboxMap -> mapboxMap.setStyle(Style.SATELLITE) }
+ }
+
+ if (Math.abs(4 - currentPosition) <= 1) {
+ mapFragment = viewPager.adapter?.instantiateItem(viewPager, 4) as SupportMapFragment
+ mapFragment.getMapAsync { mapboxMap -> mapboxMap.setStyle(Style.SATELLITE) }
+ }
+ }
+
+ internal class MapFragmentAdapter(fragmentManager: FragmentManager) : FragmentStatePagerAdapter(fragmentManager) {
+
+ override fun getCount(): Int {
+ return NUM_ITEMS
+ }
+
+ override fun getItem(position: Int): Fragment? {
+ var fragment: SupportMapFragment? = null
+ val options = MapboxMapOptions()
+ options.textureMode(true)
+
+ when (position) {
+ 0 -> {
+ options.camera(CameraPosition.Builder().target(LatLng(34.920526, 102.634774)).zoom(3.0).build())
+ fragment = SupportMapFragment.newInstance(options)
+ fragment.getMapAsync { mapboxMap -> mapboxMap.setStyle(Style.MAPBOX_STREETS) }
+ }
+ 1 -> {
+ options.camera(CameraPosition.Builder().target(LatLng(62.326440, 92.764913)).zoom(3.0).build())
+ fragment = SupportMapFragment.newInstance(options)
+ fragment.getMapAsync { mapboxMap -> mapboxMap.setStyle(Style.DARK) }
+ }
+ 2 -> {
+ options.camera(CameraPosition.Builder().target(LatLng(-25.007786, 133.623852)).zoom(3.0).build())
+ fragment = SupportMapFragment.newInstance(options)
+ fragment.getMapAsync { mapboxMap -> mapboxMap.setStyle(Style.SATELLITE) }
+ }
+ 3 -> {
+ options.camera(CameraPosition.Builder().target(LatLng(62.326440, 92.764913)).zoom(3.0).build())
+ fragment = SupportMapFragment.newInstance(options)
+ fragment.getMapAsync { mapboxMap -> mapboxMap.setStyle(Style.LIGHT) }
+ }
+ 4 -> {
+ options.camera(CameraPosition.Builder().target(LatLng(34.920526, 102.634774)).zoom(3.0).build())
+ fragment = SupportMapFragment.newInstance(options)
+ fragment.getMapAsync { mapboxMap -> mapboxMap.setStyle(Style.TRAFFIC_NIGHT) }
+ }
+ }
+ return fragment
+ }
+
+ override fun getPageTitle(position: Int): CharSequence? {
+ return "Page $position"
+ }
+
+ companion object {
+
+ private val NUM_ITEMS = 5
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/SnapshotActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/SnapshotActivity.java
deleted file mode 100644
index c1697ab960..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/SnapshotActivity.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package com.mapbox.mapboxsdk.testapp.activity.imagegenerator;
-
-import android.graphics.Bitmap;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.design.widget.FloatingActionButton;
-import android.support.v4.content.ContextCompat;
-import android.support.v7.app.AppCompatActivity;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.Toast;
-
-import com.mapbox.mapboxsdk.maps.Style;
-import com.mapbox.mapboxsdk.maps.MapView;
-import com.mapbox.mapboxsdk.maps.MapboxMap;
-import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
-import com.mapbox.mapboxsdk.testapp.R;
-
-import java.util.Locale;
-
-import timber.log.Timber;
-
-/**
- * Test activity showcasing the Snapshot API to create and display a bitmap of the current shown Map.
- */
-public class SnapshotActivity extends AppCompatActivity implements OnMapReadyCallback, View.OnClickListener {
-
- private MapView mapView;
- private MapboxMap mapboxMap;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_snapshot);
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(this);
- }
-
- @Override
- public void onMapReady(@NonNull MapboxMap map) {
- mapboxMap = map;
- mapboxMap.setStyle(new Style.Builder().fromUrl(Style.OUTDOORS));
- FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
- if (fab != null) {
- fab.setColorFilter(ContextCompat.getColor(SnapshotActivity.this, R.color.primary));
- fab.setOnClickListener(this);
- }
- }
-
- @Override
- public void onClick(View view) {
- final long startTime = System.nanoTime();
- mapboxMap.snapshot(snapshot -> {
- long endTime = System.nanoTime();
- long duration = (long) ((endTime - startTime) / 1e6);
- ImageView snapshotView = (ImageView) findViewById(R.id.imageView);
- snapshotView.setImageBitmap(snapshot);
- Toast.makeText(
- SnapshotActivity.this,
- String.format(Locale.getDefault(), "Snapshot taken in %d ms", duration),
- Toast.LENGTH_LONG).show();
- });
- }
-
- @Override
- protected void onStart() {
- super.onStart();
- mapView.onStart();
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- mapboxMap.snapshot(new MapboxMap.SnapshotReadyCallback() {
- @Override
- public void onSnapshotReady(Bitmap snapshot) {
- Timber.e("Regression test for https://github.com/mapbox/mapbox-gl-native/pull/11358");
- }
- });
- mapView.onPause();
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- mapView.onStop();
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/SnapshotActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/SnapshotActivity.kt
new file mode 100644
index 0000000000..51b1c08ba5
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/SnapshotActivity.kt
@@ -0,0 +1,80 @@
+package com.mapbox.mapboxsdk.testapp.activity.imagegenerator
+
+import android.os.Bundle
+import android.support.v7.app.AppCompatActivity
+import com.mapbox.mapboxsdk.maps.MapView
+import com.mapbox.mapboxsdk.maps.MapboxMap
+import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
+import com.mapbox.mapboxsdk.maps.Style
+import com.mapbox.mapboxsdk.testapp.R
+import kotlinx.android.synthetic.main.activity_snapshot.*
+import timber.log.Timber
+
+/**
+ * Test activity showcasing the Snapshot API to create and display a bitmap of the current shown Map.
+ */
+class SnapshotActivity : AppCompatActivity(), OnMapReadyCallback {
+
+ private lateinit var mapboxMap: MapboxMap
+
+ private val idleListener = object : MapView.OnDidBecomeIdleListener {
+ override fun onDidBecomeIdle() {
+ mapView.removeOnDidBecomeIdleListener(this)
+ mapboxMap.snapshot { snapshot ->
+ imageView.setImageBitmap(snapshot)
+ mapView.addOnDidBecomeIdleListener(this)
+ }
+ }
+ }
+
+ public override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_snapshot)
+ mapView.onCreate(savedInstanceState)
+ mapView.getMapAsync(this)
+ }
+
+ override fun onMapReady(map: MapboxMap) {
+ mapboxMap = map
+ mapboxMap.setStyle(Style.Builder().fromUrl(Style.OUTDOORS)) { mapView.addOnDidBecomeIdleListener(idleListener) }
+ }
+
+ override fun onStart() {
+ super.onStart()
+ mapView.onStart()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ mapView.onResume()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ mapboxMap.snapshot {
+ Timber.e("Regression test for https://github.com/mapbox/mapbox-gl-native/pull/11358")
+ }
+ mapView.onPause()
+ }
+
+ override fun onStop() {
+ super.onStop()
+ mapView.onStop()
+ }
+
+ public override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ mapView.onSaveInstanceState(outState)
+ }
+
+ override fun onLowMemory() {
+ super.onLowMemory()
+ mapView.onLowMemory()
+ }
+
+ public override fun onDestroy() {
+ super.onDestroy()
+ mapView.removeOnDidBecomeIdleListener(idleListener)
+ mapView.onDestroy()
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/GLSurfaceRecyclerViewActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/GLSurfaceRecyclerViewActivity.kt
new file mode 100644
index 0000000000..5acf356696
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/GLSurfaceRecyclerViewActivity.kt
@@ -0,0 +1,155 @@
+package com.mapbox.mapboxsdk.testapp.activity.maplayout
+
+import android.annotation.SuppressLint
+import android.os.Bundle
+import android.support.v7.app.AppCompatActivity
+import android.support.v7.widget.LinearLayoutManager
+import android.support.v7.widget.RecyclerView
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import android.widget.TextView
+import com.mapbox.mapboxsdk.maps.MapView
+import com.mapbox.mapboxsdk.maps.Style
+import com.mapbox.mapboxsdk.testapp.R
+import kotlinx.android.synthetic.main.activity_recyclerview.*
+
+/**
+ * TestActivity showcasing how to integrate a GLSurfaceView MapView in a RecyclerView.
+ * <p>
+ * It requires calling the correct lifecycle methods when detaching and attaching the View to
+ * the RecyclerView with onViewAttachedToWindow and onViewDetachedFromWindow.
+ * </p>
+ */
+@SuppressLint("ClickableViewAccessibility")
+open class GLSurfaceRecyclerViewActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_recyclerview)
+ recyclerView.layoutManager = LinearLayoutManager(this)
+ recyclerView.adapter = ItemAdapter(this, LayoutInflater.from(this), savedInstanceState)
+ }
+
+ override fun onSaveInstanceState(outState: Bundle?) {
+ super.onSaveInstanceState(outState)
+ // to save state, we need to call MapView#onSaveInstanceState
+ (recyclerView.adapter as ItemAdapter).onSaveInstanceState(outState)
+ }
+
+ override fun onLowMemory() {
+ super.onLowMemory()
+ // to release memory, we need to call MapView#onLowMemory
+ (recyclerView.adapter as ItemAdapter).onLowMemory()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ // to perform cleanup, we need to call MapView#onDestroy
+ (recyclerView.adapter as ItemAdapter).onDestroy()
+ }
+
+ open fun getMapItemLayoutId(): Int {
+ return R.layout.item_map_gl
+ }
+
+ class ItemAdapter(private val activity: GLSurfaceRecyclerViewActivity, private val inflater: LayoutInflater, val savedInstanceState: Bundle?) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
+
+ private val items = listOf(
+ "one", "two", "three", MapItem(), "four", "five", "six", "seven", "eight", "nine", "ten",
+ "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
+ "nineteen", "twenty", "twenty-one"
+ )
+
+ private var mapHolder: MapHolder? = null
+
+ companion object {
+ const val TYPE_MAP = 0
+ const val TYPE_TEXT = 1
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ return if (viewType == TYPE_MAP) {
+ val mapView = inflater.inflate(activity.getMapItemLayoutId(), parent, false) as MapView
+ mapView.getMapAsync { mapboxMap -> mapboxMap.setStyle(Style.MAPBOX_STREETS) }
+ mapHolder = MapHolder(mapView, savedInstanceState)
+ return mapHolder as MapHolder
+ } else {
+ TextHolder(inflater.inflate(android.R.layout.simple_list_item_1, parent, false) as TextView)
+ }
+ }
+
+ override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
+ super.onViewAttachedToWindow(holder)
+ if (holder is MapHolder) {
+ val mapView = holder.mapView
+ mapView.onStart()
+ mapView.onResume()
+ }
+ }
+
+ override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {
+ super.onViewDetachedFromWindow(holder)
+ if (holder is MapHolder) {
+ val mapView = holder.mapView
+ mapView.onPause()
+ mapView.onStop()
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return items.count()
+ }
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ if (holder.itemViewType == TYPE_TEXT) {
+ val textHolder = holder as TextHolder
+ textHolder.bind(items[position] as String)
+ }
+ }
+
+ override fun getItemViewType(position: Int): Int {
+ return if (items[position] is MapItem) {
+ TYPE_MAP
+ } else {
+ TYPE_TEXT
+ }
+ }
+
+ fun onSaveInstanceState(savedInstanceState: Bundle?) {
+ savedInstanceState?.let {
+ mapHolder?.mapView?.onSaveInstanceState(it)
+ }
+ }
+
+ fun onLowMemory() {
+ mapHolder?.mapView?.onLowMemory()
+ }
+
+ fun onDestroy() {
+ mapHolder?.mapView?.let {
+ it.onPause()
+ it.onStop()
+ it.onDestroy()
+ }
+ }
+
+ class MapItem
+ class MapHolder(val mapView: MapView, bundle: Bundle?) : RecyclerView.ViewHolder(mapView) {
+ init {
+ mapView.onCreate(bundle)
+ mapView.setOnTouchListener { view, motionEvent ->
+ // Disallow the touch request for recyclerView scroll
+ view.parent.requestDisallowInterceptTouchEvent(true)
+ mapView.onTouchEvent(motionEvent)
+ true
+ }
+ }
+ }
+
+ class TextHolder(val textView: TextView) : RecyclerView.ViewHolder(textView) {
+ fun bind(item: String) {
+ textView.text = item
+ }
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapInDialogActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapInDialogActivity.java
index c9a9377885..18092ce372 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapInDialogActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapInDialogActivity.java
@@ -1,6 +1,5 @@
package com.mapbox.mapboxsdk.testapp.activity.maplayout;
-import android.app.Dialog;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@@ -17,9 +16,6 @@ import com.mapbox.mapboxsdk.testapp.R;
/**
* Test activity showcasing showing a Map inside of a DialogFragment.
- * <p>
- * Uses the deprecated TextureView API to workaround the issue of seeing a grey background before the gl surface.
- * </p>
*/
public class MapInDialogActivity extends AppCompatActivity {
@@ -64,23 +60,6 @@ public class MapInDialogActivity extends AppCompatActivity {
mapView.getMapAsync(mapboxMap -> mapboxMap.setStyle(Style.OUTDOORS));
}
- @NonNull
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- return new Dialog(getActivity(), getTheme()) {
- @Override
- public void dismiss() {
- if (mapView != null && !mapView.isDestroyed()) {
- mapView.onPause();
- mapView.onStop();
- mapView.onDestroy();
- mapView = null;
- }
- super.dismiss();
- }
- };
- }
-
@Override
public void onStart() {
super.onStart();
@@ -96,25 +75,20 @@ public class MapInDialogActivity extends AppCompatActivity {
@Override
public void onPause() {
super.onPause();
- if (mapView != null) {
- mapView.onPause();
- }
+ mapView.onPause();
}
@Override
public void onStop() {
super.onStop();
- if (mapView != null) {
- mapView.onStop();
- }
+ mapView.onStop();
}
@Override
public void onDestroyView() {
super.onDestroyView();
- if (mapView != null) {
- mapView.onDestroy();
- }
+ mapView.onDestroy();
+ mapView = null;
}
@Override
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/RecyclerViewActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/RecyclerViewActivity.kt
deleted file mode 100644
index 9989d1b137..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/RecyclerViewActivity.kt
+++ /dev/null
@@ -1,151 +0,0 @@
-package com.mapbox.mapboxsdk.testapp.activity.maplayout
-
-import android.annotation.SuppressLint
-import android.os.Bundle
-import android.support.v7.app.AppCompatActivity
-import android.support.v7.widget.LinearLayoutManager
-import android.support.v7.widget.RecyclerView
-import android.view.LayoutInflater
-import android.view.ViewGroup
-import android.widget.TextView
-import com.mapbox.mapboxsdk.maps.MapView
-import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
-import com.mapbox.mapboxsdk.maps.Style
-import com.mapbox.mapboxsdk.testapp.R
-import kotlinx.android.synthetic.main.activity_recyclerview.*
-
-/**
- * TestActivity showcasing how to integrate a MapView in a RecyclerView.
- * <p>
- * It requires calling the correct lifecycle methods when detaching and attaching the View to
- * the RecyclerView with onViewAttachedToWindow and onViewDetachedFromWindow.
- * </p>
- */
-@SuppressLint("ClickableViewAccessibility")
-class RecyclerViewActivity : AppCompatActivity() {
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_recyclerview)
- recyclerView.layoutManager = LinearLayoutManager(this)
- recyclerView.adapter = ItemAdapter(LayoutInflater.from(this), savedInstanceState)
- }
-
- override fun onSaveInstanceState(outState: Bundle?) {
- super.onSaveInstanceState(outState)
- // to save state, we need to call MapView#onSaveInstanceState
- (recyclerView.adapter as ItemAdapter).onSaveInstanceState(outState)
- }
-
- override fun onLowMemory() {
- super.onLowMemory()
- // to release memory, we need to call MapView#onLowMemory
- (recyclerView.adapter as ItemAdapter).onLowMemory()
- }
-
- override fun onDestroy() {
- super.onDestroy()
- // to perform cleanup, we need to call MapView#onDestroy
- (recyclerView.adapter as ItemAdapter).onDestroy()
- }
-
- class ItemAdapter(private val inflater: LayoutInflater, val savedInstanceState: Bundle?) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
-
- private val items = listOf(
- "one", "two", "three", MapItem(), "four", "five", "six", "seven", "eight", "nine", "ten",
- "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
- "nineteen", "twenty", "twenty-one"
- )
-
- private var mapHolder: MapHolder? = null
-
- companion object {
- const val TYPE_MAP = 0
- const val TYPE_TEXT = 1
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
- return if (viewType == TYPE_MAP) {
- val mapView = inflater.inflate(R.layout.item_map, parent, false) as MapView
- mapView.getMapAsync { mapboxMap -> mapboxMap.setStyle(Style.MAPBOX_STREETS) }
- mapHolder = MapHolder(mapView, savedInstanceState)
- return mapHolder as MapHolder
- } else {
- TextHolder(inflater.inflate(android.R.layout.simple_list_item_1, parent, false) as TextView)
- }
- }
-
- override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
- super.onViewAttachedToWindow(holder)
- if (holder is MapHolder) {
- val mapView = holder.mapView
- mapView.onStart()
- mapView.onResume()
- }
- }
-
- override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {
- super.onViewDetachedFromWindow(holder)
- if (holder is MapHolder) {
- val mapView = holder.mapView
- mapView.onPause()
- mapView.onStop()
- }
- }
-
- override fun getItemCount(): Int {
- return items.count()
- }
-
- override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
- if (holder.itemViewType == TYPE_TEXT) {
- val textHolder = holder as TextHolder
- textHolder.bind(items[position] as String)
- }
- }
-
- override fun getItemViewType(position: Int): Int {
- return if (items[position] is MapItem) {
- TYPE_MAP
- } else {
- TYPE_TEXT
- }
- }
-
- fun onSaveInstanceState(savedInstanceState: Bundle?){
- savedInstanceState?.let {
- mapHolder?.mapView?.onSaveInstanceState(it)
- }
- }
-
- fun onLowMemory() {
- mapHolder?.mapView?.onLowMemory()
- }
-
- fun onDestroy() {
- mapHolder?.mapView?.let {
- it.onPause()
- it.onStop()
- it.onDestroy()
- }
- }
-
- class MapItem
- class MapHolder(val mapView: MapView, bundle: Bundle?) : RecyclerView.ViewHolder(mapView) {
- init {
- mapView.onCreate(bundle)
- mapView.setOnTouchListener { view, motionEvent ->
- // Disallow the touch request for recyclerView scroll
- view.parent.requestDisallowInterceptTouchEvent(true)
- mapView.onTouchEvent(motionEvent)
- true
- }
- }
- }
- class TextHolder(val textView: TextView) : RecyclerView.ViewHolder(textView) {
- fun bind(item: String) {
- textView.text = item
- }
- }
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/TextureRecyclerViewActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/TextureRecyclerViewActivity.kt
new file mode 100644
index 0000000000..895389bc1e
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/TextureRecyclerViewActivity.kt
@@ -0,0 +1,15 @@
+package com.mapbox.mapboxsdk.testapp.activity.maplayout
+
+import android.annotation.SuppressLint
+import com.mapbox.mapboxsdk.testapp.R
+
+/**
+ * TestActivity showcasing how to integrate a TexureView MapView in a RecyclerView.
+ */
+@SuppressLint("ClickableViewAccessibility")
+class TextureRecyclerViewActivity : GLSurfaceRecyclerViewActivity() {
+
+ override fun getMapItemLayoutId() : Int{
+ return R.layout.item_map_texture
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/telemetry/PerformanceMeasurementActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/telemetry/PerformanceMeasurementActivity.java
new file mode 100644
index 0000000000..285d7bc6c8
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/telemetry/PerformanceMeasurementActivity.java
@@ -0,0 +1,187 @@
+package com.mapbox.mapboxsdk.testapp.activity.telemetry;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.WindowManager;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.mapbox.mapboxsdk.Mapbox;
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.Style;
+import com.mapbox.mapboxsdk.module.http.HttpRequestUtil;
+import com.mapbox.mapboxsdk.testapp.R;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import okhttp3.Call;
+import okhttp3.EventListener;
+import okhttp3.OkHttpClient;
+import timber.log.Timber;
+
+/**
+ * Test activity showcasing gathering performance measurement data.
+ */
+public class PerformanceMeasurementActivity extends AppCompatActivity {
+
+ private MapView mapView;
+
+ private Map<String, Long> startTimes = new HashMap<>();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_map_simple);
+ mapView = findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+
+
+ OkHttpClient.Builder builder = new OkHttpClient.Builder();
+ builder.eventListener(new EventListener() {
+
+ @Override
+ public void callStart(Call call) {
+ String url = call.request().url().toString();
+ startTimes.put(url, System.nanoTime());
+ super.callStart(call);
+ Timber.e("callStart: %s", url);
+ }
+
+ @Override
+ public void callEnd(Call call) {
+ String url = call.request().url().toString();
+ Timber.e("callEnd: %s", url);
+ Long start = startTimes.get(url);
+ if (start != null) {
+ long elapsed = System.nanoTime() - start;
+ triggerPerformanceEvent(url.substring(0, url.indexOf('?')), elapsed);
+ startTimes.remove(start);
+ Timber.e("callEnd: %s took %d", url, elapsed);
+ }
+ super.callEnd(call);
+ }
+ });
+ HttpRequestUtil.setOkHttpClient(builder.build());
+
+ mapView.getMapAsync(mapboxMap -> mapboxMap.setStyle(
+ new Style.Builder().fromUrl(Style.MAPBOX_STREETS)));
+ }
+
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ protected void onDestroy() {
+
+ startTimes.clear();
+
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ private void triggerPerformanceEvent(String style, long elapsed) {
+
+ List<Attribute<String>> attributes = new ArrayList<>();
+ attributes.add(
+ new Attribute<>("style_id", style));
+ attributes.add(
+ new Attribute<>("test_perf_event", "true"));
+
+ List<Attribute<Long>> counters = new ArrayList();
+ counters.add(new Attribute<>("elapsed", elapsed));
+
+
+ JsonObject metaData = new JsonObject();
+ metaData.addProperty("os", "android");
+ metaData.addProperty("manufacturer", Build.MANUFACTURER);
+ metaData.addProperty("brand", Build.BRAND);
+ metaData.addProperty("device", Build.MODEL);
+ metaData.addProperty("version", Build.VERSION.RELEASE);
+ metaData.addProperty("abi", Build.CPU_ABI);
+ metaData.addProperty("country", Locale.getDefault().getISO3Country());
+ metaData.addProperty("ram", getRam());
+ metaData.addProperty("screenSize", getWindowSize());
+
+ Gson gson = new Gson();
+
+ Bundle bundle = new Bundle();
+ bundle.putString("attributes", gson.toJson(attributes));
+ bundle.putString("counters", gson.toJson(counters));
+ bundle.putString("metadata", metaData.toString());
+
+ Mapbox.getTelemetry().onPerformanceEvent(bundle);
+ }
+
+ private static String getRam() {
+ ActivityManager actManager =
+ (ActivityManager) Mapbox.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
+ ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
+ actManager.getMemoryInfo(memInfo);
+ return String.valueOf(memInfo.totalMem);
+ }
+
+ private static String getWindowSize() {
+ WindowManager windowManager =
+ (WindowManager) Mapbox.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
+ Display display = windowManager.getDefaultDisplay();
+ DisplayMetrics metrics = new DisplayMetrics();
+ display.getMetrics(metrics);
+ int width = metrics.widthPixels;
+ int height = metrics.heightPixels;
+
+ return "{" + width + "," + height + "}";
+ }
+
+ private class Attribute<T> {
+ private String name;
+ private T value;
+
+ Attribute(String name, T value) {
+ this.name = name;
+ this.value = value;
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_backstack_fragment.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_backstack_fragment.xml
index b6b672cf73..10c11a9320 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_backstack_fragment.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_backstack_fragment.xml
@@ -10,6 +10,7 @@
<Button android:layout_width="match_parent"
android:layout_height="58dp"
android:id="@+id/button"
+ android:contentDescription="btn_change_fragment"
android:text="Replace with empty fragment"/>
</FrameLayout> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_pixel_test.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_pixel_test.xml
new file mode 100644
index 0000000000..4c88a87703
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_pixel_test.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <com.mapbox.mapboxsdk.maps.MapView
+ android:layout_gravity="center"
+ android:id="@id/mapView"
+ app:mapbox_cameraZoom="1"
+ android:layout_width="1080px"
+ android:layout_height="1920px"
+ app:mapbox_pixelRatio="1"/>
+
+</FrameLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_snapshot.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_snapshot.xml
index 53345571b4..f0787ecad9 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_snapshot.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_snapshot.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
@@ -27,15 +26,4 @@
</LinearLayout>
- <android.support.design.widget.FloatingActionButton
- android:id="@id/fab"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:layout_alignParentEnd="true"
- android:layout_alignParentRight="true"
- android:layout_margin="@dimen/fab_margin"
- android:src="@drawable/ic_add_a_photo_black"
- app:backgroundTint="@android:color/white"/>
-
</RelativeLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_viewpager.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_viewpager.xml
index 3edaff6985..516bf60b6b 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_viewpager.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_viewpager.xml
@@ -5,7 +5,7 @@
android:layout_height="match_parent">
<com.mapbox.mapboxsdk.testapp.view.MapViewPager
- android:id="@+id/viewpager"
+ android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent">
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/item_map_gl.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/item_map_gl.xml
new file mode 100644
index 0000000000..850399e355
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/item_map_gl.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.mapbox.mapboxsdk.maps.MapView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@id/mapView"
+ android:layout_width="match_parent"
+ android:layout_height="256dp"
+ app:mapbox_cameraTargetLat="45.38301927899065"
+ app:mapbox_cameraTargetLng="8.63525390625"
+ app:mapbox_cameraZoom="7"/>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/item_map.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/item_map_texture.xml
index 3224b73477..3224b73477 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/item_map.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/item_map_texture.xml
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/categories.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/categories.xml
index a4403a34f7..2c34a59327 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/categories.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/categories.xml
@@ -15,4 +15,6 @@
<string name="category_storage">Storage</string>
<string name="category_textureview">Texture View</string>
<string name="category_location">Location</string>
+ <string name="category_integration">_Integration</string>
+ <string name="category_telemetry">Telemetry</string>
</resources> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml
index 21ebeaabd5..778805b3b3 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml
@@ -78,6 +78,8 @@
<string name="description_location_fragment">Uses LocationComponent in a Fragment</string>
<string name="description_location_manual">Force location updates and don\'t rely on the engine</string>
<string name="description_location_activation_builder">Use LocationComponentActivationOptions to set options</string>
- <string name="description_recyclerview">Show a MapView as a recyclerView item</string>
+ <string name="description_recyclerview_textureview">Show a TextureView MapView as a recyclerView item</string>
+ <string name="description_recyclerview_glsurfaceview">Show a GLSurfaceView MapView as a recyclerView item</string>
<string name="description_nested_viewpager">Show a MapView inside a viewpager inside a recyclerView</string>
+ <string name="description_performance_measurement">Show the use PerformanceEvent for performance measurements</string>
</resources>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/titles.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/titles.xml
index 26f56f29b1..12c82bf21a 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/titles.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/titles.xml
@@ -78,6 +78,8 @@
<string name="activity_location_fragment">Location Fragment</string>
<string name="activity_location_manual">Manual Location updates</string>
<string name="activity_location_activation_builder">Build Location Activation</string>
- <string name="activity_recyclerview">RecyclerView</string>
+ <string name="activity_recyclerview_textureview">RecyclerView TextureView</string>
+ <string name="activity_recyclerview_glsurfaceview">RecyclerView GLSurfaceView</string>
<string name="activity_nested_viewpager">Nested ViewPager</string>
+ <string name="activity_performance_measurement">Performance Measurement</string>
</resources> \ No newline at end of file
diff --git a/platform/android/build.gradle b/platform/android/build.gradle
index 5334c93ce9..97f3037afb 100644
--- a/platform/android/build.gradle
+++ b/platform/android/build.gradle
@@ -12,6 +12,7 @@ buildscript {
classpath dependenciesList.bintrayPlugin
classpath dependenciesList.artifactoryPlugin
classpath dependenciesList.androidPublishPlugin
+ classpath dependenciesList.jacocoPlugin
}
}
diff --git a/platform/android/gradle/android-nitpick.gradle b/platform/android/gradle/android-nitpick.gradle
index f8e4a47b0b..32539270f5 100644
--- a/platform/android/gradle/android-nitpick.gradle
+++ b/platform/android/gradle/android-nitpick.gradle
@@ -17,6 +17,8 @@ task androidNitpick {
verifyVendorSubmodulePin(MAPBOX_JAVA_DIR, MAPBOX_JAVA_TAG_PREFIX, versions.mapboxServices)
verifyVendorSubmodulePin(MAPBOX_TELEMETRY_DIR, MAPBOX_TELEMETRY_TAG_PREFIX, versions.mapboxTelemetry)
verifyVendorSubmodulePin(MAPBOX_GESTURES_DIR, MAPBOX_GESTURES_TAG_PREFIX, versions.mapboxGestures)
+
+ verifyLicenseGeneration()
}
}
@@ -51,4 +53,12 @@ private def verifyVendorSubmodulePin(def dir, def prefix, def version) {
"If you've bumped the pin, make sure to verify the version tag prefix in the android-nitpick.gradle file.")
}
output.close()
+}
+
+private def verifyLicenseGeneration() {
+ println "Verify license generation with git diff..."
+ exec {
+ workingDir = "${rootDir}"
+ commandLine "python", "scripts/validate-license.py"
+ }
} \ No newline at end of file
diff --git a/platform/android/gradle/dependencies.gradle b/platform/android/gradle/dependencies.gradle
index 600901ca76..1d17e7f83d 100644
--- a/platform/android/gradle/dependencies.gradle
+++ b/platform/android/gradle/dependencies.gradle
@@ -8,7 +8,7 @@ ext {
versions = [
mapboxServices : '4.3.0',
- mapboxTelemetry : '4.2.0',
+ mapboxTelemetry : '4.3.0',
mapboxGestures : '0.4.0',
supportLib : '27.1.1',
constraintLayout: '1.1.2',
@@ -29,7 +29,8 @@ ext {
androidPublish : '3.6.2',
lint : '26.1.4',
gms : '16.0.0',
- reLinker : '1.3.1'
+ reLinker : '1.3.1',
+ jacoco : '0.8.3'
]
dependenciesList = [
@@ -72,6 +73,7 @@ ext {
bintrayPlugin : "com.jfrog.bintray.gradle:gradle-bintray-plugin:${versions.bintray}",
artifactoryPlugin : "org.jfrog.buildinfo:build-info-extractor-gradle:${versions.artifactory}",
androidPublishPlugin : "digital.wup:android-maven-publish:${versions.androidPublish}",
+ jacocoPlugin : "org.jacoco:org.jacoco.core:${versions.jacoco}",
lint : "com.android.tools.lint:lint:${versions.lint}",
lintApi : "com.android.tools.lint:lint-api:${versions.lint}",
diff --git a/platform/android/gradle/jacoco-report.gradle b/platform/android/gradle/jacoco-report.gradle
new file mode 100644
index 0000000000..e50facb683
--- /dev/null
+++ b/platform/android/gradle/jacoco-report.gradle
@@ -0,0 +1,33 @@
+apply plugin: 'jacoco'
+apply from: "${rootDir}/gradle/dependencies.gradle"
+
+jacoco {
+ toolVersion = versions.jacoco
+}
+
+task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest']) {
+ group = "Reporting"
+ description = "Combine code coverage to unified report."
+
+ reports {
+ xml.enabled = true
+ html.enabled = true
+ }
+
+ def fileExcludes = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*']
+ def debugTree = fileTree(dir: "${project.buildDir}/intermediates/javac/debug/compileDebugJavaWithJavac/classes", excludes: fileExcludes)
+ def mainSrc = "${project.projectDir}/src/main/java"
+ println(mainSrc)
+ def ecSrc = fileTree(dir: "$project.buildDir", include: "**/*.ec")
+ def execSrc = fileTree(dir: "$project.buildDir", include: "**/*.exec")
+
+ doFirst {
+ def files = files([ecSrc, execSrc]).files
+ println "Creating Jacoco Report for ${files.size()} coverage files"
+ files.each { file -> println file }
+ }
+
+ sourceDirectories = files([mainSrc])
+ classDirectories = files([debugTree])
+ executionData = files([ecSrc, execSrc])
+} \ No newline at end of file
diff --git a/platform/android/scripts/exclude-activity-gen.json b/platform/android/scripts/exclude-activity-gen.json
index 9e0a1d154f..a6070edccf 100644
--- a/platform/android/scripts/exclude-activity-gen.json
+++ b/platform/android/scripts/exclude-activity-gen.json
@@ -48,5 +48,7 @@
"EspressoTestActivity",
"ChangeResourcesCachePathActivity",
"EspressoTestActivity",
- "FragmentBackStackActivity"
+ "FragmentBackStackActivity",
+ "ChildFragmentMapInDialogActivity",
+ "PerformanceMeasurementActivity"
]
diff --git a/platform/android/scripts/generate-style-code.js b/platform/android/scripts/generate-style-code.js
index 56e7511362..688a3aa527 100755
--- a/platform/android/scripts/generate-style-code.js
+++ b/platform/android/scripts/generate-style-code.js
@@ -197,7 +197,12 @@ global.defaultValueJava = function(property) {
case 'array':
switch (property.value) {
case 'string':
- return '[' + property['default'] + "]";
+ case 'enum':
+ if (property['default'] !== undefined) {
+ return '[' + property['default'] + ']';
+ } else {
+ return 'new String[0]';
+ }
case 'number':
var result ='new Float[] {';
for (var i = 0; i < property.length; i++) {
diff --git a/platform/android/scripts/parse-jacoco-report.py b/platform/android/scripts/parse-jacoco-report.py
new file mode 100755
index 0000000000..4d06fda6cc
--- /dev/null
+++ b/platform/android/scripts/parse-jacoco-report.py
@@ -0,0 +1,31 @@
+#!/usr/bin/python
+
+import os
+import re
+from io import open
+
+reportPath = os.getcwd() + "/platform/android/MapboxGLAndroidSDK/build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml"
+with open(reportPath, 'r', encoding='utf-8') as jacocoReport:
+ line = jacocoReport.readline().strip()
+
+ # find the last INSTRUCTION coverage report which is a sum of all separate ones
+ instructionIndex = line.rfind('type="INSTRUCTION"')
+ startIndex = line.find('missed', instructionIndex)
+ endIndex = line.find('/>', startIndex)
+
+ # find the missed and covered lines counts
+ numbers = re.match(r'missed="(\d+)" covered="(\d+)"', line[startIndex:endIndex])
+ missed = int(numbers.group(1))
+ covered = int(numbers.group(2))
+
+ # calculate the code coverage percentage
+ percentage = round(covered * 100.0 / (missed + covered), 2)
+ print("Android tests code coverage: %s%%" % (str(percentage)))
+
+ # invoke the script that send the data to s3
+ testEnvironment = "LOCAL"
+ if os.environ.get('IS_LOCAL_DEVELOPMENT').lower()=='false':
+ testEnvironment = "CI"
+
+ cmd = os.getcwd() + ("/scripts/code-coverage.sh %.2f %s %s" % (percentage, "Android", testEnvironment))
+ os.system(cmd)
diff --git a/platform/android/scripts/validate-license.py b/platform/android/scripts/validate-license.py
new file mode 100644
index 0000000000..365d7ac265
--- /dev/null
+++ b/platform/android/scripts/validate-license.py
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+
+from subprocess import call
+from subprocess import Popen, PIPE
+import sys
+
+## Run license generation
+call('cd ../../ && make android-license', shell=True)
+
+## Git diff changes
+p = Popen(['git', 'diff', '--name-only', 'LICENSE.md'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
+output, err = p.communicate(b"input data that is passed to subprocess' stdin")
+if "platform/android/LICENSE.md" in output:
+ raise ValueError("""An error ocurred while validating the license generation.
+ Changes were detected to the license generation output
+ but weren't commited. Run make android-license and
+ commit the changeset to make this validation pass.""") \ No newline at end of file
diff --git a/platform/android/src/conversion/constant.hpp b/platform/android/src/conversion/constant.hpp
index 4def670f3c..839e6e84dc 100644
--- a/platform/android/src/conversion/constant.hpp
+++ b/platform/android/src/conversion/constant.hpp
@@ -88,6 +88,17 @@ struct Converter<jni::Local<jni::Object<>>, T, typename std::enable_if_t<std::is
}
};
+template <class T>
+struct Converter<jni::Local<jni::Object<>>, std::vector<T>, typename std::enable_if_t<std::is_enum<T>::value>> {
+ Result<jni::Local<jni::Object<>>> operator()(jni::JNIEnv& env, const std::vector<T>& value) const {
+ auto result = jni::Array<jni::String>::New(env, value.size());
+ for (std::size_t i = 0; i < value.size(); ++i) {
+ result.Set(env, i, jni::Make<jni::String>(env, Enum<T>::toString(value.at(i))));
+ }
+ return result;
+ }
+};
+
} // namespace conversion
} // namespace android
} // namespace mbgl
diff --git a/platform/android/src/file_source.cpp b/platform/android/src/file_source.cpp
index 4cfb545b84..41081cd0fb 100644
--- a/platform/android/src/file_source.cpp
+++ b/platform/android/src/file_source.cpp
@@ -3,6 +3,7 @@
#include <mbgl/actor/actor.hpp>
#include <mbgl/actor/scheduler.hpp>
+#include <mbgl/storage/resource_options.hpp>
#include <mbgl/storage/resource_transform.hpp>
#include <mbgl/util/logging.hpp>
@@ -11,6 +12,14 @@
#include "asset_manager_file_source.hpp"
namespace mbgl {
+
+std::shared_ptr<FileSource> FileSource::createPlatformFileSource(const ResourceOptions& options) {
+ auto* assetFileSource = reinterpret_cast<AssetManagerFileSource*>(options.platformContext());
+ auto fileSource = std::make_shared<DefaultFileSource>(options.cachePath(), std::unique_ptr<AssetManagerFileSource>(assetFileSource));
+ fileSource->setAccessToken(options.accessToken());
+ return fileSource;
+}
+
namespace android {
// FileSource //
@@ -22,15 +31,13 @@ FileSource::FileSource(jni::JNIEnv& _env,
std::string path = jni::Make<std::string>(_env, _cachePath);
mapbox::sqlite::setTempPath(path);
- // Create a core default file source
- fileSource = std::make_unique<mbgl::DefaultFileSource>(
- path + DATABASE_FILE,
- std::make_unique<AssetManagerFileSource>(_env, assetManager));
+ resourceOptions
+ .withAccessToken(accessToken ? jni::Make<std::string>(_env, accessToken) : "")
+ .withCachePath(path + DATABASE_FILE)
+ .withPlatformContext(reinterpret_cast<void*>(new AssetManagerFileSource(_env, assetManager)));
- // Set access token
- if (accessToken) {
- fileSource->setAccessToken(jni::Make<std::string>(_env, accessToken));
- }
+ // Create a core default file source
+ fileSource = std::static_pointer_cast<mbgl::DefaultFileSource>(mbgl::FileSource::getSharedFileSource(resourceOptions));
}
FileSource::~FileSource() {
@@ -110,10 +117,10 @@ FileSource* FileSource::getNativePeer(jni::JNIEnv& env, const jni::Object<FileSo
return reinterpret_cast<FileSource *>(jFileSource.Get(env, field));
}
-mbgl::DefaultFileSource& FileSource::getDefaultFileSource(jni::JNIEnv& env, const jni::Object<FileSource>& jFileSource) {
+mbgl::ResourceOptions FileSource::getSharedResourceOptions(jni::JNIEnv& env, const jni::Object<FileSource>& jFileSource) {
FileSource* fileSource = FileSource::getNativePeer(env, jFileSource);
assert(fileSource != nullptr);
- return *fileSource->fileSource;
+ return fileSource->resourceOptions.clone();
}
void FileSource::registerNative(jni::JNIEnv& env) {
diff --git a/platform/android/src/file_source.hpp b/platform/android/src/file_source.hpp
index 575702120e..3001a5e0f0 100644
--- a/platform/android/src/file_source.hpp
+++ b/platform/android/src/file_source.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <mbgl/storage/default_file_source.hpp>
+#include <mbgl/storage/resource_options.hpp>
#include "asset_manager.hpp"
@@ -49,15 +50,16 @@ public:
static FileSource* getNativePeer(jni::JNIEnv&, const jni::Object<FileSource>&);
- static mbgl::DefaultFileSource& getDefaultFileSource(jni::JNIEnv&, const jni::Object<FileSource>&);
+ static mbgl::ResourceOptions getSharedResourceOptions(jni::JNIEnv&, const jni::Object<FileSource>&);
static void registerNative(jni::JNIEnv&);
private:
const std::string DATABASE_FILE = "/mbgl-offline.db";
optional<int> activationCounter;
+ mbgl::ResourceOptions resourceOptions;
std::unique_ptr<Actor<ResourceTransform>> resourceTransform;
- std::unique_ptr<mbgl::DefaultFileSource> fileSource;
+ std::shared_ptr<mbgl::DefaultFileSource> fileSource;
};
diff --git a/platform/android/src/map_renderer.hpp b/platform/android/src/map_renderer.hpp
index 3e5b99605e..57265cebb1 100644
--- a/platform/android/src/map_renderer.hpp
+++ b/platform/android/src/map_renderer.hpp
@@ -1,13 +1,15 @@
#pragma once
+#include <mbgl/actor/actor_ref.hpp>
#include <mbgl/actor/scheduler.hpp>
#include <mbgl/util/image.hpp>
+#include <mbgl/util/optional.hpp>
#include <memory>
+#include <mutex>
#include <utility>
#include <jni/jni.hpp>
-#include <mbgl/storage/default_file_source.hpp>
namespace mbgl {
diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp
index 3a4e2014ba..e74e4c3bbc 100755
--- a/platform/android/src/native_map_view.cpp
+++ b/platform/android/src/native_map_view.cpp
@@ -13,6 +13,7 @@
#include <jni/jni.hpp>
+#include <mbgl/map/map.hpp>
#include <mbgl/map/map_options.hpp>
#include <mbgl/math/minmax.hpp>
#include <mbgl/util/constants.hpp>
@@ -74,24 +75,22 @@ NativeMapView::NativeMapView(jni::JNIEnv& _env,
return;
}
- // Get native peer for file source
- mbgl::FileSource& fileSource = mbgl::android::FileSource::getDefaultFileSource(_env, jFileSource);
-
// Create a renderer frontend
rendererFrontend = std::make_unique<AndroidRendererFrontend>(mapRenderer);
// Create Map options
MapOptions options;
options.withMapMode(MapMode::Continuous)
+ .withSize(mbgl::Size{ static_cast<uint32_t>(width), static_cast<uint32_t>(height) })
+ .withPixelRatio(pixelRatio)
.withConstrainMode(ConstrainMode::HeightOnly)
.withViewportMode(ViewportMode::Default)
.withCrossSourceCollisions(_crossSourceCollisions);
// Create the core map
- map = std::make_unique<mbgl::Map>(*rendererFrontend, *this,
- mbgl::Size{ static_cast<uint32_t>(width),
- static_cast<uint32_t>(height) }, pixelRatio,
- fileSource, *threadPool, options);
+ map = std::make_unique<mbgl::Map>(
+ *rendererFrontend, *this, *threadPool, options,
+ mbgl::android::FileSource::getSharedResourceOptions(_env, jFileSource));
}
/**
diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp
index d695a91ce0..903543e5d1 100755
--- a/platform/android/src/native_map_view.hpp
+++ b/platform/android/src/native_map_view.hpp
@@ -6,7 +6,6 @@
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/util/run_loop.hpp>
-#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/network_status.hpp>
#include "annotation/marker.hpp"
diff --git a/platform/android/src/offline/offline_manager.cpp b/platform/android/src/offline/offline_manager.cpp
index 968c33b644..54b1142845 100644
--- a/platform/android/src/offline/offline_manager.cpp
+++ b/platform/android/src/offline/offline_manager.cpp
@@ -10,20 +10,19 @@ namespace android {
// OfflineManager //
OfflineManager::OfflineManager(jni::JNIEnv& env, const jni::Object<FileSource>& jFileSource)
- : fileSource(mbgl::android::FileSource::getDefaultFileSource(env, jFileSource)) {
-}
+ : fileSource(std::static_pointer_cast<DefaultFileSource>(mbgl::FileSource::getSharedFileSource(FileSource::getSharedResourceOptions(env, jFileSource)))) {}
OfflineManager::~OfflineManager() {}
void OfflineManager::setOfflineMapboxTileCountLimit(jni::JNIEnv&, jni::jlong limit) {
- fileSource.setOfflineMapboxTileCountLimit(limit);
+ fileSource->setOfflineMapboxTileCountLimit(limit);
}
void OfflineManager::listOfflineRegions(jni::JNIEnv& env_, const jni::Object<FileSource>& jFileSource_, const jni::Object<ListOfflineRegionsCallback>& callback_) {
auto globalCallback = jni::NewGlobal<jni::EnvAttachingDeleter>(env_, callback_);
auto globalFilesource = jni::NewGlobal<jni::EnvAttachingDeleter>(env_, jFileSource_);
- fileSource.listOfflineRegions([
+ fileSource->listOfflineRegions([
//Keep a shared ptr to a global reference of the callback and file source so they are not GC'd in the meanwhile
callback = std::make_shared<decltype(globalCallback)>(std::move(globalCallback)),
jFileSource = std::make_shared<decltype(globalFilesource)>(std::move(globalFilesource))
@@ -59,7 +58,7 @@ void OfflineManager::createOfflineRegion(jni::JNIEnv& env_,
auto globalFilesource = jni::NewGlobal<jni::EnvAttachingDeleter>(env_, jFileSource_);
// Create region
- fileSource.createOfflineRegion(definition, metadata, [
+ fileSource->createOfflineRegion(definition, metadata, [
//Keep a shared ptr to a global reference of the callback and file source so they are not GC'd in the meanwhile
callback = std::make_shared<decltype(globalCallback)>(std::move(globalCallback)),
jFileSource = std::make_shared<decltype(globalFilesource)>(std::move(globalFilesource))
@@ -86,7 +85,7 @@ void OfflineManager::mergeOfflineRegions(jni::JNIEnv& env_, const jni::Object<Fi
auto globalFilesource = jni::NewGlobal<jni::EnvAttachingDeleter>(env_, jFileSource_);
auto path = jni::Make<std::string>(env_, jString_);
- fileSource.mergeOfflineRegions(path, [
+ fileSource->mergeOfflineRegions(path, [
//Keep a shared ptr to a global reference of the callback and file source so they are not GC'd in the meanwhile
callback = std::make_shared<decltype(globalCallback)>(std::move(globalCallback)),
jFileSource = std::make_shared<decltype(globalFilesource)>(std::move(globalFilesource))
@@ -226,7 +225,7 @@ void OfflineManager::putResourceWithUrl(jni::JNIEnv& env,
response.expires = Timestamp(mbgl::Seconds(expires));
}
- fileSource.put(resource, response);
+ fileSource->put(resource, response);
}
} // namespace android
diff --git a/platform/android/src/offline/offline_manager.hpp b/platform/android/src/offline/offline_manager.hpp
index f8d57b88da..d0b637b900 100644
--- a/platform/android/src/offline/offline_manager.hpp
+++ b/platform/android/src/offline/offline_manager.hpp
@@ -1,7 +1,5 @@
#pragma once
-
-#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/offline.hpp>
#include <jni/jni.hpp>
@@ -10,8 +8,12 @@
#include "offline_region_definition.hpp"
#include "../java_types.hpp"
+#include <memory>
namespace mbgl {
+
+class DefaultFileSource;
+
namespace android {
class OfflineManager {
@@ -85,7 +87,7 @@ public:
private:
- mbgl::DefaultFileSource& fileSource;
+ std::shared_ptr<mbgl::DefaultFileSource> fileSource;
};
} // namespace android
diff --git a/platform/android/src/offline/offline_region.cpp b/platform/android/src/offline/offline_region.cpp
index 1cd73a7c76..e0f28631b4 100644
--- a/platform/android/src/offline/offline_region.cpp
+++ b/platform/android/src/offline/offline_region.cpp
@@ -14,8 +14,8 @@ namespace android {
// OfflineRegion //
OfflineRegion::OfflineRegion(jni::JNIEnv& env, jni::jlong offlineRegionPtr, const jni::Object<FileSource>& jFileSource)
- : region(reinterpret_cast<mbgl::OfflineRegion *>(offlineRegionPtr)),
- fileSource(mbgl::android::FileSource::getDefaultFileSource(env, jFileSource)) {}
+ : region(reinterpret_cast<mbgl::OfflineRegion *>(offlineRegionPtr))
+ , fileSource(std::static_pointer_cast<DefaultFileSource>(mbgl::FileSource::getSharedFileSource(FileSource::getSharedResourceOptions(env, jFileSource)))) {}
OfflineRegion::~OfflineRegion() {}
@@ -62,7 +62,7 @@ void OfflineRegion::setOfflineRegionObserver(jni::JNIEnv& env_, const jni::Objec
};
// Set the observer
- fileSource.setOfflineRegionObserver(*region, std::make_unique<Observer>(jni::NewGlobal<jni::EnvAttachingDeleter>(env_, callback)));
+ fileSource->setOfflineRegionObserver(*region, std::make_unique<Observer>(jni::NewGlobal<jni::EnvAttachingDeleter>(env_, callback)));
}
void OfflineRegion::setOfflineRegionDownloadState(jni::JNIEnv&, jni::jint jState) {
@@ -80,13 +80,13 @@ void OfflineRegion::setOfflineRegionDownloadState(jni::JNIEnv&, jni::jint jState
return;
}
- fileSource.setOfflineRegionDownloadState(*region, state);
+ fileSource->setOfflineRegionDownloadState(*region, state);
}
void OfflineRegion::getOfflineRegionStatus(jni::JNIEnv& env_, const jni::Object<OfflineRegionStatusCallback>& callback_) {
auto globalCallback = jni::NewGlobal<jni::EnvAttachingDeleter>(env_, callback_);
- fileSource.getOfflineRegionStatus(*region, [
+ fileSource->getOfflineRegionStatus(*region, [
//Ensure the object is not gc'd in the meanwhile
callback = std::make_shared<decltype(globalCallback)>(std::move(globalCallback))
](mbgl::expected<mbgl::OfflineRegionStatus, std::exception_ptr> status) mutable {
@@ -104,7 +104,7 @@ void OfflineRegion::getOfflineRegionStatus(jni::JNIEnv& env_, const jni::Object<
void OfflineRegion::deleteOfflineRegion(jni::JNIEnv& env_, const jni::Object<OfflineRegionDeleteCallback>& callback_) {
auto globalCallback = jni::NewGlobal<jni::EnvAttachingDeleter>(env_, callback_);
- fileSource.deleteOfflineRegion(std::move(*region), [
+ fileSource->deleteOfflineRegion(std::move(*region), [
//Ensure the object is not gc'd in the meanwhile
callback = std::make_shared<decltype(globalCallback)>(std::move(globalCallback))
](std::exception_ptr error) mutable {
@@ -123,7 +123,7 @@ void OfflineRegion::updateOfflineRegionMetadata(jni::JNIEnv& env_, const jni::Ar
auto metadata = OfflineRegion::metadata(env_, jMetadata);
auto globalCallback = jni::NewGlobal<jni::EnvAttachingDeleter>(env_, callback_);
- fileSource.updateOfflineMetadata(region->getID(), metadata, [
+ fileSource->updateOfflineMetadata(region->getID(), metadata, [
//Ensure the object is not gc'd in the meanwhile
callback = std::make_shared<decltype(globalCallback)>(std::move(globalCallback))
](mbgl::expected<mbgl::OfflineRegionMetadata, std::exception_ptr> data) mutable {
diff --git a/platform/android/src/offline/offline_region.hpp b/platform/android/src/offline/offline_region.hpp
index 49fa0c8ff8..4618e1abbd 100644
--- a/platform/android/src/offline/offline_region.hpp
+++ b/platform/android/src/offline/offline_region.hpp
@@ -74,7 +74,7 @@ public:
private:
std::unique_ptr<mbgl::OfflineRegion> region;
- mbgl::DefaultFileSource& fileSource;
+ std::shared_ptr<mbgl::DefaultFileSource> fileSource;
};
} // namespace android
diff --git a/platform/android/src/snapshotter/map_snapshotter.cpp b/platform/android/src/snapshotter/map_snapshotter.cpp
index 8eb1d02605..47a2781cb5 100644
--- a/platform/android/src/snapshotter/map_snapshotter.cpp
+++ b/platform/android/src/snapshotter/map_snapshotter.cpp
@@ -37,7 +37,6 @@ MapSnapshotter::MapSnapshotter(jni::JNIEnv& _env,
}
jFileSource = FileSource::getNativePeer(_env, _jFileSource);
- auto& fileSource = mbgl::android::FileSource::getDefaultFileSource(_env, _jFileSource);
auto size = mbgl::Size { static_cast<uint32_t>(width), static_cast<uint32_t>(height) };
optional<mbgl::CameraOptions> cameraOptions;
@@ -56,11 +55,10 @@ MapSnapshotter::MapSnapshotter(jni::JNIEnv& _env,
} else {
style = std::make_pair(false, jni::Make<std::string>(_env, styleURL));
}
-
+
showLogo = _showLogo;
// Create the core snapshotter
- snapshotter = std::make_unique<mbgl::MapSnapshotter>(&fileSource,
- threadPool,
+ snapshotter = std::make_unique<mbgl::MapSnapshotter>(threadPool,
style,
size,
pixelRatio,
@@ -69,8 +67,8 @@ MapSnapshotter::MapSnapshotter(jni::JNIEnv& _env,
jni::Make<std::string>(_env, _programCacheDir),
_localIdeographFontFamily ?
jni::Make<std::string>(_env, _localIdeographFontFamily) :
- optional<std::string>{});
-
+ optional<std::string>{},
+ mbgl::android::FileSource::getSharedResourceOptions(_env, _jFileSource));
}
MapSnapshotter::~MapSnapshotter() = default;
diff --git a/platform/android/src/style/layers/symbol_layer.cpp b/platform/android/src/style/layers/symbol_layer.cpp
index 61e4d59326..810848e9cb 100644
--- a/platform/android/src/style/layers/symbol_layer.cpp
+++ b/platform/android/src/style/layers/symbol_layer.cpp
@@ -176,6 +176,16 @@ namespace android {
return std::move(*convert<jni::Local<jni::Object<>>>(env, toSymbolLayer(layer).getTextJustify()));
}
+ jni::Local<jni::Object<>> SymbolLayer::getTextRadialOffset(jni::JNIEnv& env) {
+ using namespace mbgl::android::conversion;
+ return std::move(*convert<jni::Local<jni::Object<>>>(env, toSymbolLayer(layer).getTextRadialOffset()));
+ }
+
+ jni::Local<jni::Object<>> SymbolLayer::getTextVariableAnchor(jni::JNIEnv& env) {
+ using namespace mbgl::android::conversion;
+ return std::move(*convert<jni::Local<jni::Object<>>>(env, toSymbolLayer(layer).getTextVariableAnchor()));
+ }
+
jni::Local<jni::Object<>> SymbolLayer::getTextAnchor(jni::JNIEnv& env) {
using namespace mbgl::android::conversion;
return std::move(*convert<jni::Local<jni::Object<>>>(env, toSymbolLayer(layer).getTextAnchor()));
@@ -514,6 +524,8 @@ namespace android {
METHOD(&SymbolLayer::getTextLineHeight, "nativeGetTextLineHeight"),
METHOD(&SymbolLayer::getTextLetterSpacing, "nativeGetTextLetterSpacing"),
METHOD(&SymbolLayer::getTextJustify, "nativeGetTextJustify"),
+ METHOD(&SymbolLayer::getTextRadialOffset, "nativeGetTextRadialOffset"),
+ METHOD(&SymbolLayer::getTextVariableAnchor, "nativeGetTextVariableAnchor"),
METHOD(&SymbolLayer::getTextAnchor, "nativeGetTextAnchor"),
METHOD(&SymbolLayer::getTextMaxAngle, "nativeGetTextMaxAngle"),
METHOD(&SymbolLayer::getTextRotate, "nativeGetTextRotate"),
diff --git a/platform/android/src/style/layers/symbol_layer.hpp b/platform/android/src/style/layers/symbol_layer.hpp
index f52597ef6f..3b0f8ee5d1 100644
--- a/platform/android/src/style/layers/symbol_layer.hpp
+++ b/platform/android/src/style/layers/symbol_layer.hpp
@@ -80,6 +80,10 @@ public:
jni::Local<jni::Object<jni::ObjectTag>> getTextJustify(jni::JNIEnv&);
+ jni::Local<jni::Object<jni::ObjectTag>> getTextRadialOffset(jni::JNIEnv&);
+
+ jni::Local<jni::Object<jni::ObjectTag>> getTextVariableAnchor(jni::JNIEnv&);
+
jni::Local<jni::Object<jni::ObjectTag>> getTextAnchor(jni::JNIEnv&);
jni::Local<jni::Object<jni::ObjectTag>> getTextMaxAngle(jni::JNIEnv&);
diff --git a/platform/android/vendor/mapbox-events-android b/platform/android/vendor/mapbox-events-android
-Subproject 1636d1ae9d5b0f0dd2367c8f32f1af958640b14
+Subproject 5bdf0d90292fb46cd8b1f795763d281b5ac83e0