From 08916f2d5f63a6ef746e0560e3a56784db81e3dc Mon Sep 17 00:00:00 2001 From: Antonio Zugaldia Date: Thu, 11 May 2017 09:19:24 -0400 Subject: [android] Update release script to support CircleCI builds (#8950) * update release script to trigger builds on circleci now * update release script to trigger builds on circleci now --- platform/android/scripts/release.py | 48 ++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/platform/android/scripts/release.py b/platform/android/scripts/release.py index 8abcccffdb..ce554d1362 100644 --- a/platform/android/scripts/release.py +++ b/platform/android/scripts/release.py @@ -1,5 +1,5 @@ ''' -Utility to schedule SDK builds in Bitrise. +Utility to schedule SDK builds on CircleCI. Examples: @@ -33,7 +33,7 @@ Examples: TODO: -- Add a flag to wait until the release has been built (Bitrise) and published (Maven). +- Add a flag to wait until the release has been built (CircleCI) and published (Maven). ''' @@ -49,8 +49,8 @@ ALLOWED_STAGES = ['snapshot', 'beta', 'final'] # Get the version from GRADLE_PROPERTIES_PATH below CURRENT_VERSION_TAG = 'current' -# You can find the API token in https://www.bitrise.io/app/79cdcbdc42de4303#/code -> API token -BITRISE_API_TOKEN_ENV_VAR = 'BITRISE_API_TOKEN' +# You can add your API token on https://circleci.com/account/api +CIRCLECI_API_TOKEN_ENV_VAR = 'CIRCLECI_API_TOKEN' # In the future we might want to consider alpha, or rc. ALLOWED_PRE_RELEASE = ['beta'] @@ -62,8 +62,8 @@ GRADLE_TOKEN = 'VERSION_NAME=' FABRIC_PROPERTIES_PATH = '%s/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties' % MAPBOX_GL_ANDROID_SDK_PATH FABRIC_TOKEN = 'fabric-version=' -# Bitrise -URL_BITRISE = 'https://www.bitrise.io/app/79cdcbdc42de4303/build/start.json' +# Triggers a new build, returns a summary of the build +URL_CIRCLECI = 'https://circleci.com/api/v1.1/project/github/mapbox/mapbox-gl-native/tree/' # + :branch # We support three parameters: stage, branch, and version @click.command() @@ -129,7 +129,7 @@ def publish_snapshot(branch, version): if dirty_gradle: git_add(path=GRADLE_PROPERTIES_PATH) git_commit_and_push(branch=branch, version=version) - do_bitrise_request(build_params={'branch': branch, 'workflow_id': 'scheduled'}) + do_circleci_request(branch=branch) def publish_beta(branch, version): click.echo('Publishing beta from branch: %s (version: %s).' % (branch, version)) @@ -137,7 +137,7 @@ def publish_beta(branch, version): if dirty_gradle: git_add(path=GRADLE_PROPERTIES_PATH) git_commit_and_push(branch=branch, version=version) - do_bitrise_request(build_params={'branch': branch, 'workflow_id': 'scheduled'}) + do_circleci_request(branch=branch) def publish_final(branch, version): click.echo('Publishing final release from branch: %s (version: %s).' % (branch, version)) @@ -149,7 +149,7 @@ def publish_final(branch, version): git_add(path=FABRIC_PROPERTIES_PATH) if dirty_gradle or dirty_fabric: git_commit_and_push(branch=branch, version=version) - do_bitrise_request(build_params={'branch': branch, 'workflow_id': 'scheduled'}) + do_circleci_request(branch=branch) # # Utils @@ -166,26 +166,24 @@ def execute_call(command): abort_with_message('Command failed: %s' % command) # -# Bitrise +# CircleCI # -def get_bitrise_api_token(): - bitrise_api_token = os.environ.get(BITRISE_API_TOKEN_ENV_VAR) - if not bitrise_api_token: - abort_with_message('You need to set the BITRISE_API_TOKEN environment variable.') - click.echo('Found Bitrise API token.') - return bitrise_api_token - -def do_bitrise_request(build_params): - data = { - 'hook_info': {'type': 'bitrise', 'api_token': get_bitrise_api_token()}, - 'build_params' : build_params} - click.echo('Bitrise request data: %s' % json.dumps(data)) +def get_circleci_api_token(): + circleci_api_token = os.environ.get(CIRCLECI_API_TOKEN_ENV_VAR) + if not circleci_api_token: + abort_with_message('You need to set the CIRCLECI_API_TOKEN environment variable.') + click.echo('Found CircleCI API token.') + return circleci_api_token + +def do_circleci_request(branch): + url = URL_CIRCLECI + branch + params = {'circle-token': get_circleci_api_token()} + click.echo('CircleCI request to %s (params: %s)' % (url, json.dumps(params))) click.confirm('\nDo you want to start a build?', abort=True) - r = requests.post(URL_BITRISE, data=json.dumps(data)) - click.echo('- Bitrise response code: %s' % r.status_code) - click.echo('- Bitrise response content: %s' % r.text) + r = requests.post(url, params=params) + click.echo('- CircleCI response code: %s' % r.status_code) # # Git -- cgit v1.2.1 From db370a02b13f39ce79b8df11e784b3543f2908cb Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 10 May 2017 17:51:55 -0700 Subject: [core] When a layer is added, reload its source's tiles --- mapbox-gl-js | 2 +- src/mbgl/style/style.cpp | 31 ++++++++++++++++--------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/mapbox-gl-js b/mapbox-gl-js index 44641e917e..8b085a2115 160000 --- a/mapbox-gl-js +++ b/mapbox-gl-js @@ -1 +1 @@ -Subproject commit 44641e917ed0e37a1c1622ab154f068b22927b03 +Subproject commit 8b085a211579d417ad8b3d58bc502c4ffbdfc2e9 diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index 4b694917c3..f083ca47b8 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -52,6 +52,21 @@ namespace style { static Observer nullObserver; +struct QueueSourceReloadVisitor { + UpdateBatch& updateBatch; + + // No need to reload sources for these types; their visibility can change but + // they don't participate in layout. + void operator()(CustomLayer&) {} + void operator()(RasterLayer&) {} + void operator()(BackgroundLayer&) {} + + template + void operator()(VectorLayer& layer) { + updateBatch.sourceIDs.insert(layer.getSourceID()); + } +}; + Style::Style(Scheduler& scheduler_, FileSource& fileSource_, float pixelRatio) : scheduler(scheduler_), fileSource(fileSource_), @@ -248,6 +263,7 @@ Layer* Style::addLayer(std::unique_ptr layer, optional befor } layer->baseImpl->setObserver(this); + layer->accept(QueueSourceReloadVisitor { updateBatch }); auto added = layers.emplace(before ? findLayer(*before) : layers.end(), std::move(layer))->get(); renderLayers.emplace(before ? findRenderLayer(*before) : renderLayers.end(), added->baseImpl->createRenderLayer()); @@ -726,21 +742,6 @@ void Style::onSpriteError(std::exception_ptr error) { observer->onResourceError(error); } -struct QueueSourceReloadVisitor { - UpdateBatch& updateBatch; - - // No need to reload sources for these types; their visibility can change but - // they don't participate in layout. - void operator()(CustomLayer&) {} - void operator()(RasterLayer&) {} - void operator()(BackgroundLayer&) {} - - template - void operator()(VectorLayer& layer) { - updateBatch.sourceIDs.insert(layer.getSourceID()); - } -}; - void Style::onLayerFilterChanged(Layer& layer) { layer.accept(QueueSourceReloadVisitor { updateBatch }); observer->onUpdate(Update::Repaint); -- cgit v1.2.1 From ad46d67aeb84b258668126dddc00c581f4808f3e Mon Sep 17 00:00:00 2001 From: Tobrun Date: Thu, 11 May 2017 21:00:41 +0200 Subject: [android] - keep observer when timeout occurs, make observer param nullable, fixup log messages (#8919) --- .../com/mapbox/mapboxsdk/offline/OfflineRegion.java | 17 ++++++++++++----- .../testapp/activity/offline/OfflineActivity.java | 10 ++++------ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java index a55e8dd848..2110e12b36 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java @@ -4,6 +4,7 @@ import android.os.Handler; import android.os.Looper; import android.support.annotation.IntDef; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import com.mapbox.mapboxsdk.storage.FileSource; @@ -205,7 +206,7 @@ public class OfflineRegion { /** * Constructor - * + *

* For JNI use only, to create a new offline region, use * {@link OfflineManager#createOfflineRegion} instead. */ @@ -247,7 +248,7 @@ public class OfflineRegion { * * @param observer the observer to be notified */ - public void setObserver(@NonNull final OfflineRegionObserver observer) { + public void setObserver(@Nullable final OfflineRegionObserver observer) { setOfflineRegionObserver(new OfflineRegionObserver() { @Override public void onStatusChanged(final OfflineRegionStatus status) { @@ -255,7 +256,9 @@ public class OfflineRegion { getHandler().post(new Runnable() { @Override public void run() { - observer.onStatusChanged(status); + if (observer != null) { + observer.onStatusChanged(status); + } } }); } @@ -267,7 +270,9 @@ public class OfflineRegion { getHandler().post(new Runnable() { @Override public void run() { - observer.onError(error); + if (observer != null) { + observer.onError(error); + } } }); } @@ -279,7 +284,9 @@ public class OfflineRegion { getHandler().post(new Runnable() { @Override public void run() { - observer.mapboxTileCountLimitExceeded(limit); + if (observer != null) { + observer.mapboxTileCountLimitExceeded(limit); + } } }); } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java index be5d809457..344e9e140a 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java @@ -274,22 +274,20 @@ public class OfflineActivity extends AppCompatActivity } // Debug - Timber.d(String.format("%s/%s resources; %s bytes downloaded.", + Timber.d("%s/%s resources; %s bytes downloaded.", String.valueOf(status.getCompletedResourceCount()), String.valueOf(status.getRequiredResourceCount()), - String.valueOf(status.getCompletedResourceSize()))); + String.valueOf(status.getCompletedResourceSize())); } @Override public void onError(OfflineRegionError error) { - Timber.e("onError reason: " + error.getReason()); - Timber.e("onError message: " + error.getMessage()); - offlineRegion.setObserver(null); + Timber.e("onError: %s, %s", error.getReason(), error.getMessage()); } @Override public void mapboxTileCountLimitExceeded(long limit) { - Timber.e("Mapbox tile count limit exceeded: " + limit); + Timber.e("Mapbox tile count limit exceeded: %s", limit); } }); -- cgit v1.2.1 From 850b008a2fd872c6158502b821da17864711bb12 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Thu, 11 May 2017 21:39:17 +0200 Subject: [android] - avoid crashing when deleting already deleted region (#8920) --- .../mapbox/mapboxsdk/offline/OfflineRegion.java | 48 ++++++++++++---------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java index 2110e12b36..44bb2a05ee 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java @@ -37,6 +37,9 @@ public class OfflineRegion { //Region id private long id; + // delete status + private boolean isDeleted; + private OfflineRegionDefinition definition; /** @@ -353,28 +356,31 @@ public class OfflineRegion { * @param callback the callback to be invoked */ public void delete(@NonNull final OfflineRegionDeleteCallback callback) { - deleteOfflineRegion(new OfflineRegionDeleteCallback() { - @Override - public void onDelete() { - getHandler().post(new Runnable() { - @Override - public void run() { - callback.onDelete(); - OfflineRegion.this.finalize(); - } - }); - } + if (!isDeleted) { + deleteOfflineRegion(new OfflineRegionDeleteCallback() { + @Override + public void onDelete() { + isDeleted = true; + getHandler().post(new Runnable() { + @Override + public void run() { + callback.onDelete(); + OfflineRegion.this.finalize(); + } + }); + } - @Override - public void onError(final String error) { - getHandler().post(new Runnable() { - @Override - public void run() { - callback.onError(error); - } - }); - } - }); + @Override + public void onError(final String error) { + getHandler().post(new Runnable() { + @Override + public void run() { + callback.onError(error); + } + }); + } + }); + } } /** -- cgit v1.2.1 From e681f69993ea9b28e745e8933744960eb5a608f8 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 12 May 2017 15:16:13 +0200 Subject: [android] - update LOST to 2.3.0 (#8872) --- platform/android/MapboxGLAndroidSDK/build.gradle | 4 +++- .../java/com/mapbox/mapboxsdk/location/LocationSource.java | 10 ---------- platform/android/MapboxGLAndroidSDKTestApp/build.gradle | 3 --- platform/android/build.gradle | 1 + platform/android/dependencies.gradle | 14 +++++++------- 5 files changed, 11 insertions(+), 21 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/build.gradle b/platform/android/MapboxGLAndroidSDK/build.gradle index 1156a6ef43..c4668f598c 100644 --- a/platform/android/MapboxGLAndroidSDK/build.gradle +++ b/platform/android/MapboxGLAndroidSDK/build.gradle @@ -6,7 +6,9 @@ dependencies { compile rootProject.ext.dep.supportDesign compile rootProject.ext.dep.timber compile rootProject.ext.dep.okhttp3 - compile rootProject.ext.dep.lost + compile(rootProject.ext.dep.lost) { + exclude module: 'support-compat' + } // Mapbox Android Services (GeoJSON support) compile(rootProject.ext.dep.mapboxJavaGeoJSON) { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java index b795cf1d5b..c4bdb4a17d 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java @@ -135,14 +135,4 @@ public class LocationSource extends LocationEngine implements listener.onLocationChanged(location); } } - - @Override - public void onProviderDisabled(String provider) { - Log.d(LOG_TAG, "Provider disabled: " + provider); - } - - @Override - public void onProviderEnabled(String provider) { - Log.d(LOG_TAG, "Provider enabled: " + provider); - } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle index 3dc20c9f5b..56b537e2a2 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle +++ b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle @@ -61,10 +61,7 @@ dependencies { } // Support libraries - compile rootProject.ext.dep.supportAnnotations - compile rootProject.ext.dep.supportV4 compile rootProject.ext.dep.supportAppcompatV7 - compile rootProject.ext.dep.supportDesign compile rootProject.ext.dep.supportRecyclerView // Leak Canary diff --git a/platform/android/build.gradle b/platform/android/build.gradle index 120c0219e4..bc90896812 100644 --- a/platform/android/build.gradle +++ b/platform/android/build.gradle @@ -12,6 +12,7 @@ buildscript { allprojects { repositories { jcenter() + maven { url "http://oss.sonatype.org/content/repositories/snapshots/" } } } diff --git a/platform/android/dependencies.gradle b/platform/android/dependencies.gradle index 738f571c09..817697140e 100644 --- a/platform/android/dependencies.gradle +++ b/platform/android/dependencies.gradle @@ -7,21 +7,21 @@ ext { versionCode = 11 versionName = "5.0.0" - supportLibVersion = "25.3.1" - leakCanaryVersion = '1.5' + mapboxServicesVersion = "2.2.0-SNAPSHOT" + supportLibVersion = "25.1.0" wearableVersion = '2.0.0' - espressoVersion = '2.2.2' testRunnerVersion = '0.5' + leakCanaryVersion = '1.5' dep = [ // mapbox - mapboxJavaServices : 'com.mapbox.mapboxsdk:mapbox-java-services:2.1.0@jar', - mapboxJavaGeoJSON : 'com.mapbox.mapboxsdk:mapbox-java-geojson:2.1.0@jar', - mapboxAndroidTelemetry : 'com.mapbox.mapboxsdk:mapbox-android-telemetry:2.1.0@aar', + mapboxJavaServices : "com.mapbox.mapboxsdk:mapbox-java-services:${mapboxServicesVersion}@jar", + mapboxJavaGeoJSON : "com.mapbox.mapboxsdk:mapbox-java-geojson:${mapboxServicesVersion}@jar", + mapboxAndroidTelemetry : "com.mapbox.mapboxsdk:mapbox-android-telemetry:${mapboxServicesVersion}@aar", // mapzen lost - lost : 'com.mapzen.android:lost:2.2.0', + lost : 'com.mapzen.android:lost:2.3.0-SNAPSHOT', // unit test junit : 'junit:junit:4.12', -- cgit v1.2.1 From cb737362b631284e1516561caf30c2027f9bdc03 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 12 May 2017 15:27:27 +0200 Subject: [android] - update proguard config, allow debug mimification, update OkHttp to latest version (#8944) --- platform/android/MapboxGLAndroidSDK/build.gradle | 4 +- .../android/MapboxGLAndroidSDK/proguard-rules.pro | 89 +--------------------- .../MapboxGLAndroidSDKTestApp/proguard-rules.pro | 1 + platform/android/dependencies.gradle | 2 +- 4 files changed, 9 insertions(+), 87 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/build.gradle b/platform/android/MapboxGLAndroidSDK/build.gradle index c4668f598c..fca36237c3 100644 --- a/platform/android/MapboxGLAndroidSDK/build.gradle +++ b/platform/android/MapboxGLAndroidSDK/build.gradle @@ -95,6 +95,9 @@ android { } } } + + // proguard config for .aar + consumerProguardFiles 'proguard-rules.pro' } // avoid naming conflicts, force usage of prefix @@ -122,7 +125,6 @@ android { release { // aar proguard configuration - consumerProguardFiles 'proguard-rules.pro' jniDebuggable false } } diff --git a/platform/android/MapboxGLAndroidSDK/proguard-rules.pro b/platform/android/MapboxGLAndroidSDK/proguard-rules.pro index baecd80e50..8e47815451 100644 --- a/platform/android/MapboxGLAndroidSDK/proguard-rules.pro +++ b/platform/android/MapboxGLAndroidSDK/proguard-rules.pro @@ -2,89 +2,8 @@ # in ../sdk/tools/proguard/proguard-android.txt, # contents of this file will be appended into proguard-android.txt -keepattributes Signature, *Annotation*, EnclosingMethod - -# Square okio, ignoring warnings, -# see https://github.com/square/okio/issues/60 --dontwarn okhttp3.** --dontwarn okio.** - -# Gesture package -keep class almeros.android.multitouch.gesturedetectors.** { *; } - -# Package annotations --keep class com.mapbox.mapboxsdk.annotations.** { *; } - -# Package camera --keep class com.mapbox.mapboxsdk.camera.** { *; } - -# Package geometry --keep class com.mapbox.mapboxsdk.geometry.** { *; } - -# Package http --keep class com.mapbox.mapboxsdk.http.** { *; } - -# Package maps --keep class com.mapbox.mapboxsdk.maps.** { *; } - -# Package net --keep class com.mapbox.mapboxsdk.net.** { *; } - -# Package offline --keep class com.mapbox.mapboxsdk.offline.** { *; } - -# Package storage --keep class com.mapbox.mapboxsdk.storage.** { *; } - -# Package style --keep class com.mapbox.mapboxsdk.style.layers.** { *; } --keep class com.mapbox.mapboxsdk.style.sources.** { *; } --keep class com.mapbox.mapboxsdk.style.functions.** { *; } - -# Package telemetry --keep class com.mapbox.mapboxsdk.telemetry.** { *; } - -# -# Mapbox-java Proguard rules -# We include these rules since libjava is a Jar file not AAR -# - -# Retrofit 2 -# Platform calls Class.forName on types which do not exist on Android to determine platform. --dontnote retrofit2.Platform -# Platform used when running on RoboVM on iOS. Will not be used at runtime. --dontnote retrofit2.Platform$IOS$MainThreadExecutor -# Platform used when running on Java 8 VMs. Will not be used at runtime. --dontwarn retrofit2.Platform$Java8 -# Retain generic type information for use by reflection by converters and adapters. --keepattributes Signature -# Retain declared checked exceptions for use by a Proxy instance. --keepattributes Exceptions - -# For using GSON @Expose annotation --keepattributes *Annotation* -# Gson specific classes --dontwarn sun.misc.** - -# Prevent proguard from stripping interface information from TypeAdapterFactory, -# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter) --keep class * implements com.google.gson.TypeAdapterFactory --keep class * implements com.google.gson.JsonSerializer --keep class * implements com.google.gson.JsonDeserializer - -# MAS Data Models --keep class com.mapbox.services.commons.geojson.** { *; } --keep class com.mapbox.services.mapmatching.v4.models.** { *; } --keep class com.mapbox.services.distance.v1.models.** { *; } --keep class com.mapbox.services.directions.v4.models.** { *; } --keep class com.mapbox.services.directions.v5.models.** { *; } --keep class com.mapbox.services.geocoding.v5.models.** { *; } - --dontwarn javax.annotation.** - --keepclassmembers class rx.internal.util.unsafe.** { - long producerIndex; - long consumerIndex; -} - --keep class com.google.** { *; } --dontwarn com.google.** \ No newline at end of file +-keep class com.mapbox.mapboxsdk.** { *; } +-keep interface com.mapbox.mapboxsdk.** { *; } +-keep class com.mapbox.services.android.telemetry.** { *; } +-keep class com.mapbox.services.commons.** { *;} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/proguard-rules.pro b/platform/android/MapboxGLAndroidSDKTestApp/proguard-rules.pro index 5d944b5dd4..f8243ca44f 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/proguard-rules.pro +++ b/platform/android/MapboxGLAndroidSDKTestApp/proguard-rules.pro @@ -4,5 +4,6 @@ -dontwarn org.codehaus.** -keep class com.google.** -dontwarn com.google.** +-dontwarn java.nio.** -keep class com.mapbox.mapboxsdk.testapp.model.customlayer.ExampleCustomLayer { *; } diff --git a/platform/android/dependencies.gradle b/platform/android/dependencies.gradle index 817697140e..bbf1fb075d 100644 --- a/platform/android/dependencies.gradle +++ b/platform/android/dependencies.gradle @@ -47,7 +47,7 @@ ext { // square crew timber : 'com.jakewharton.timber:timber:4.5.1', - okhttp3 : 'com.squareup.okhttp3:okhttp:3.6.0', + okhttp3 : 'com.squareup.okhttp3:okhttp:3.7.0', leakCanaryDebug : "com.squareup.leakcanary:leakcanary-android:${leakCanaryVersion}", leakCanaryRelease : "com.squareup.leakcanary:leakcanary-android-no-op:${leakCanaryVersion}", leakCanaryTest : "com.squareup.leakcanary:leakcanary-android-no-op:${leakCanaryVersion}" -- cgit v1.2.1 From 0ef1293dada1490c808ae821228d5a2f3324afdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Fri, 9 Sep 2016 10:17:42 -0700 Subject: [core, android, ios, macos, qt] v10 default styles Upgraded from v9 default styles to v10 wherever the developer expects to get the latest and greatest, as well as in a couple tests where it may be beneficial to ensure that we can handle a two-digit version number in the style URL. Cherry-picked from ed54849e9909e7f7cd8724b39b2bc94f16cf9a11. --- .../src/main/java/com/mapbox/mapboxsdk/constants/Style.java | 6 +++--- .../MapboxGLAndroidSDK/src/main/res/values/strings.xml | 6 +++--- .../src/main/res/layout/activity_multi_map.xml | 4 ++-- .../src/main/res/layout/fragment_dialog_map.xml | 2 +- .../src/main/res/layout/activity_simple_mapview.xml | 2 +- platform/darwin/src/MGLStyle.h | 2 +- platform/default/mbgl/util/default_styles.cpp | 12 ++++++------ platform/default/mbgl/util/default_styles.hpp | 2 +- platform/ios/CHANGELOG.md | 2 +- platform/macos/CHANGELOG.md | 1 + test/util/mapbox.test.cpp | 4 ++-- 11 files changed, 22 insertions(+), 21 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java index d55fd4c023..fae3bdde2c 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java @@ -35,13 +35,13 @@ public class Style { * constant means your map style will always use the latest version and may change as we * improve the style. */ - public static final String MAPBOX_STREETS = "mapbox://styles/mapbox/streets-v9"; + public static final String MAPBOX_STREETS = "mapbox://styles/mapbox/streets-v10"; /** * Outdoors: A general-purpose style tailored to outdoor activities. Using this constant means * your map style will always use the latest version and may change as we improve the style. */ - public static final String OUTDOORS = "mapbox://styles/mapbox/outdoors-v9"; + public static final String OUTDOORS = "mapbox://styles/mapbox/outdoors-v10"; /** * Light: Subtle light backdrop for data visualizations. Using this constant means your map @@ -66,5 +66,5 @@ public class Style { * constant means your map style will always use the latest version and may change as we * improve the style. */ - public static final String SATELLITE_STREETS = "mapbox://styles/mapbox/satellite-streets-v9"; + public static final String SATELLITE_STREETS = "mapbox://styles/mapbox/satellite-streets-v10"; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml index 0862305cfb..7adc29e2de 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml +++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml @@ -18,10 +18,10 @@ - mapbox://styles/mapbox/streets-v9 - mapbox://styles/mapbox/outdoors-v9 + mapbox://styles/mapbox/streets-v10 + mapbox://styles/mapbox/outdoors-v10 mapbox://styles/mapbox/light-v9 mapbox://styles/mapbox/dark-v9 mapbox://styles/mapbox/satellite-v9 - mapbox://styles/mapbox/satellite-streets-v9 + mapbox://styles/mapbox/satellite-streets-v10 diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_multi_map.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_multi_map.xml index 0b3fd9acdf..599ae3fa1c 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_multi_map.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_multi_map.xml @@ -23,7 +23,7 @@ android:layout_weight="0.5" mapbox:center_latitude="38.913187" mapbox:center_longitude="-77.032546" - mapbox:style_url="mapbox://styles/mapbox/streets-v9" + mapbox:style_url="mapbox://styles/mapbox/streets-v10" mapbox:zoom="12"/> @@ -35,7 +35,7 @@ android:layout_weight="0.5" mapbox:center_latitude="37.775732" mapbox:center_longitude="-122.413985" - mapbox:style_url="mapbox://styles/mapbox/outdoors-v9" + mapbox:style_url="mapbox://styles/mapbox/outdoors-v10" mapbox:zoom="13"/> diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/fragment_dialog_map.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/fragment_dialog_map.xml index 8241d0264f..afebfa1c47 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/fragment_dialog_map.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/fragment_dialog_map.xml @@ -13,6 +13,6 @@ mapbox:mapbox_cameraTargetLng="-122.3421" mapbox:mapbox_cameraZoom="11" mapbox:mapbox_renderTextureMode="true" - mapbox:mapbox_styleUrl="mapbox://styles/mapbox/streets-v9" /> + mapbox:mapbox_styleUrl="mapbox://styles/mapbox/streets-v10" /> diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/layout/activity_simple_mapview.xml b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/layout/activity_simple_mapview.xml index 8f260c46ff..44374f2c6c 100644 --- a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/layout/activity_simple_mapview.xml +++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/layout/activity_simple_mapview.xml @@ -15,7 +15,7 @@ android:layout_height="match_parent" mapbox:mapbox_cameraTargetLat="40.73581" mapbox:mapbox_cameraTargetLng="-73.99155" - mapbox:mapbox_styleUrl="mapbox://styles/mapbox/streets-v9" + mapbox:mapbox_styleUrl="mapbox://styles/mapbox/streets-v10" mapbox:mapbox_cameraZoom="11" mapbox:mapbox_uiZoomControls="false"/> diff --git a/platform/darwin/src/MGLStyle.h b/platform/darwin/src/MGLStyle.h index bd17fdec44..0e1403b114 100644 --- a/platform/darwin/src/MGLStyle.h +++ b/platform/darwin/src/MGLStyle.h @@ -28,7 +28,7 @@ NS_ASSUME_NONNULL_BEGIN the constant itself. Such details may change significantly from version to version. */ -static MGL_EXPORT const NSInteger MGLStyleDefaultVersion = 9; +static MGL_EXPORT const NSInteger MGLStyleDefaultVersion = 10; /** The proxy object for the current map style. diff --git a/platform/default/mbgl/util/default_styles.cpp b/platform/default/mbgl/util/default_styles.cpp index 17cc2f5740..5457d0f0a2 100644 --- a/platform/default/mbgl/util/default_styles.cpp +++ b/platform/default/mbgl/util/default_styles.cpp @@ -4,12 +4,12 @@ namespace mbgl { namespace util { namespace default_styles { -const DefaultStyle streets = { "mapbox://styles/mapbox/streets-v9", "Streets" }; -const DefaultStyle outdoors = { "mapbox://styles/mapbox/outdoors-v9", "Outdoors" }; -const DefaultStyle light = { "mapbox://styles/mapbox/light-v9", "Light" }; -const DefaultStyle dark = { "mapbox://styles/mapbox/dark-v9", "Dark" }; -const DefaultStyle satellite = { "mapbox://styles/mapbox/satellite-v9", "Satellite" }; -const DefaultStyle satelliteStreets = { "mapbox://styles/mapbox/satellite-streets-v9", "Satellite Streets" }; +const DefaultStyle streets = { "mapbox://styles/mapbox/streets-v10", "Streets" }; +const DefaultStyle outdoors = { "mapbox://styles/mapbox/outdoors-v10", "Outdoors" }; +const DefaultStyle light = { "mapbox://styles/mapbox/light-v9", "Light" }; +const DefaultStyle dark = { "mapbox://styles/mapbox/dark-v9", "Dark" }; +const DefaultStyle satellite = { "mapbox://styles/mapbox/satellite-v9", "Satellite" }; +const DefaultStyle satelliteStreets = { "mapbox://styles/mapbox/satellite-streets-v10", "Satellite Streets" }; } // namespace default_styles } // end namespace util diff --git a/platform/default/mbgl/util/default_styles.hpp b/platform/default/mbgl/util/default_styles.hpp index eb7e034722..32944394aa 100644 --- a/platform/default/mbgl/util/default_styles.hpp +++ b/platform/default/mbgl/util/default_styles.hpp @@ -24,7 +24,7 @@ const DefaultStyle orderedStyles[] = { }; const size_t numOrderedStyles = sizeof(orderedStyles) / sizeof(DefaultStyle); -static const unsigned currentVersion = 9; +static const unsigned currentVersion = 10; } // end namespace default_styles } // end namespace util diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index aa70346d70..e877613f1c 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -7,6 +7,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT ### Styles * Added support for 3D extrusion of buildings and other polygonal features via the `MGLFillExtrusionStyleLayer` class and the `fill-extrusion` layer type in style JSON. ([#8431](https://github.com/mapbox/mapbox-gl-native/pull/8431)) +* MGLMapView and MGLTilePyramidOfflineRegion now default to version 10 of the Mapbox Streets style. Similarly, several style URL class methods of MGLStyle return URLs to version 10 styles. ([#6301](https://github.com/mapbox/mapbox-gl-native/pull/6301)) * MGLSymbolStyleLayer’s `iconImageName`, `iconScale`, `textFontSize`, `textOffset`, and `textRotation` properties can now be set to a source or composite function. ([#8544](https://github.com/mapbox/mapbox-gl-native/pull/8544), [#8590](https://github.com/mapbox/mapbox-gl-native/pull/8590), [#8592](https://github.com/mapbox/mapbox-gl-native/pull/8592), [#8593](https://github.com/mapbox/mapbox-gl-native/pull/8593)) * Fixed an issue where setting the `MGLVectorStyleLayer.predicate` property failed to take effect if the relevant source was not in use by a visible layer at the time. ([#8653](https://github.com/mapbox/mapbox-gl-native/pull/8653)) * Fixed an issue causing a composite function’s highest zoom level stop to be misinterpreted. ([#8613](https://github.com/mapbox/mapbox-gl-native/pull/8613), [#8790](https://github.com/mapbox/mapbox-gl-native/pull/8790)) @@ -61,7 +62,6 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT ### Styles * Added support for data-driven styling in the form of source and composite style functions. `MGLStyleFunction` is now an abstract class, with `MGLCameraStyleFunction` providing the behavior of `MGLStyleFunction` in previous releases. New `MGLStyleFunction` subclasses allow you to vary a style attribute by the values of attributes of features in the source. ([#7596](https://github.com/mapbox/mapbox-gl-native/pull/7596)) -* Added methods to MGLShapeSource and MGLVectorSource for querying features loaded by the source, whether or not they’re visible on the map. ([#8263](https://github.com/mapbox/mapbox-gl-native/pull/8263)) * Added `circleStrokeColor`, `circleStrokeWidth`, and `circleStrokeOpacity` properties to MGLCircleStyleLayer and support for corresponding properties in style JSON files. ([#7356](https://github.com/mapbox/mapbox-gl-native/pull/7356)) * Point-placed labels in symbol style layers are now placed at more optimal locations within polygons. ([#7465](https://github.com/mapbox/mapbox-gl-native/pull/7465)) * Fixed flickering that occurred when manipulating a style layer. ([#7616](https://github.com/mapbox/mapbox-gl-native/pull/7616)) diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index d364bc9bf6..31315541a8 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -5,6 +5,7 @@ ### Styles * Added support for 3D extrusion of buildings and other polygonal features via the `MGLFillExtrusionStyleLayer` class and the `fill-extrusion` layer type in style JSON. ([#8431](https://github.com/mapbox/mapbox-gl-native/pull/8431)) +* MGLMapView and MGLTilePyramidOfflineRegion now default to version 10 of the Mapbox Streets style. Similarly, several style URL class methods of MGLStyle return URLs to version 10 styles. ([#6301](https://github.com/mapbox/mapbox-gl-native/pull/6301)) * MGLSymbolStyleLayer’s `iconImageName`, `iconScale`, `textFontSize`, `textOffset`, and `textRotation` properties can now be set to a source or composite function. ([#8544](https://github.com/mapbox/mapbox-gl-native/pull/8544), [#8590](https://github.com/mapbox/mapbox-gl-native/pull/8590), [#8592](https://github.com/mapbox/mapbox-gl-native/pull/8592), [#8593](https://github.com/mapbox/mapbox-gl-native/pull/8593)) * Fixed an issue where setting the `MGLVectorStyleLayer.predicate` property failed to take effect if the relevant source was not in use by a visible layer at the time. ([#8653](https://github.com/mapbox/mapbox-gl-native/pull/8653)) * Fixed an issue causing a composite function’s highest zoom level stop to be misinterpreted. ([#8613](https://github.com/mapbox/mapbox-gl-native/pull/8613), [#8790](https://github.com/mapbox/mapbox-gl-native/pull/8790)) diff --git a/test/util/mapbox.test.cpp b/test/util/mapbox.test.cpp index ba867ccb5c..cdbd85118f 100644 --- a/test/util/mapbox.test.cpp +++ b/test/util/mapbox.test.cpp @@ -91,9 +91,9 @@ TEST(Mapbox, SpriteURL) { "https://api.mapbox.com/styles/v1/mapbox/streets-v8/draft/sprite@2x.png?access_token=key", mbgl::util::mapbox::normalizeSpriteURL(util::API_BASE_URL, "mapbox://sprites/mapbox/streets-v8/draft@2x.png", "key")); EXPECT_EQ( - "https://api.mapbox.com/styles/v1/mapbox/streets-v9/sprite?access_token=key&fresh=true.png", + "https://api.mapbox.com/styles/v1/mapbox/streets-v10/sprite?access_token=key&fresh=true.png", mbgl::util::mapbox::normalizeSpriteURL(util::API_BASE_URL, - "mapbox://sprites/mapbox/streets-v9?fresh=true.png", + "mapbox://sprites/mapbox/streets-v10?fresh=true.png", "key")); EXPECT_EQ("mapbox://////", mbgl::util::mapbox::normalizeSpriteURL(util::API_BASE_URL, "mapbox://////", "key")); } -- cgit v1.2.1 From d85471b7deb9c57973f9b70e0dfe4a8f386c8a01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Fri, 9 Sep 2016 10:29:45 -0700 Subject: [ios, macos] Updated documented default style version MGLStyleDefaultVersion is just for Streets now. Deleted style version documentation tests because not all styles are on the same version. Cherry-picked from ca97dd8cf4c70a5ed380c99700749fd3239715f0. --- platform/darwin/src/MGLStyle.h | 12 ++++++------ platform/darwin/test/MGLStyleTests.mm | 13 ------------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/platform/darwin/src/MGLStyle.h b/platform/darwin/src/MGLStyle.h index 0e1403b114..ab5a20686a 100644 --- a/platform/darwin/src/MGLStyle.h +++ b/platform/darwin/src/MGLStyle.h @@ -10,9 +10,9 @@ NS_ASSUME_NONNULL_BEGIN /** - A version number identifying the default version of the suite of default styles - provided by Mapbox. This version number may be passed into one of the - “StyleURLWithVersion” class methods of MGLStyle. + A version number identifying the default version of the Mapbox Streets style + obtained through the `-streetsStyleURL` method. This version number may also be + passed into the `-streetsStyleURLWithVersion:` method. The value of this constant generally corresponds to the latest released version as of the date on which this SDK was published. You can use this constant to @@ -72,7 +72,7 @@ MGL_EXPORT is specified explicitly. @param version The style’s latest released version. As of publication, the - current version is `9`. + current version is `10`. */ + (NSURL *)streetsStyleURLWithVersion:(NSInteger)version; @@ -91,7 +91,7 @@ MGL_EXPORT Outdoors is a general-purpose style tailored to outdoor activities. @param version The style’s latest released version. As of publication, the - current version is `9`. + current version is `10`. */ + (NSURL *)outdoorsStyleURLWithVersion:(NSInteger)version; @@ -173,7 +173,7 @@ MGL_EXPORT Streets. @param version The style’s latest released version. As of publication, the - current version is `9`. + current version is `10`. */ + (NSURL *)satelliteStreetsStyleURLWithVersion:(NSInteger)version; diff --git a/platform/darwin/test/MGLStyleTests.mm b/platform/darwin/test/MGLStyleTests.mm index f9598a143d..8681bddc46 100644 --- a/platform/darwin/test/MGLStyleTests.mm +++ b/platform/darwin/test/MGLStyleTests.mm @@ -119,19 +119,6 @@ XCTAssertNil(versionedMethodError, @"Error compiling regular expression to search for versioned methods."); NSUInteger numVersionedMethodDeclarations = [versionedMethodExpression numberOfMatchesInString:styleHeader options:0 range:NSMakeRange(0, styleHeader.length)]; XCTAssertEqual(numVersionedMethodDeclarations, numVersionedMethods); - - // Test that “current version is” statements are present and current for all versioned style methods. - NSError *versionError; - NSString *versionExpressionString = @(R"RE(current version is `(\d+)`)RE"); - NSRegularExpression *versionExpression = [NSRegularExpression regularExpressionWithPattern:versionExpressionString options:0 error:&versionError]; - XCTAssertNil(versionError, @"Error compiling regular expression to search for current version statements."); - NSUInteger numVersionDeclarations = [versionExpression numberOfMatchesInString:styleHeader options:0 range:NSMakeRange(0, styleHeader.length)]; - XCTAssertEqual(numVersionDeclarations, numVersionedMethods); - [versionExpression enumerateMatchesInString:styleHeader options:0 range:NSMakeRange(0, styleHeader.length) usingBlock:^(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL * _Nonnull stop) { - XCTAssertEqual(result.numberOfRanges, 2, @"Regular expression should have one capture group."); - NSString *version = [styleHeader substringWithRange:[result rangeAtIndex:1]]; - XCTAssertEqual([version integerValue], MGLStyleDefaultVersion, @"Versioned style URL method should document current version as %ld, not %ld.", MGLStyleDefaultVersion, version.integerValue); - }]; } - (void)testName { -- cgit v1.2.1 From c5ee41a93a1f012acf41f29dc8bd75dc736ff4bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Tue, 25 Apr 2017 20:52:47 -0400 Subject: [ios, macos] Undeprecated unversioned style URL factory methods Undeprecated the unversioned style URL factory methods in MGLStyle for consistency with the Android and Qt SDKs. Added warnings about using them with the runtime styling API. Refactored mbgl::util::default_styles to track different versions for different styles. Cherry-picked from 9e384b78fbcf46d66d390122eefdf273f91b314e. --- platform/darwin/src/MGLStyle.h | 104 +++++++++++++++++++------- platform/darwin/src/MGLStyle.mm | 10 +-- platform/darwin/test/MGLStyleTests.mm | 50 +++++++++---- platform/default/mbgl/util/default_styles.cpp | 12 +-- platform/default/mbgl/util/default_styles.hpp | 3 +- platform/ios/CHANGELOG.md | 2 +- platform/macos/CHANGELOG.md | 2 +- 7 files changed, 124 insertions(+), 59 deletions(-) diff --git a/platform/darwin/src/MGLStyle.h b/platform/darwin/src/MGLStyle.h index ab5a20686a..49898a1863 100644 --- a/platform/darwin/src/MGLStyle.h +++ b/platform/darwin/src/MGLStyle.h @@ -52,15 +52,22 @@ MGL_EXPORT #pragma mark Accessing Default Styles /** - Returns the URL to version 8 of the - Mapbox Streets style. + Returns the URL to the current version of the + Mapbox Streets style as of + publication. Streets is a general-purpose style with detailed road and transit networks. `MGLMapView` and `MGLTilePyramidOfflineRegion` use Mapbox Streets when no style is specified explicitly. + + @warning The return value may change in a future release of the SDK. If you use + any feature that depends on a specific aspect of a default style – for + instance, the minimum zoom level that includes roads – use the + `-streetsStyleURLWithVersion:` method instead. Such details may change + significantly from version to version. */ -+ (NSURL *)streetsStyleURL __attribute__((deprecated("Use -streetsStyleURLWithVersion:."))); ++ (NSURL *)streetsStyleURL; /** Returns the URL to the given version of the @@ -71,8 +78,7 @@ MGL_EXPORT `MGLMapView` and `MGLTilePyramidOfflineRegion` use Mapbox Streets when no style is specified explicitly. - @param version The style’s latest released version. As of publication, the - current version is `10`. + @param version A specific version of the style. */ + (NSURL *)streetsStyleURLWithVersion:(NSInteger)version; @@ -84,71 +90,103 @@ MGL_EXPORT */ + (NSURL *)emeraldStyleURL __attribute__((deprecated("Create an NSURL object with the string “mapbox://styles/mapbox/emerald-v8”."))); +/** + Returns the URL to the current version of the + Mapbox Outdoors style as of + publication. + + Outdoors is a general-purpose style tailored to outdoor activities. + + @warning The return value may change in a future release of the SDK. If you use + any feature that depends on a specific aspect of a default style – for + instance, the minimum zoom level that includes roads – use the + `-outdoorsStyleURLWithVersion:` method instead. Such details may change + significantly from version to version. + */ ++ (NSURL *)outdoorsStyleURL; + /** Returns the URL to the given version of the Mapbox Outdoors style. Outdoors is a general-purpose style tailored to outdoor activities. - @param version The style’s latest released version. As of publication, the - current version is `10`. + @param version A specific version of the style. */ + (NSURL *)outdoorsStyleURLWithVersion:(NSInteger)version; /** - Returns the URL to version 8 of the + Returns the URL to the current version of the Mapbox Light style. Light is a subtle, light-colored backdrop for data visualizations. + + @warning The return value may change in a future release of the SDK. If you use + any feature that depends on a specific aspect of a default style – for + instance, the minimum zoom level that includes roads – use the + `-lightStyleURLWithVersion:` method instead. Such details may change + significantly from version to version. */ -+ (NSURL *)lightStyleURL __attribute__((deprecated("Use -lightStyleURLWithVersion:."))); ++ (NSURL *)lightStyleURL; /** Returns the URL to the given version of the - Mapbox Light style. + Mapbox Light style as of + publication. Light is a subtle, light-colored backdrop for data visualizations. - @param version The style’s latest released version. As of publication, the - current version is `9`. + @param version A specific version of the style. */ + (NSURL *)lightStyleURLWithVersion:(NSInteger)version; /** - Returns the URL to version 8 of the + Returns the URL to the current version of the Mapbox Dark style. Dark is a subtle, dark-colored backdrop for data visualizations. + + @warning The return value may change in a future release of the SDK. If you use + any feature that depends on a specific aspect of a default style – for + instance, the minimum zoom level that includes roads – use the + `-darkStyleURLWithVersion:` method instead. Such details may change + significantly from version to version. */ -+ (NSURL *)darkStyleURL __attribute__((deprecated("Use -darkStyleURLWithVersion:."))); ++ (NSURL *)darkStyleURL; /** Returns the URL to the given version of the - Mapbox Dark style. + Mapbox Dark style as of + publication. Dark is a subtle, dark-colored backdrop for data visualizations. - @param version The style’s latest released version. As of publication, the - current version is `9`. + @param version A specific version of the style. */ + (NSURL *)darkStyleURLWithVersion:(NSInteger)version; /** - Returns the URL to version 8 of the + Returns the URL to the current version of the Mapbox Satellite style. Satellite is high-resolution satellite and aerial imagery. + + @warning The return value may change in a future release of the SDK. If you use + any feature that depends on a specific aspect of a default style – for + instance, the raster tile sets included in the style – use the + `-satelliteStyleURLWithVersion:` method instead. Such details may change + significantly from version to version. */ -+ (NSURL *)satelliteStyleURL __attribute__((deprecated("Use -satelliteStyleURLWithVersion:."))); ++ (NSURL *)satelliteStyleURL; /** Returns the URL to the given version of the - Mapbox Satellite style. + Mapbox Satellite style as + of publication. Satellite is high-resolution satellite and aerial imagery. - @param version The style’s latest released version. As of publication, the - current version is `9`. + @param version A specific version of the style. */ + (NSURL *)satelliteStyleURLWithVersion:(NSInteger)version; @@ -161,7 +199,24 @@ MGL_EXPORT Mapbox Satellite with unobtrusive labels and translucent roads from Mapbox Streets. */ -+ (NSURL *)hybridStyleURL __attribute__((deprecated("Use -satelliteStreetsStyleURLWithVersion:."))); ++ (NSURL *)hybridStyleURL __attribute__((deprecated("Use -satelliteStreetsStyleURL."))); + +/** + Returns the URL to the current version of the + Mapbox Satellite Streets + style as of publication. + + Satellite Streets combines the high-resolution satellite and aerial imagery of + Mapbox Satellite with unobtrusive labels and translucent roads from Mapbox + Streets. + + @warning The return value may change in a future release of the SDK. If you use + any feature that depends on a specific aspect of a default style – for + instance, the minimum zoom level that includes roads – use the + `-satelliteStreetsStyleURLWithVersion:` method instead. Such details may + change significantly from version to version. + */ ++ (NSURL *)satelliteStreetsStyleURL; /** Returns the URL to the given version of the @@ -172,8 +227,7 @@ MGL_EXPORT Mapbox Satellite with unobtrusive labels and translucent roads from Mapbox Streets. - @param version The style’s latest released version. As of publication, the - current version is `10`. + @param version A specific version of the style. */ + (NSURL *)satelliteStreetsStyleURLWithVersion:(NSInteger)version; diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm index 81b6446e7f..ce9e55bb99 100644 --- a/platform/darwin/src/MGLStyle.mm +++ b/platform/darwin/src/MGLStyle.mm @@ -58,8 +58,6 @@ #pragma mark Default style URLs -static_assert(mbgl::util::default_styles::currentVersion == MGLStyleDefaultVersion, "mbgl::util::default_styles::currentVersion and MGLStyleDefaultVersion disagree."); - /// @param name The style’s marketing name, written in lower camelCase. /// @param fileName The last path component in the style’s URL, excluding the version suffix. #define MGL_DEFINE_STYLE(name, fileName) \ @@ -67,17 +65,13 @@ static_assert(mbgl::util::default_styles::currentVersion == MGLStyleDefaultVersi + (NSURL *)name##StyleURL { \ static dispatch_once_t onceToken; \ dispatch_once(&onceToken, ^{ \ - MGLStyleURL_##name = [self name##StyleURLWithVersion:8]; \ + MGLStyleURL_##name = [self name##StyleURLWithVersion:mbgl::util::default_styles::name.currentVersion]; \ }); \ return MGLStyleURL_##name; \ } \ \ + (NSURL *)name##StyleURL##WithVersion:(NSInteger)version { \ - if (mbgl::util::default_styles::currentVersion == version) { \ - return [NSURL URLWithString:@(mbgl::util::default_styles::name.url)]; \ - } else { \ - return [NSURL URLWithString:[@"mapbox://styles/mapbox/" #fileName "-v" stringByAppendingFormat:@"%li", (long)version]]; \ - } \ + return [NSURL URLWithString:[@"mapbox://styles/mapbox/" #fileName "-v" stringByAppendingFormat:@"%li", (long)version]]; \ } MGL_DEFINE_STYLE(streets, streets) diff --git a/platform/darwin/test/MGLStyleTests.mm b/platform/darwin/test/MGLStyleTests.mm index 8681bddc46..a2ad1cbb3f 100644 --- a/platform/darwin/test/MGLStyleTests.mm +++ b/platform/darwin/test/MGLStyleTests.mm @@ -55,13 +55,19 @@ } - (void)testUnversionedStyleURLs { + XCTAssertEqual(mbgl::util::default_styles::streets.currentVersion, MGLStyleDefaultVersion, + "mbgl::util::default_styles::streets.currentVersion and MGLStyleDefaultVersion disagree."); + + XCTAssertEqualObjects([MGLStyle streetsStyleURL].absoluteString, @(mbgl::util::default_styles::streets.url)); + XCTAssertEqualObjects([MGLStyle outdoorsStyleURL].absoluteString, @(mbgl::util::default_styles::outdoors.url)); + XCTAssertEqualObjects([MGLStyle lightStyleURL].absoluteString, @(mbgl::util::default_styles::light.url)); + XCTAssertEqualObjects([MGLStyle darkStyleURL].absoluteString, @(mbgl::util::default_styles::dark.url)); + XCTAssertEqualObjects([MGLStyle satelliteStyleURL].absoluteString, @(mbgl::util::default_styles::satellite.url)); + XCTAssertEqualObjects([MGLStyle satelliteStreetsStyleURL].absoluteString, @(mbgl::util::default_styles::satelliteStreets.url)); + #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - XCTAssertEqualObjects([MGLStyle streetsStyleURL].absoluteString, @"mapbox://styles/mapbox/streets-v8"); XCTAssertEqualObjects([MGLStyle emeraldStyleURL].absoluteString, @"mapbox://styles/mapbox/emerald-v8"); - XCTAssertEqualObjects([MGLStyle lightStyleURL].absoluteString, @"mapbox://styles/mapbox/light-v8"); - XCTAssertEqualObjects([MGLStyle darkStyleURL].absoluteString, @"mapbox://styles/mapbox/dark-v8"); - XCTAssertEqualObjects([MGLStyle satelliteStyleURL].absoluteString, @"mapbox://styles/mapbox/satellite-v8"); XCTAssertEqualObjects([MGLStyle hybridStyleURL].absoluteString, @"mapbox://styles/mapbox/satellite-hybrid-v8"); #pragma clang diagnostic pop } @@ -69,18 +75,30 @@ - (void)testVersionedStyleURLs { // Test that all the default styles have publicly-declared MGLStyle class // methods and that the URLs all have the right values. - XCTAssertEqualObjects([MGLStyle streetsStyleURLWithVersion:MGLStyleDefaultVersion].absoluteString, @(mbgl::util::default_styles::streets.url)); - XCTAssertEqualObjects([MGLStyle streetsStyleURLWithVersion:99].absoluteString, @"mapbox://styles/mapbox/streets-v99"); - XCTAssertEqualObjects([MGLStyle outdoorsStyleURLWithVersion:MGLStyleDefaultVersion].absoluteString, @(mbgl::util::default_styles::outdoors.url)); - XCTAssertEqualObjects([MGLStyle outdoorsStyleURLWithVersion:99].absoluteString, @"mapbox://styles/mapbox/outdoors-v99"); - XCTAssertEqualObjects([MGLStyle lightStyleURLWithVersion:MGLStyleDefaultVersion].absoluteString, @(mbgl::util::default_styles::light.url)); - XCTAssertEqualObjects([MGLStyle lightStyleURLWithVersion:99].absoluteString, @"mapbox://styles/mapbox/light-v99"); - XCTAssertEqualObjects([MGLStyle darkStyleURLWithVersion:MGLStyleDefaultVersion].absoluteString, @(mbgl::util::default_styles::dark.url)); - XCTAssertEqualObjects([MGLStyle darkStyleURLWithVersion:99].absoluteString, @"mapbox://styles/mapbox/dark-v99"); - XCTAssertEqualObjects([MGLStyle satelliteStyleURLWithVersion:MGLStyleDefaultVersion].absoluteString, @(mbgl::util::default_styles::satellite.url)); - XCTAssertEqualObjects([MGLStyle satelliteStyleURLWithVersion:99].absoluteString, @"mapbox://styles/mapbox/satellite-v99"); - XCTAssertEqualObjects([MGLStyle satelliteStreetsStyleURLWithVersion:MGLStyleDefaultVersion].absoluteString, @(mbgl::util::default_styles::satelliteStreets.url)); - XCTAssertEqualObjects([MGLStyle satelliteStreetsStyleURLWithVersion:99].absoluteString, @"mapbox://styles/mapbox/satellite-streets-v99"); + XCTAssertEqualObjects([MGLStyle streetsStyleURLWithVersion:mbgl::util::default_styles::streets.currentVersion].absoluteString, + @(mbgl::util::default_styles::streets.url)); + XCTAssertEqualObjects([MGLStyle streetsStyleURLWithVersion:99].absoluteString, + @"mapbox://styles/mapbox/streets-v99"); + XCTAssertEqualObjects([MGLStyle outdoorsStyleURLWithVersion:mbgl::util::default_styles::outdoors.currentVersion].absoluteString, + @(mbgl::util::default_styles::outdoors.url)); + XCTAssertEqualObjects([MGLStyle outdoorsStyleURLWithVersion:99].absoluteString, + @"mapbox://styles/mapbox/outdoors-v99"); + XCTAssertEqualObjects([MGLStyle lightStyleURLWithVersion:mbgl::util::default_styles::light.currentVersion].absoluteString, + @(mbgl::util::default_styles::light.url)); + XCTAssertEqualObjects([MGLStyle lightStyleURLWithVersion:99].absoluteString, + @"mapbox://styles/mapbox/light-v99"); + XCTAssertEqualObjects([MGLStyle darkStyleURLWithVersion:mbgl::util::default_styles::dark.currentVersion].absoluteString, + @(mbgl::util::default_styles::dark.url)); + XCTAssertEqualObjects([MGLStyle darkStyleURLWithVersion:99].absoluteString, + @"mapbox://styles/mapbox/dark-v99"); + XCTAssertEqualObjects([MGLStyle satelliteStyleURLWithVersion:mbgl::util::default_styles::satellite.currentVersion].absoluteString, + @(mbgl::util::default_styles::satellite.url)); + XCTAssertEqualObjects([MGLStyle satelliteStyleURLWithVersion:99].absoluteString, + @"mapbox://styles/mapbox/satellite-v99"); + XCTAssertEqualObjects([MGLStyle satelliteStreetsStyleURLWithVersion:mbgl::util::default_styles::satelliteStreets.currentVersion].absoluteString, + @(mbgl::util::default_styles::satelliteStreets.url)); + XCTAssertEqualObjects([MGLStyle satelliteStreetsStyleURLWithVersion:99].absoluteString, + @"mapbox://styles/mapbox/satellite-streets-v99"); static_assert(6 == mbgl::util::default_styles::numOrderedStyles, "MGLStyleTests isn’t testing all the styles in mbgl::util::default_styles."); diff --git a/platform/default/mbgl/util/default_styles.cpp b/platform/default/mbgl/util/default_styles.cpp index 5457d0f0a2..e051817ada 100644 --- a/platform/default/mbgl/util/default_styles.cpp +++ b/platform/default/mbgl/util/default_styles.cpp @@ -4,12 +4,12 @@ namespace mbgl { namespace util { namespace default_styles { -const DefaultStyle streets = { "mapbox://styles/mapbox/streets-v10", "Streets" }; -const DefaultStyle outdoors = { "mapbox://styles/mapbox/outdoors-v10", "Outdoors" }; -const DefaultStyle light = { "mapbox://styles/mapbox/light-v9", "Light" }; -const DefaultStyle dark = { "mapbox://styles/mapbox/dark-v9", "Dark" }; -const DefaultStyle satellite = { "mapbox://styles/mapbox/satellite-v9", "Satellite" }; -const DefaultStyle satelliteStreets = { "mapbox://styles/mapbox/satellite-streets-v10", "Satellite Streets" }; +const DefaultStyle streets = { "mapbox://styles/mapbox/streets-v10", "Streets", 10 }; +const DefaultStyle outdoors = { "mapbox://styles/mapbox/outdoors-v10", "Outdoors", 10 }; +const DefaultStyle light = { "mapbox://styles/mapbox/light-v9", "Light", 9 }; +const DefaultStyle dark = { "mapbox://styles/mapbox/dark-v9", "Dark", 9 }; +const DefaultStyle satellite = { "mapbox://styles/mapbox/satellite-v9", "Satellite", 9 }; +const DefaultStyle satelliteStreets = { "mapbox://styles/mapbox/satellite-streets-v10", "Satellite Streets", 10 }; } // namespace default_styles } // end namespace util diff --git a/platform/default/mbgl/util/default_styles.hpp b/platform/default/mbgl/util/default_styles.hpp index 32944394aa..5e0d083d82 100644 --- a/platform/default/mbgl/util/default_styles.hpp +++ b/platform/default/mbgl/util/default_styles.hpp @@ -10,6 +10,7 @@ namespace default_styles { struct DefaultStyle { const char* url; const char* name; + const unsigned currentVersion; }; extern const DefaultStyle streets; @@ -24,8 +25,6 @@ const DefaultStyle orderedStyles[] = { }; const size_t numOrderedStyles = sizeof(orderedStyles) / sizeof(DefaultStyle); -static const unsigned currentVersion = 10; - } // end namespace default_styles } // end namespace util } // end namespace mbgl diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index e877613f1c..b975030b1b 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -7,7 +7,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT ### Styles * Added support for 3D extrusion of buildings and other polygonal features via the `MGLFillExtrusionStyleLayer` class and the `fill-extrusion` layer type in style JSON. ([#8431](https://github.com/mapbox/mapbox-gl-native/pull/8431)) -* MGLMapView and MGLTilePyramidOfflineRegion now default to version 10 of the Mapbox Streets style. Similarly, several style URL class methods of MGLStyle return URLs to version 10 styles. ([#6301](https://github.com/mapbox/mapbox-gl-native/pull/6301)) +* MGLMapView and MGLTilePyramidOfflineRegion now default to version 10 of the Mapbox Streets style. Similarly, several style URL class methods of MGLStyle return URLs to version 10 styles. Unversioned variations of these methods are no longer deprecated. `MGLStyleDefaultVersion` should no longer be used with any style other than Streets. ([#6301](https://github.com/mapbox/mapbox-gl-native/pull/6301)) * MGLSymbolStyleLayer’s `iconImageName`, `iconScale`, `textFontSize`, `textOffset`, and `textRotation` properties can now be set to a source or composite function. ([#8544](https://github.com/mapbox/mapbox-gl-native/pull/8544), [#8590](https://github.com/mapbox/mapbox-gl-native/pull/8590), [#8592](https://github.com/mapbox/mapbox-gl-native/pull/8592), [#8593](https://github.com/mapbox/mapbox-gl-native/pull/8593)) * Fixed an issue where setting the `MGLVectorStyleLayer.predicate` property failed to take effect if the relevant source was not in use by a visible layer at the time. ([#8653](https://github.com/mapbox/mapbox-gl-native/pull/8653)) * Fixed an issue causing a composite function’s highest zoom level stop to be misinterpreted. ([#8613](https://github.com/mapbox/mapbox-gl-native/pull/8613), [#8790](https://github.com/mapbox/mapbox-gl-native/pull/8790)) diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index 31315541a8..298cc8ecfc 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -5,7 +5,7 @@ ### Styles * Added support for 3D extrusion of buildings and other polygonal features via the `MGLFillExtrusionStyleLayer` class and the `fill-extrusion` layer type in style JSON. ([#8431](https://github.com/mapbox/mapbox-gl-native/pull/8431)) -* MGLMapView and MGLTilePyramidOfflineRegion now default to version 10 of the Mapbox Streets style. Similarly, several style URL class methods of MGLStyle return URLs to version 10 styles. ([#6301](https://github.com/mapbox/mapbox-gl-native/pull/6301)) +* MGLMapView and MGLTilePyramidOfflineRegion now default to version 10 of the Mapbox Streets style. Similarly, several style URL class methods of MGLStyle return URLs to version 10 styles. Unversioned variations of these methods are no longer deprecated. `MGLStyleDefaultVersion` should no longer be used with any style other than Streets. ([#6301](https://github.com/mapbox/mapbox-gl-native/pull/6301)) * MGLSymbolStyleLayer’s `iconImageName`, `iconScale`, `textFontSize`, `textOffset`, and `textRotation` properties can now be set to a source or composite function. ([#8544](https://github.com/mapbox/mapbox-gl-native/pull/8544), [#8590](https://github.com/mapbox/mapbox-gl-native/pull/8590), [#8592](https://github.com/mapbox/mapbox-gl-native/pull/8592), [#8593](https://github.com/mapbox/mapbox-gl-native/pull/8593)) * Fixed an issue where setting the `MGLVectorStyleLayer.predicate` property failed to take effect if the relevant source was not in use by a visible layer at the time. ([#8653](https://github.com/mapbox/mapbox-gl-native/pull/8653)) * Fixed an issue causing a composite function’s highest zoom level stop to be misinterpreted. ([#8613](https://github.com/mapbox/mapbox-gl-native/pull/8613), [#8790](https://github.com/mapbox/mapbox-gl-native/pull/8790)) -- cgit v1.2.1 From 886bf2528ff1615a50521e75fc6ea211cef3b8d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Mon, 8 May 2017 17:45:22 -0700 Subject: [core, android, ios, macos] Added Traffic Day/Night to default styles The Styles API section of the Mapbox API Documentation site now lists Traffic Day v2 and Traffic Night v2, so this change adds those styles to all the places where styles are listed. Also switched iosapp and macosapp to unversioned style factory methods since MGLStyleDefaultVersion is no longer applicable for all styles. Cherry-picked from 4d6f54553d277c0af24a0b8ff03d2dd7e9284ca2. --- platform/android/CHANGELOG.md | 1 + .../java/com/mapbox/mapboxsdk/constants/Style.java | 20 ++++++- .../src/main/res/values/strings.xml | 2 + platform/darwin/src/MGLStyle.h | 62 ++++++++++++++++++++++ platform/darwin/src/MGLStyle.mm | 4 +- platform/darwin/test/MGLStyleTests.mm | 12 ++++- platform/default/mbgl/util/default_styles.cpp | 2 + platform/default/mbgl/util/default_styles.hpp | 3 ++ platform/ios/CHANGELOG.md | 1 + platform/ios/app/MBXViewController.m | 16 +++--- platform/macos/CHANGELOG.md | 1 + platform/macos/app/Base.lproj/MainMenu.xib | 22 +++++--- platform/macos/app/Base.lproj/MapDocument.xib | 16 ++++-- platform/macos/app/MapDocument.m | 47 +++++++++------- 14 files changed, 170 insertions(+), 39 deletions(-) diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md index 4f12907f38..fdc6343b7c 100644 --- a/platform/android/CHANGELOG.md +++ b/platform/android/CHANGELOG.md @@ -37,6 +37,7 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to * Derived source attribution [#8630](https://github.com/mapbox/mapbox-gl-native/pull/8630) * Consistent use of duration unit [#8578](https://github.com/mapbox/mapbox-gl-native/pull/8578) * Swedish localization [#8883](https://github.com/mapbox/mapbox-gl-native/pull/8883) +* Streets v10, Outdoors v10, Satellite Streets v10, Traffic Day v2, Traffic Night v2 [#6301](https://github.com/mapbox/mapbox-gl-native/pull/6301) ## 5.0.2 - April 3, 2017 diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java index fae3bdde2c..77d0929df3 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java @@ -23,7 +23,7 @@ public class Style { * constants means your map style will always use the latest version and may change as we * improve the style */ - @StringDef( {MAPBOX_STREETS, OUTDOORS, LIGHT, DARK, SATELLITE, SATELLITE_STREETS}) + @StringDef( {MAPBOX_STREETS, OUTDOORS, LIGHT, DARK, SATELLITE, SATELLITE_STREETS, TRAFFIC_DAY, TRAFFIC_NIGHT}) @Retention(RetentionPolicy.SOURCE) public @interface StyleUrl { } @@ -67,4 +67,22 @@ public class Style { * improve the style. */ public static final String SATELLITE_STREETS = "mapbox://styles/mapbox/satellite-streets-v10"; + + /** + * Traffic Day: Color-coded roads based on live traffic congestion data. Traffic data is currently + * available in + * these select + * countries. Using this constant means your map style will always use the latest version and + * may change as we improve the style. + */ + public static final String TRAFFIC_DAY = "mapbox://styles/mapbox/traffic-day-v2"; + + /** + * Traffic Night: Color-coded roads based on live traffic congestion data, designed to maximize + * legibility in low-light situations. Traffic data is currently available in + * these select + * countries. Using this constant means your map style will always use the latest version and + * may change as we improve the style. + */ + public static final String TRAFFIC_NIGHT = "mapbox://styles/mapbox/traffic-night-v2"; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml index 7adc29e2de..65fb3e14a3 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml +++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml @@ -24,4 +24,6 @@ mapbox://styles/mapbox/dark-v9 mapbox://styles/mapbox/satellite-v9 mapbox://styles/mapbox/satellite-streets-v10 + mapbox://styles/mapbox/traffic-day-v2 + mapbox://styles/mapbox/traffic-night-v2 diff --git a/platform/darwin/src/MGLStyle.h b/platform/darwin/src/MGLStyle.h index 49898a1863..26434eb492 100644 --- a/platform/darwin/src/MGLStyle.h +++ b/platform/darwin/src/MGLStyle.h @@ -231,6 +231,68 @@ MGL_EXPORT */ + (NSURL *)satelliteStreetsStyleURLWithVersion:(NSInteger)version; +/** + Returns the URL to the current version of the + Mapbox Traffic Day + style. + + Traffic Day color-codes roads based on live traffic congestion data. Traffic + data is currently available in + these select countries. + + @warning The return value may change in a future release of the SDK. If you use + any feature that depends on a specific aspect of a default style – for + instance, the minimum zoom level that includes roads – use the + `-trafficDayStyleURLWithVersion:` method instead. Such details may change + significantly from version to version. + */ ++ (NSURL *)trafficDayStyleURL; + +/** + Returns the URL to the given version of the + Mapbox Traffic Day + style as of publication. + + Traffic Day color-codes roads based on live traffic congestion data. Traffic + data is currently available in + these select countries. + + @param version A specific version of the style. + */ ++ (NSURL *)trafficDayStyleURLWithVersion:(NSInteger)version; + +/** + Returns the URL to the current version of the + Mapbox Traffic Night + style. + + Traffic Night color-codes roads based on live traffic congestion data and is + designed to maximize legibility in low-light situations. Traffic data is + currently available in + these select countries. + + @warning The return value may change in a future release of the SDK. If you use + any feature that depends on a specific aspect of a default style – for + instance, the minimum zoom level that includes roads – use the + `-trafficNightStyleURLWithVersion:` method instead. Such details may change + significantly from version to version. + */ ++ (NSURL *)trafficNightStyleURL; + +/** + Returns the URL to the given version of the + Mapbox Traffic Night + style as of publication. + + Traffic Night color-codes roads based on live traffic congestion data and is + designed to maximize legibility in low-light situations. Traffic data is + currently available in + these select countries. + + @param version A specific version of the style. + */ ++ (NSURL *)trafficNightStyleURLWithVersion:(NSInteger)version; + #pragma mark Accessing Metadata About the Style /** diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm index ce9e55bb99..af02c31b6d 100644 --- a/platform/darwin/src/MGLStyle.mm +++ b/platform/darwin/src/MGLStyle.mm @@ -80,10 +80,12 @@ MGL_DEFINE_STYLE(light, light) MGL_DEFINE_STYLE(dark, dark) MGL_DEFINE_STYLE(satellite, satellite) MGL_DEFINE_STYLE(satelliteStreets, satellite-streets) +MGL_DEFINE_STYLE(trafficDay, traffic-day) +MGL_DEFINE_STYLE(trafficNight, traffic-night) // Make sure all the styles listed in mbgl::util::default_styles::orderedStyles // are defined above and also declared in MGLStyle.h. -static_assert(6 == mbgl::util::default_styles::numOrderedStyles, +static_assert(8 == mbgl::util::default_styles::numOrderedStyles, "mbgl::util::default_styles::orderedStyles and MGLStyle have different numbers of styles."); // Hybrid has been renamed Satellite Streets, so the last Hybrid version is hard-coded here. diff --git a/platform/darwin/test/MGLStyleTests.mm b/platform/darwin/test/MGLStyleTests.mm index a2ad1cbb3f..f80d5776f0 100644 --- a/platform/darwin/test/MGLStyleTests.mm +++ b/platform/darwin/test/MGLStyleTests.mm @@ -99,8 +99,16 @@ @(mbgl::util::default_styles::satelliteStreets.url)); XCTAssertEqualObjects([MGLStyle satelliteStreetsStyleURLWithVersion:99].absoluteString, @"mapbox://styles/mapbox/satellite-streets-v99"); - - static_assert(6 == mbgl::util::default_styles::numOrderedStyles, + XCTAssertEqualObjects([MGLStyle trafficDayStyleURLWithVersion:mbgl::util::default_styles::trafficDay.currentVersion].absoluteString, + @(mbgl::util::default_styles::trafficDay.url)); + XCTAssertEqualObjects([MGLStyle trafficDayStyleURLWithVersion:99].absoluteString, + @"mapbox://styles/mapbox/traffic-day-v99"); + XCTAssertEqualObjects([MGLStyle trafficNightStyleURLWithVersion:mbgl::util::default_styles::trafficNight.currentVersion].absoluteString, + @(mbgl::util::default_styles::trafficNight.url)); + XCTAssertEqualObjects([MGLStyle trafficNightStyleURLWithVersion:99].absoluteString, + @"mapbox://styles/mapbox/traffic-night-v99"); + + static_assert(8 == mbgl::util::default_styles::numOrderedStyles, "MGLStyleTests isn’t testing all the styles in mbgl::util::default_styles."); } diff --git a/platform/default/mbgl/util/default_styles.cpp b/platform/default/mbgl/util/default_styles.cpp index e051817ada..5f4ca862fe 100644 --- a/platform/default/mbgl/util/default_styles.cpp +++ b/platform/default/mbgl/util/default_styles.cpp @@ -10,6 +10,8 @@ const DefaultStyle light = { "mapbox://styles/mapbox/light-v9", const DefaultStyle dark = { "mapbox://styles/mapbox/dark-v9", "Dark", 9 }; const DefaultStyle satellite = { "mapbox://styles/mapbox/satellite-v9", "Satellite", 9 }; const DefaultStyle satelliteStreets = { "mapbox://styles/mapbox/satellite-streets-v10", "Satellite Streets", 10 }; +const DefaultStyle trafficDay = { "mapbox://styles/mapbox/traffic-day-v2", "Traffic Day", 2 }; +const DefaultStyle trafficNight = { "mapbox://styles/mapbox/traffic-night-v2", "Traffic Night", 2 }; } // namespace default_styles } // end namespace util diff --git a/platform/default/mbgl/util/default_styles.hpp b/platform/default/mbgl/util/default_styles.hpp index 5e0d083d82..466102d623 100644 --- a/platform/default/mbgl/util/default_styles.hpp +++ b/platform/default/mbgl/util/default_styles.hpp @@ -19,9 +19,12 @@ extern const DefaultStyle light; extern const DefaultStyle dark; extern const DefaultStyle satellite; extern const DefaultStyle satelliteStreets; +extern const DefaultStyle trafficDay; +extern const DefaultStyle trafficNight; const DefaultStyle orderedStyles[] = { streets, outdoors, light, dark, satellite, satelliteStreets, + trafficDay, trafficNight, }; const size_t numOrderedStyles = sizeof(orderedStyles) / sizeof(DefaultStyle); diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index b975030b1b..922b7b6486 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -8,6 +8,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Added support for 3D extrusion of buildings and other polygonal features via the `MGLFillExtrusionStyleLayer` class and the `fill-extrusion` layer type in style JSON. ([#8431](https://github.com/mapbox/mapbox-gl-native/pull/8431)) * MGLMapView and MGLTilePyramidOfflineRegion now default to version 10 of the Mapbox Streets style. Similarly, several style URL class methods of MGLStyle return URLs to version 10 styles. Unversioned variations of these methods are no longer deprecated. `MGLStyleDefaultVersion` should no longer be used with any style other than Streets. ([#6301](https://github.com/mapbox/mapbox-gl-native/pull/6301)) +* Added class methods to MGLStyle that correspond to the new [Traffic Day and Traffic Night](https://www.mapbox.com/blog/live-traffic-maps/) styles. ([#6301](https://github.com/mapbox/mapbox-gl-native/pull/6301)) * MGLSymbolStyleLayer’s `iconImageName`, `iconScale`, `textFontSize`, `textOffset`, and `textRotation` properties can now be set to a source or composite function. ([#8544](https://github.com/mapbox/mapbox-gl-native/pull/8544), [#8590](https://github.com/mapbox/mapbox-gl-native/pull/8590), [#8592](https://github.com/mapbox/mapbox-gl-native/pull/8592), [#8593](https://github.com/mapbox/mapbox-gl-native/pull/8593)) * Fixed an issue where setting the `MGLVectorStyleLayer.predicate` property failed to take effect if the relevant source was not in use by a visible layer at the time. ([#8653](https://github.com/mapbox/mapbox-gl-native/pull/8653)) * Fixed an issue causing a composite function’s highest zoom level stop to be misinterpreted. ([#8613](https://github.com/mapbox/mapbox-gl-native/pull/8613), [#8790](https://github.com/mapbox/mapbox-gl-native/pull/8790)) diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m index 70271c02b9..209998adb9 100644 --- a/platform/ios/app/MBXViewController.m +++ b/platform/ios/app/MBXViewController.m @@ -1543,14 +1543,18 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) { @"Dark", @"Satellite", @"Satellite Streets", + @"Traffic Day", + @"Traffic Night", ]; styleURLs = @[ - [MGLStyle streetsStyleURLWithVersion:MGLStyleDefaultVersion], - [MGLStyle outdoorsStyleURLWithVersion:MGLStyleDefaultVersion], - [MGLStyle lightStyleURLWithVersion:MGLStyleDefaultVersion], - [MGLStyle darkStyleURLWithVersion:MGLStyleDefaultVersion], - [MGLStyle satelliteStyleURLWithVersion:MGLStyleDefaultVersion], - [MGLStyle satelliteStreetsStyleURLWithVersion:MGLStyleDefaultVersion], + [MGLStyle streetsStyleURL], + [MGLStyle outdoorsStyleURL], + [MGLStyle lightStyleURL], + [MGLStyle darkStyleURL], + [MGLStyle satelliteStyleURL], + [MGLStyle satelliteStreetsStyleURL], + [MGLStyle trafficDayStyleURL], + [MGLStyle trafficNightStyleURL], ]; NSAssert(styleNames.count == styleURLs.count, @"Style names and URLs don’t match."); diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index 298cc8ecfc..632bcfa44b 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -6,6 +6,7 @@ * Added support for 3D extrusion of buildings and other polygonal features via the `MGLFillExtrusionStyleLayer` class and the `fill-extrusion` layer type in style JSON. ([#8431](https://github.com/mapbox/mapbox-gl-native/pull/8431)) * MGLMapView and MGLTilePyramidOfflineRegion now default to version 10 of the Mapbox Streets style. Similarly, several style URL class methods of MGLStyle return URLs to version 10 styles. Unversioned variations of these methods are no longer deprecated. `MGLStyleDefaultVersion` should no longer be used with any style other than Streets. ([#6301](https://github.com/mapbox/mapbox-gl-native/pull/6301)) +* Added class methods to MGLStyle that correspond to the new [Traffic Day and Traffic Night](https://www.mapbox.com/blog/live-traffic-maps/) styles. ([#6301](https://github.com/mapbox/mapbox-gl-native/pull/6301)) * MGLSymbolStyleLayer’s `iconImageName`, `iconScale`, `textFontSize`, `textOffset`, and `textRotation` properties can now be set to a source or composite function. ([#8544](https://github.com/mapbox/mapbox-gl-native/pull/8544), [#8590](https://github.com/mapbox/mapbox-gl-native/pull/8590), [#8592](https://github.com/mapbox/mapbox-gl-native/pull/8592), [#8593](https://github.com/mapbox/mapbox-gl-native/pull/8593)) * Fixed an issue where setting the `MGLVectorStyleLayer.predicate` property failed to take effect if the relevant source was not in use by a visible layer at the time. ([#8653](https://github.com/mapbox/mapbox-gl-native/pull/8653)) * Fixed an issue causing a composite function’s highest zoom level stop to be misinterpreted. ([#8613](https://github.com/mapbox/mapbox-gl-native/pull/8613), [#8790](https://github.com/mapbox/mapbox-gl-native/pull/8790)) diff --git a/platform/macos/app/Base.lproj/MainMenu.xib b/platform/macos/app/Base.lproj/MainMenu.xib index 941bed2136..20a4f65b3f 100644 --- a/platform/macos/app/Base.lproj/MainMenu.xib +++ b/platform/macos/app/Base.lproj/MainMenu.xib @@ -1,7 +1,7 @@ - - + + - + @@ -395,6 +395,16 @@ + + + + + + + + + + @@ -643,7 +653,7 @@ CA - + @@ -654,7 +664,7 @@ CA - + @@ -723,7 +733,7 @@ CA - + diff --git a/platform/macos/app/Base.lproj/MapDocument.xib b/platform/macos/app/Base.lproj/MapDocument.xib index 065acc41fd..d95f21b2e9 100644 --- a/platform/macos/app/Base.lproj/MapDocument.xib +++ b/platform/macos/app/Base.lproj/MapDocument.xib @@ -1,7 +1,7 @@ - + - + @@ -48,7 +48,7 @@ - + @@ -183,9 +183,9 @@ - + - + @@ -204,6 +204,12 @@ + + + + + + diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m index 5be17c1cbe..59c1817f63 100644 --- a/platform/macos/app/MapDocument.m +++ b/platform/macos/app/MapDocument.m @@ -165,22 +165,28 @@ NS_ARRAY_OF(id ) *MBXFlattenedShapes(NS_ARRAY_OF(id ) *MBXFlattenedShapes(NS_ARRAY_OF(id ) *MBXFlattenedShapes(NS_ARRAY_OF(id Date: Fri, 12 May 2017 20:07:06 +0200 Subject: [android] Release android-v5.1.0-beta.2 (#8976) * [android] url getter on sources * [android] fix ui test filter in makefile * [android] - build SNAPSHOT from release branch (#8958) * [android] - update changelog for 5.1.0-beta.2 * [android] - bump version number * [android] - Camera change listener v2.0 * [core] allow filesource url transform reset * [android] Update attribution wordmark (#8774) * Update wordmark on android * Moved attribution i icon to the right of mapbox word (in mapview preview image) * update padding and margin * [android] update hardcoded branch name * revert version to 5.1.0-SNAPSHOT --- Makefile | 2 +- circle.yml | 2 +- platform/android/CHANGELOG.md | 28 +++++- .../mapboxsdk/maps/CameraChangeDispatcher.java | 67 ++++++++++++++ .../mapbox/mapboxsdk/maps/MapGestureDetector.java | 39 ++++---- .../java/com/mapbox/mapboxsdk/maps/MapView.java | 11 ++- .../java/com/mapbox/mapboxsdk/maps/MapboxMap.java | 100 ++++++++++++++++++++- .../mapbox/mapboxsdk/maps/MapboxMapOptions.java | 30 +++---- .../java/com/mapbox/mapboxsdk/maps/Transform.java | 57 ++++++++++-- .../java/com/mapbox/mapboxsdk/maps/UiSettings.java | 23 ++--- .../mapboxsdk/style/sources/GeoJsonSource.java | 10 +++ .../mapboxsdk/style/sources/RasterSource.java | 13 +++ .../mapboxsdk/style/sources/VectorSource.java | 10 +++ .../main/res/drawable-hdpi/mapbox_logo_icon.png | Bin 3408 -> 4778 bytes .../main/res/drawable-mdpi/mapbox_logo_icon.png | Bin 1958 -> 2622 bytes .../main/res/drawable-xhdpi/mapbox_logo_icon.png | Bin 4492 -> 6579 bytes .../main/res/drawable-xxhdpi/mapbox_logo_icon.png | Bin 7059 -> 10802 bytes .../main/res/drawable-xxxhdpi/mapbox_logo_icon.png | Bin 9402 -> 14441 bytes .../main/res/drawable/mapbox_info_icon_default.xml | 8 +- .../res/drawable/mapbox_info_icon_selected.xml | 10 +-- .../main/res/layout/mapbox_mapview_internal.xml | 3 +- .../src/main/res/layout/mapbox_mapview_preview.xml | 35 +++++--- .../src/main/res/values/dimens.xml | 9 +- .../mapboxsdk/testapp/style/RuntimeStyleTests.java | 33 +++++++ .../activity/camera/CameraPositionActivity.java | 31 ++++++- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../android/src/style/sources/geojson_source.cpp | 6 ++ .../android/src/style/sources/geojson_source.hpp | 2 + .../android/src/style/sources/raster_source.cpp | 8 +- .../android/src/style/sources/raster_source.hpp | 2 + .../android/src/style/sources/vector_source.cpp | 8 +- .../android/src/style/sources/vector_source.hpp | 2 + platform/default/default_file_source.cpp | 16 ++-- 33 files changed, 468 insertions(+), 99 deletions(-) create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraChangeDispatcher.java diff --git a/Makefile b/Makefile index e8f7f175ff..abccb306a6 100644 --- a/Makefile +++ b/Makefile @@ -571,7 +571,7 @@ run-android-ui-test-$1: platform/android/configuration.gradle run-android-ui-test-$1-%: platform/android/configuration.gradle adb uninstall com.mapbox.mapboxsdk.testapp > /dev/null - cd platform/android && $(MBGL_ANDROID_GRADLE) -Pmapbox.abis=$2 :MapboxGLAndroidSDKTestApp:connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.class="$*" + cd platform/android && $(MBGL_ANDROID_GRADLE) -Pmapbox.abis=$2 :MapboxGLAndroidSDKTestApp:connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.class="$$*" endef diff --git a/circle.yml b/circle.yml index 7d75427bcb..4ce00872b4 100644 --- a/circle.yml +++ b/circle.yml @@ -133,4 +133,4 @@ jobs: - deploy: name: Publish to Maven command: | - if [ "${CIRCLE_BRANCH}" == "master" ]; then make run-android-upload-archives ; fi + if [ "${CIRCLE_BRANCH}" == "release-android-v5.1.0-beta.2" ]; then make run-android-upload-archives ; fi diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md index fdc6343b7c..bc307e5061 100644 --- a/platform/android/CHANGELOG.md +++ b/platform/android/CHANGELOG.md @@ -3,11 +3,35 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to do so please see the [`Contributing Guide`](https://github.com/mapbox/mapbox-gl-native/blob/master/CONTRIBUTING.md) first to get started. ## 5.1.0 - TBA - +* Update attribution with new Mapbox wordmark [#8774](https://github.com/mapbox/mapbox-gl-native/pull/8774) + +## 5.1.0-beta.2 - May 12, 2017 + +5.1.0-beta.2 builds further on 5.1.0-beta.1 and adds: + +* When a layer is added, reload its source's tiles [#8963](https://github.com/mapbox/mapbox-gl-native/pull/8963) +* Update release script to support CircleCI builds [#8950](https://github.com/mapbox/mapbox-gl-native/pull/8950) +* URL getter on Sources [#8959](https://github.com/mapbox/mapbox-gl-native/pull/8959) +* Build SNAPSHOT from release branch CI configuration [#8958](https://github.com/mapbox/mapbox-gl-native/pull/8958) +* Fix UI test filter in Makefile [#8960](https://github.com/mapbox/mapbox-gl-native/pull/8960) +* Bump & fixup dependencies [#8921](https://github.com/mapbox/mapbox-gl-native/pull/8921) +* Ignore already deleted region [#8920](https://github.com/mapbox/mapbox-gl-native/pull/8920) +* Keep offline observer when timeout occurs [#8919](https://github.com/mapbox/mapbox-gl-native/pull/8919) +* Show error message when no browser installed [#8920](https://github.com/mapbox/mapbox-gl-native/pull/8920) +* Reset observers of removed Sources and Layers [#8900](https://github.com/mapbox/mapbox-gl-native/pull/8900) +* Only build custom layer .so for debug builds [#8885](https://github.com/mapbox/mapbox-gl-native/pull/8885) +* Update localizations [#8883](https://github.com/mapbox/mapbox-gl-native/pull/8883) +* Reset observers of removed Sources and Layers [#8862](https://github.com/mapbox/mapbox-gl-native/pull/8862) +* Remove force style cascade [#8866](https://github.com/mapbox/mapbox-gl-native/pull/8866) +* Update proguard config [#8944](https://github.com/mapbox/mapbox-gl-native/pull/8944) +* Update LOST to 2.3.0-SNAPSHOT [#8872](https://github.com/mapbox/mapbox-gl-native/pull/8872) +* Update logo [#8774](https://github.com/mapbox/mapbox-gl-native/pull/8774) +* Camera change listener v2.0 [#8644](https://github.com/mapbox/mapbox-gl-native/pull/8644) +* Allow filesource url transform reset [#8957](https://github.com/mapbox/mapbox-gl-native/pull/8957) ## 5.1.0-beta.1 - May 2, 2017 -5.1.0 builds further on 5.0.2 and adds: +5.1.0-beta.1 builds further on 5.0.2 and adds: * Support for FillExtrusionLayer [#8431](https://github.com/mapbox/mapbox-gl-native/pull/8431) * Limit Viewport [#8622](https://github.com/mapbox/mapbox-gl-native/pull/8622) 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 new file mode 100644 index 0000000000..bd028aecb6 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraChangeDispatcher.java @@ -0,0 +1,67 @@ +package com.mapbox.mapboxsdk.maps; + +import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraIdleListener; +import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveCanceledListener; +import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveStartedListener; +import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveListener; + +class CameraChangeDispatcher implements MapboxMap.OnCameraMoveStartedListener, MapboxMap.OnCameraMoveListener, + MapboxMap.OnCameraMoveCanceledListener, OnCameraIdleListener { + + private boolean idle = true; + + private OnCameraMoveStartedListener onCameraMoveStartedListener; + private OnCameraMoveCanceledListener onCameraMoveCanceledListener; + private OnCameraMoveListener onCameraMoveListener; + private OnCameraIdleListener onCameraIdleListener; + + void setOnCameraMoveStartedListener(OnCameraMoveStartedListener onCameraMoveStartedListener) { + this.onCameraMoveStartedListener = onCameraMoveStartedListener; + } + + void setOnCameraMoveCanceledListener(OnCameraMoveCanceledListener onCameraMoveCanceledListener) { + this.onCameraMoveCanceledListener = onCameraMoveCanceledListener; + } + + void setOnCameraMoveListener(OnCameraMoveListener onCameraMoveListener) { + this.onCameraMoveListener = onCameraMoveListener; + } + + void setOnCameraIdleListener(OnCameraIdleListener onCameraIdleListener) { + this.onCameraIdleListener = onCameraIdleListener; + } + + @Override + public void onCameraMoveStarted(int reason) { + if (!idle) { + return; + } + + idle = false; + if (onCameraMoveStartedListener != null) { + onCameraMoveStartedListener.onCameraMoveStarted(reason); + } + } + + @Override + public void onCameraMove() { + if (onCameraMoveListener != null && !idle) { + onCameraMoveListener.onCameraMove(); + } + } + + @Override + public void onCameraMoveCanceled() { + if (onCameraMoveCanceledListener != null && !idle) { + onCameraMoveCanceledListener.onCameraMoveCanceled(); + } + } + + @Override + public void onCameraIdle() { + if (onCameraIdleListener != null && !idle) { + idle = true; + onCameraIdleListener.onCameraIdle(); + } + } +} 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 dca833bbf4..39433d8b93 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 @@ -22,6 +22,8 @@ import com.mapbox.services.android.telemetry.MapboxTelemetry; import com.mapbox.services.android.telemetry.utils.MathUtils; import com.mapbox.services.android.telemetry.utils.TelemetryUtils; +import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveStartedListener.REASON_API_GESTURE; + /** * Manages gestures events on a MapView. *

@@ -35,6 +37,7 @@ final class MapGestureDetector { private final UiSettings uiSettings; private final TrackingSettings trackingSettings; private final AnnotationManager annotationManager; + private final CameraChangeDispatcher cameraChangeDispatcher; private final GestureDetectorCompat gestureDetector; private final ScaleGestureDetector scaleGestureDetector; @@ -56,12 +59,14 @@ final class MapGestureDetector { private boolean scaleGestureOccurred = false; MapGestureDetector(Context context, Transform transform, Projection projection, UiSettings uiSettings, - TrackingSettings trackingSettings, AnnotationManager annotationManager) { + TrackingSettings trackingSettings, AnnotationManager annotationManager, + CameraChangeDispatcher cameraChangeDispatcher) { this.annotationManager = annotationManager; this.transform = transform; this.projection = projection; this.uiSettings = uiSettings; this.trackingSettings = trackingSettings; + this.cameraChangeDispatcher = cameraChangeDispatcher; // Touch gesture detectors gestureDetector = new GestureDetectorCompat(context, new GestureListener()); @@ -187,6 +192,7 @@ final class MapGestureDetector { MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapDragEndEvent( getLocationFromGesture(event.getX(), event.getY()), transform)); scrollInProgress = false; + cameraChangeDispatcher.onCameraIdle(); } twoTap = false; @@ -273,6 +279,9 @@ final class MapGestureDetector { break; } + // notify camera change listener + cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); + // Single finger double tap if (focalPoint != null) { // User provided focal point @@ -337,6 +346,7 @@ final class MapGestureDetector { // and ignore when a scale gesture has occurred return false; } + cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); float screenDensity = uiSettings.getPixelRatio(); @@ -362,9 +372,7 @@ final class MapGestureDetector { long animationTime = (long) (velocityXY / 7 / tiltFactor + MapboxConstants.ANIMATION_DURATION_FLING_BASE); // update transformation - transform.setGestureInProgress(true); transform.moveBy(offsetX, offsetY, animationTime); - transform.setGestureInProgress(false); if (onFlingListener != null) { onFlingListener.onFling(); @@ -377,6 +385,10 @@ final class MapGestureDetector { public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { if (!scrollInProgress) { scrollInProgress = true; + + // Cancel any animation + transform.cancelTransitions(); + cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapClickEvent( getLocationFromGesture(e1.getX(), e1.getY()), MapboxEvent.GESTURE_PAN_START, transform)); @@ -391,8 +403,6 @@ final class MapGestureDetector { // reset tracking if needed trackingSettings.resetTrackingModesIfRequired(true, false); - // Cancel any animation - transform.cancelTransitions(); // Scroll the map transform.moveBy(-distanceX, -distanceY, 0 /*no duration*/); @@ -446,6 +456,8 @@ final class MapGestureDetector { // If scale is large enough ignore a tap scaleFactor *= detector.getScaleFactor(); if ((scaleFactor > 1.05f) || (scaleFactor < 0.95f)) { + // notify camera change listener + cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); zoomStarted = true; } @@ -465,9 +477,6 @@ final class MapGestureDetector { return false; } - // Cancel any animation - transform.cancelTransitions(); - // Gesture is a quickzoom if there aren't two fingers quickZoom = !twoTap; @@ -512,6 +521,9 @@ final class MapGestureDetector { return false; } + // notify camera change listener + cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); + beginTime = detector.getEventTime(); MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapClickEvent( getLocationFromGesture(detector.getFocusX(), detector.getFocusY()), @@ -522,6 +534,7 @@ final class MapGestureDetector { // Called when the fingers leave the screen @Override public void onRotateEnd(RotateGestureDetector detector) { + // notify camera change listener beginTime = 0; totalAngle = 0.0f; started = false; @@ -553,13 +566,8 @@ final class MapGestureDetector { if (!started) { return false; } - - // Cancel any animation - transform.cancelTransitions(); - // rotation constitutes translation of anything except the center of // rotation, so cancel both location and bearing tracking if required - trackingSettings.resetTrackingModesIfRequired(true, true); // Get rotate value @@ -593,6 +601,8 @@ final class MapGestureDetector { return false; } + // notify camera change listener + cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); beginTime = detector.getEventTime(); MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapClickEvent( getLocationFromGesture(detector.getFocusX(), detector.getFocusY()), @@ -633,9 +643,6 @@ final class MapGestureDetector { return false; } - // Cancel any animation - transform.cancelTransitions(); - // Get tilt value (scale and clamp) double pitch = transform.getTilt(); pitch -= 0.1 * detector.getShovePixelsDelta(); 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 872802292c..d00da4c155 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 @@ -129,6 +129,9 @@ public class MapView extends FrameLayout { // callback for zooming in the camera CameraZoomInvalidator zoomInvalidator = new CameraZoomInvalidator(); + // callback for camera change events + CameraChangeDispatcher cameraChangeDispatcher = new CameraChangeDispatcher(); + // setup components for MapboxMap creation Projection proj = new Projection(nativeMapView); UiSettings uiSettings = new UiSettings(proj, focalPoint, compassView, attrView, view.findViewById(R.id.logoView)); @@ -136,12 +139,14 @@ public class MapView extends FrameLayout { MyLocationViewSettings myLocationViewSettings = new MyLocationViewSettings(myLocationView, proj, focalPoint); MarkerViewManager markerViewManager = new MarkerViewManager((ViewGroup) findViewById(R.id.markerViewContainer)); AnnotationManager annotations = new AnnotationManager(nativeMapView, this, markerViewManager); - Transform transform = new Transform(nativeMapView, annotations.getMarkerViewManager(), trackingSettings); + Transform transform = new Transform(nativeMapView, annotations.getMarkerViewManager(), trackingSettings, + cameraChangeDispatcher); mapboxMap = new MapboxMap(nativeMapView, transform, uiSettings, trackingSettings, myLocationViewSettings, proj, - registerTouchListener, annotations); + registerTouchListener, annotations, cameraChangeDispatcher); // user input - mapGestureDetector = new MapGestureDetector(context, transform, proj, uiSettings, trackingSettings, annotations); + mapGestureDetector = new MapGestureDetector(context, transform, proj, uiSettings, trackingSettings, annotations, + cameraChangeDispatcher); mapKeyListener = new MapKeyListener(transform, trackingSettings, uiSettings); MapZoomControllerListener zoomListener = new MapZoomControllerListener(mapGestureDetector, uiSettings, transform); 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 1751dcf042..96603355f1 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 @@ -69,6 +69,7 @@ public final class MapboxMap { private final Transform transform; private final AnnotationManager annotationManager; private final MyLocationViewSettings myLocationViewSettings; + private final CameraChangeDispatcher cameraChangeDispatcher; private final OnRegisterTouchListener onRegisterTouchListener; @@ -76,7 +77,7 @@ public final class MapboxMap { MapboxMap(NativeMapView map, Transform transform, UiSettings ui, TrackingSettings tracking, MyLocationViewSettings myLocationView, Projection projection, OnRegisterTouchListener listener, - AnnotationManager annotations) { + AnnotationManager annotations, CameraChangeDispatcher cameraChangeDispatcher) { this.nativeMapView = map; this.uiSettings = ui; this.trackingSettings = tracking; @@ -85,6 +86,7 @@ public final class MapboxMap { this.annotationManager = annotations.bind(this); this.transform = transform; this.onRegisterTouchListener = listener; + this.cameraChangeDispatcher = cameraChangeDispatcher; } void initialise(@NonNull Context context, @NonNull MapboxMapOptions options) { @@ -1595,10 +1597,51 @@ public final class MapboxMap { * To unset the callback, use null. */ @UiThread + @Deprecated public void setOnCameraChangeListener(@Nullable OnCameraChangeListener listener) { transform.setOnCameraChangeListener(listener); } + /** + * Sets a callback that is invoked when camera movement has ended. + * + * @param listener the listener to notify + */ + @UiThread + public void setOnCameraIdleListener(@Nullable OnCameraIdleListener listener) { + cameraChangeDispatcher.setOnCameraIdleListener(listener); + } + + /** + * Sets a callback that is invoked when camera movement was cancelled. + * + * @param listener the listener to notify + */ + @UiThread + public void setOnCameraMoveCancelListener(@Nullable OnCameraMoveCanceledListener listener) { + cameraChangeDispatcher.setOnCameraMoveCanceledListener(listener); + } + + /** + * Sets a callback that is invoked when camera movement has started. + * + * @param listener the listener to notify + */ + @UiThread + public void setOnCameraMoveStartedistener(@Nullable OnCameraMoveStartedListener listener) { + cameraChangeDispatcher.setOnCameraMoveStartedListener(listener); + } + + /** + * Sets a callback that is invoked when camera position changes. + * + * @param listener the listener to notify + */ + @UiThread + public void setOnCameraMoveListener(@Nullable OnCameraMoveListener listener) { + cameraChangeDispatcher.setOnCameraMoveListener(listener); + } + /** * Sets a callback that's invoked on every frame rendered to the map view. * @@ -1913,7 +1956,12 @@ public final class MapboxMap { /** * Interface definition for a callback to be invoked when the camera changes position. + * + * @deprecated Replaced by MapboxMap.OnCameraMoveStartedListener, MapboxMap.OnCameraMoveListener and + * MapboxMap.OnCameraIdleListener. The order in which the deprecated onCameraChange method will be called in relation + * to the methods in the new camera change listeners is undefined. */ + @Deprecated public interface OnCameraChangeListener { /** * Called after the camera position has changed. During an animation, @@ -1925,6 +1973,56 @@ public final class MapboxMap { void onCameraChange(CameraPosition position); } + /** + * Interface definition for a callback to be invoked for when the camera motion starts. + */ + public interface OnCameraMoveStartedListener { + int REASON_API_GESTURE = 1; + int REASON_DEVELOPER_ANIMATION = 2; + int REASON_API_ANIMATION = 3; + + /** + * Called when the camera starts moving after it has been idle or when the reason for camera motion has changed. + * + * @param reason the reason for the camera change + */ + void onCameraMoveStarted(int reason); + } + + /** + * Interface definition for a callback to be invoked for when the camera changes position. + */ + public interface OnCameraMoveListener { + /** + * Called repeatedly as the camera continues to move after an onCameraMoveStarted call. + * This may be called as often as once every frame and should not perform expensive operations. + */ + void onCameraMove(); + } + + /** + * Interface definition for a callback to be invoked for when the camera's motion has been stopped or when the camera + * starts moving for a new reason. + */ + public interface OnCameraMoveCanceledListener { + /** + * Called when the developer explicitly calls the cancelTransitions() method or if the reason for camera motion has + * changed before the onCameraIdle had a chance to fire after the previous animation. + * Do not update or animate the camera from within this method. + */ + void onCameraMoveCanceled(); + } + + /** + * Interface definition for a callback to be invoked for when camera movement has ended. + */ + public interface OnCameraIdleListener { + /** + * Called when camera movement has ended. + */ + void onCameraIdle(); + } + /** * Interface definition for a callback to be invoked when a frame is rendered to the map view. * diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java index 8fcfdd6db0..68603ab1a3 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java @@ -35,10 +35,8 @@ import java.util.Arrays; */ public class MapboxMapOptions implements Parcelable { - private static final float DIMENSION_SEVEN_DP = 7f; - private static final float DIMENSION_TEN_DP = 10f; - private static final float DIMENSION_SIXTEEN_DP = 16f; - private static final float DIMENSION_SEVENTY_SIX_DP = 76f; + private static final float FOUR_DP = 4f; + private static final float EIGHTY_NINE_DP = 92f; private CameraPosition cameraPosition; @@ -206,13 +204,13 @@ public class MapboxMapOptions implements Parcelable { Gravity.TOP | Gravity.END)); mapboxMapOptions.compassMargins(new int[] { (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiCompassMarginLeft, - DIMENSION_TEN_DP * pxlRatio)), + FOUR_DP * pxlRatio)), ((int) typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiCompassMarginTop, - DIMENSION_TEN_DP * pxlRatio)), + FOUR_DP * pxlRatio)), ((int) typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiCompassMarginRight, - DIMENSION_TEN_DP * pxlRatio)), + FOUR_DP * pxlRatio)), ((int) typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiCompassMarginBottom, - DIMENSION_TEN_DP * pxlRatio))}); + FOUR_DP * pxlRatio))}); mapboxMapOptions.compassFadesWhenFacingNorth(typedArray.getBoolean( R.styleable.mapbox_MapView_mapbox_uiCompassFadeFacingNorth, true)); Drawable compassDrawable = typedArray.getDrawable( @@ -227,13 +225,13 @@ public class MapboxMapOptions implements Parcelable { Gravity.BOTTOM | Gravity.START)); mapboxMapOptions.logoMargins(new int[] { (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiLogoMarginLeft, - DIMENSION_SIXTEEN_DP * pxlRatio)), + FOUR_DP * pxlRatio)), (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiLogoMarginTop, - DIMENSION_SIXTEEN_DP * pxlRatio)), + FOUR_DP * pxlRatio)), (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiLogoMarginRight, - DIMENSION_SIXTEEN_DP * pxlRatio)), + FOUR_DP * pxlRatio)), (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiLogoMarginBottom, - DIMENSION_SIXTEEN_DP * pxlRatio))}); + FOUR_DP * pxlRatio))}); mapboxMapOptions.attributionTintColor(typedArray.getColor( R.styleable.mapbox_MapView_mapbox_uiAttributionTintColor, -1)); @@ -243,13 +241,13 @@ public class MapboxMapOptions implements Parcelable { R.styleable.mapbox_MapView_mapbox_uiAttributionGravity, Gravity.BOTTOM)); mapboxMapOptions.attributionMargins(new int[] { (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiAttributionMarginLeft, - DIMENSION_SEVENTY_SIX_DP) * pxlRatio), + EIGHTY_NINE_DP * pxlRatio)), (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiAttributionMarginTop, - DIMENSION_SEVEN_DP * pxlRatio)), + FOUR_DP * pxlRatio)), (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiAttributionMarginRight, - DIMENSION_SEVEN_DP * pxlRatio)), + FOUR_DP * pxlRatio)), (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiAttributionMarginBottom, - DIMENSION_SEVEN_DP * pxlRatio))}); + FOUR_DP * pxlRatio))}); mapboxMapOptions.locationEnabled(typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_myLocation, false)); mapboxMapOptions.myLocationForegroundTintColor( diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java index e101340111..af44a08a81 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java @@ -16,6 +16,7 @@ import com.mapbox.mapboxsdk.maps.widgets.MyLocationView; import timber.log.Timber; import static com.mapbox.mapboxsdk.maps.MapView.REGION_DID_CHANGE_ANIMATED; +import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveStartedListener; /** * Resembles the current Map transformation. @@ -33,13 +34,18 @@ final class Transform implements MapView.OnMapChangedListener { private CameraPosition cameraPosition; private MapboxMap.CancelableCallback cameraCancelableCallback; + private MapboxMap.OnCameraChangeListener onCameraChangeListener; - Transform(NativeMapView mapView, MarkerViewManager markerViewManager, TrackingSettings trackingSettings) { + private CameraChangeDispatcher cameraChangeDispatcher; + + Transform(NativeMapView mapView, MarkerViewManager markerViewManager, TrackingSettings trackingSettings, + CameraChangeDispatcher cameraChangeDispatcher) { this.mapView = mapView; this.markerViewManager = markerViewManager; this.trackingSettings = trackingSettings; this.myLocationView = trackingSettings.getMyLocationView(); + this.cameraChangeDispatcher = cameraChangeDispatcher; } void initialise(@NonNull MapboxMap mapboxMap, @NonNull MapboxMapOptions options) { @@ -79,6 +85,7 @@ final class Transform implements MapView.OnMapChangedListener { cameraCancelableCallback.onFinish(); cameraCancelableCallback = null; } + cameraChangeDispatcher.onCameraIdle(); mapView.removeOnMapChangedListener(this); } } @@ -89,10 +96,12 @@ final class Transform implements MapView.OnMapChangedListener { if (!cameraPosition.equals(this.cameraPosition)) { trackingSettings.resetTrackingModesIfRequired(cameraPosition); cancelTransitions(); + cameraChangeDispatcher.onCameraMoveStarted(OnCameraMoveStartedListener.REASON_API_ANIMATION); mapView.jumpTo(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, cameraPosition.zoom); if (callback != null) { callback.onFinish(); } + cameraChangeDispatcher.onCameraIdle(); } } @@ -103,6 +112,8 @@ final class Transform implements MapView.OnMapChangedListener { if (!cameraPosition.equals(this.cameraPosition)) { trackingSettings.resetTrackingModesIfRequired(cameraPosition); cancelTransitions(); + cameraChangeDispatcher.onCameraMoveStarted(OnCameraMoveStartedListener.REASON_API_ANIMATION); + if (callback != null) { cameraCancelableCallback = callback; mapView.addOnMapChangedListener(this); @@ -119,8 +130,9 @@ final class Transform implements MapView.OnMapChangedListener { CameraPosition cameraPosition = update.getCameraPosition(mapboxMap); if (!cameraPosition.equals(this.cameraPosition)) { trackingSettings.resetTrackingModesIfRequired(cameraPosition); - cancelTransitions(); + cameraChangeDispatcher.onCameraMoveStarted(OnCameraMoveStartedListener.REASON_API_ANIMATION); + if (callback != null) { cameraCancelableCallback = callback; mapView.addOnMapChangedListener(this); @@ -135,7 +147,12 @@ final class Transform implements MapView.OnMapChangedListener { @Nullable CameraPosition invalidateCameraPosition() { if (mapView != null) { - cameraPosition = mapView.getCameraPosition(); + CameraPosition cameraPosition = mapView.getCameraPosition(); + if (this.cameraPosition != null && !this.cameraPosition.equals(cameraPosition)) { + cameraChangeDispatcher.onCameraMove(); + } + + this.cameraPosition = cameraPosition; if (onCameraChangeListener != null) { onCameraChangeListener.onCameraChange(this.cameraPosition); } @@ -144,10 +161,17 @@ final class Transform implements MapView.OnMapChangedListener { } void cancelTransitions() { + // notify user about cancel + cameraChangeDispatcher.onCameraMoveCanceled(); + + // notify animateCamera and easeCamera about cancelling if (cameraCancelableCallback != null) { + cameraChangeDispatcher.onCameraIdle(); cameraCancelableCallback.onCancel(); cameraCancelableCallback = null; } + + // cancel ongoing transitions mapView.cancelTransitions(); } @@ -157,6 +181,10 @@ final class Transform implements MapView.OnMapChangedListener { mapView.resetNorth(); } + // + // Camera change listener API + // + void setOnCameraChangeListener(@Nullable MapboxMap.OnCameraChangeListener listener) { this.onCameraChangeListener = listener; } @@ -172,9 +200,6 @@ final class Transform implements MapView.OnMapChangedListener { } void zoom(boolean zoomIn, @NonNull PointF focalPoint) { - // Cancel any animation - cancelTransitions(); - CameraPosition cameraPosition = invalidateCameraPosition(); if (cameraPosition != null) { int newZoom = (int) Math.round(cameraPosition.zoom + (zoomIn ? 1 : -1)); @@ -187,6 +212,15 @@ final class Transform implements MapView.OnMapChangedListener { } void setZoom(double zoom, @NonNull PointF focalPoint, long duration) { + mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() { + @Override + public void onMapChanged(int change) { + if (change == MapView.REGION_DID_CHANGE_ANIMATED) { + mapView.removeOnMapChangedListener(this); + cameraChangeDispatcher.onCameraIdle(); + } + } + }); mapView.setZoom(zoom, focalPoint, duration); } @@ -278,6 +312,17 @@ final class Transform implements MapView.OnMapChangedListener { } void moveBy(double offsetX, double offsetY, long duration) { + if (duration > 0) { + mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() { + @Override + public void onMapChanged(int change) { + if (change == MapView.DID_FINISH_RENDERING_MAP_FULLY_RENDERED) { + mapView.removeOnMapChangedListener(this); + cameraChangeDispatcher.onCameraIdle(); + } + } + }); + } mapView.moveBy(offsetX, offsetY, duration); } 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 354a42536a..1bcf8a70b9 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 @@ -146,7 +146,7 @@ public final class UiSettings { if (compassMargins != null) { setCompassMargins(compassMargins[0], compassMargins[1], compassMargins[2], compassMargins[3]); } else { - int tenDp = (int) resources.getDimension(R.dimen.mapbox_ten_dp); + int tenDp = (int) resources.getDimension(R.dimen.mapbox_four_dp); setCompassMargins(tenDp, tenDp, tenDp, tenDp); } setCompassFadeFacingNorth(options.getCompassFadeFacingNorth()); @@ -171,9 +171,7 @@ public final class UiSettings { private byte[] convert(Bitmap resource) { ByteArrayOutputStream stream = new ByteArrayOutputStream(); resource.compress(Bitmap.CompressFormat.PNG, 100, stream); - byte[] byteArray = stream.toByteArray(); - - return byteArray; + return stream.toByteArray(); } private void restoreCompass(Bundle savedInstanceState) { @@ -189,10 +187,7 @@ public final class UiSettings { private Drawable decode(byte[] bitmap) { Bitmap compass = BitmapFactory.decodeByteArray(bitmap, 0, bitmap.length); - - Drawable compassImage = new BitmapDrawable(compassView.getResources(), compass); - - return compassImage; + return new BitmapDrawable(compassView.getResources(), compass); } private void initialiseLogo(MapboxMapOptions options, Resources resources) { @@ -202,8 +197,8 @@ public final class UiSettings { if (logoMargins != null) { setLogoMargins(logoMargins[0], logoMargins[1], logoMargins[2], logoMargins[3]); } else { - int sixteenDp = (int) resources.getDimension(R.dimen.mapbox_sixteen_dp); - setLogoMargins(sixteenDp, sixteenDp, sixteenDp, sixteenDp); + int twoDp = (int) resources.getDimension(R.dimen.mapbox_two_dp); + setLogoMargins(twoDp, twoDp, twoDp, twoDp); } } @@ -226,16 +221,12 @@ public final class UiSettings { } private void initialiseAttribution(Context context, MapboxMapOptions options) { - Resources resources = context.getResources(); setAttributionEnabled(options.getAttributionEnabled()); setAttributionGravity(options.getAttributionGravity()); int[] attributionMargins = options.getAttributionMargins(); if (attributionMargins != null) { - setAttributionMargins(attributionMargins[0], attributionMargins[1], attributionMargins[2], attributionMargins[3]); - } else { - int sevenDp = (int) resources.getDimension(R.dimen.mapbox_seven_dp); - int seventySixDp = (int) resources.getDimension(R.dimen.mapbox_seventy_six_dp); - setAttributionMargins(seventySixDp, sevenDp, sevenDp, sevenDp); + setAttributionMargins(attributionMargins[0], attributionMargins[1], + attributionMargins[2], attributionMargins[3]); } int attributionTintColor = options.getAttributionTintColor(); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java index ec80186761..10ecb945ad 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java @@ -227,6 +227,14 @@ public class GeoJsonSource extends Source { nativeSetUrl(url); } + /** + * @return The url or null + */ + @Nullable + public String getUrl() { + return nativeGetUrl(); + } + /** * Queries the source for features. * @@ -243,6 +251,8 @@ public class GeoJsonSource extends Source { protected native void nativeSetUrl(String url); + protected native String nativeGetUrl(); + private native void nativeSetGeoJsonString(String geoJson); private native void nativeSetFeatureCollection(FeatureCollection geoJson); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterSource.java index 98b74afcff..38ed208618 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterSource.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterSource.java @@ -1,5 +1,7 @@ package com.mapbox.mapboxsdk.style.sources; +import android.support.annotation.Nullable; + import java.net.URL; /** @@ -72,8 +74,19 @@ public class RasterSource extends Source { initialize(id, tileSet.toValueObject(), tileSize); } + /** + * @return The url or null + */ + @Nullable + public String getUrl() { + return nativeGetUrl(); + } + protected native void initialize(String layerId, Object payload, int tileSize); @Override protected native void finalize() throws Throwable; + + protected native String nativeGetUrl(); + } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.java index 7230492d0e..9b59cf8967 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.java @@ -76,11 +76,21 @@ public class VectorSource extends Source { return features != null ? Arrays.asList(features) : new ArrayList(); } + /** + * @return The url or null + */ + @Nullable + public String getUrl() { + return nativeGetUrl(); + } + protected native void initialize(String layerId, Object payload); @Override protected native void finalize() throws Throwable; + protected native String nativeGetUrl(); + private native Feature[] querySourceFeatures(String[] sourceLayerId, Object[] filter); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_logo_icon.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_logo_icon.png index c0f4ed2c4c..7568387a8d 100644 Binary files a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_logo_icon.png and b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_logo_icon.png differ diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_logo_icon.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_logo_icon.png index 5a9da3fe39..9cdec5151c 100644 Binary files a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_logo_icon.png and b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_logo_icon.png differ diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_logo_icon.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_logo_icon.png index 194aa64da2..7eec45f4b1 100644 Binary files a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_logo_icon.png and b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_logo_icon.png differ diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_logo_icon.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_logo_icon.png index d1260a16f3..5876056f1c 100644 Binary files a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_logo_icon.png and b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_logo_icon.png differ diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_logo_icon.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_logo_icon.png index 5f9647610a..e5780ccc07 100644 Binary files a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_logo_icon.png and b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_logo_icon.png differ diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_info_icon_default.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_info_icon_default.xml index fa82bb8d9b..65837d65d0 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_info_icon_default.xml +++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_info_icon_default.xml @@ -1,8 +1,8 @@ + android:width="21dp" + android:height="21dp" + android:viewportHeight="24.0" + android:viewportWidth="24.0"> diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_info_icon_selected.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_info_icon_selected.xml index 074928d05a..ccbd1d8d39 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_info_icon_selected.xml +++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_info_icon_selected.xml @@ -1,9 +1,9 @@ + android:width="21dp" + android:height="21dp" + android:viewportHeight="24.0" + android:viewportWidth="24.0"> + android:pathData="M11,17h2v-6h-2v6zm1,-15C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zm0,18c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2V7h-2v2z"/> 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 e6a2677785..6d07de7baa 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 @@ -39,10 +39,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:adjustViewBounds="true" - android:background="@drawable/mapbox_default_bg_selector" android:clickable="true" + android:focusable="true" android:contentDescription="@string/mapbox_attributionsIconContentDescription" - android:padding="7dp" android:src="@drawable/mapbox_info_bg_selector"/> diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_preview.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_preview.xml index d015bc5785..1c1ab0e71b 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_preview.xml +++ b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_preview.xml @@ -1,22 +1,29 @@ + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + android:contentDescription="@null" + android:src="@drawable/mapbox_mapview_preview" + android:layout_alignParentTop="true" + android:layout_alignParentLeft="true" + android:layout_alignParentStart="true"/> @@ -24,18 +31,22 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" - android:layout_marginBottom="@dimen/mapbox_seven_dp" - android:layout_marginLeft="@dimen/mapbox_seventy_six_dp" + android:layout_toEndOf="@+id/logoView" + android:contentDescription="@null" + android:layout_marginBottom="@dimen/mapbox_four_dp" android:background="@drawable/mapbox_default_bg_selector" - android:clickable="true" - android:contentDescription="@string/mapbox_attributionsIconContentDescription" - android:src="@drawable/mapbox_info_bg_selector" /> + android:src="@drawable/mapbox_info_bg_selector" + android:layout_marginLeft="@dimen/mapbox_four_dp" + android:layout_marginStart="@dimen/mapbox_four_dp" + android:layout_toRightOf="@+id/logoView"/> + android:contentDescription="@null" + android:src="@drawable/mapbox_compass_icon"/> diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml index df6983e11d..ce20cb9a8b 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml +++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml @@ -4,10 +4,15 @@ 8dp -2dp 1.5dp - 7dp + @dimen/mapbox_two_dp + @dimen/mapbox_two_dp + @dimen/mapbox_two_dp + @dimen/mapbox_two_dp + 2dp + 4dp 8dp 10dp 16dp - 76dp + 95dp 18dp 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 354f5def6f..a1c46903bf 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 @@ -15,6 +15,8 @@ import com.mapbox.mapboxsdk.style.layers.Layer; import com.mapbox.mapboxsdk.style.layers.Property; import com.mapbox.mapboxsdk.style.layers.PropertyFactory; import com.mapbox.mapboxsdk.style.sources.CannotAddSourceException; +import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; +import com.mapbox.mapboxsdk.style.sources.RasterSource; import com.mapbox.mapboxsdk.style.sources.Source; import com.mapbox.mapboxsdk.style.sources.VectorSource; import com.mapbox.mapboxsdk.testapp.R; @@ -28,6 +30,8 @@ import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; +import java.net.MalformedURLException; +import java.net.URL; import java.util.List; import timber.log.Timber; @@ -190,6 +194,35 @@ public class RuntimeStyleTests extends BaseActivityTest { onView(withId(R.id.mapView)).perform(new AddRemoveSourceAction()); } + @Test + public void testVectorSourceUrlGetter() { + validateTestSetup(); + + VectorSource source = new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2"); + mapboxMap.addSource(source); + assertEquals("mapbox://mapbox.mapbox-terrain-v2", source.getUrl()); + } + + @Test + public void testRasterSourceUrlGetter() { + validateTestSetup(); + + RasterSource source = new RasterSource("my-source", "mapbox://mapbox.mapbox-terrain-v2"); + mapboxMap.addSource(source); + assertEquals("mapbox://mapbox.mapbox-terrain-v2", source.getUrl()); + } + + @Test + public void testGeoJsonSourceUrlGetter() throws MalformedURLException { + validateTestSetup(); + + GeoJsonSource source = new GeoJsonSource("my-source"); + mapboxMap.addSource(source); + assertNull(source.getUrl()); + source.setUrl(new URL("http://mapbox.com/my-file.json")); + assertEquals("http://mapbox.com/my-file.json", source.getUrl()); + } + /** * https://github.com/mapbox/mapbox-gl-native/issues/7973 */ diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraPositionActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraPositionActivity.java index 08399f3b3e..60518239c8 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraPositionActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraPositionActivity.java @@ -43,10 +43,35 @@ public class CameraPositionActivity extends AppCompatActivity implements OnMapRe public void onMapReady(@NonNull final MapboxMap mapboxMap) { this.mapboxMap = mapboxMap; - mapboxMap.setOnCameraChangeListener(new MapboxMap.OnCameraChangeListener() { + mapboxMap.setOnCameraIdleListener(new MapboxMap.OnCameraIdleListener() { @Override - public void onCameraChange(CameraPosition position) { - Timber.w("OnCameraChange: " + position); + public void onCameraIdle() { + Timber.e("OnCameraIdle"); + } + }); + + mapboxMap.setOnCameraMoveCancelListener(new MapboxMap.OnCameraMoveCanceledListener() { + @Override + public void onCameraMoveCanceled() { + Timber.e("OnCameraMoveCanceled"); + } + }); + + mapboxMap.setOnCameraMoveListener(new MapboxMap.OnCameraMoveListener() { + @Override + public void onCameraMove() { + Timber.e("OnCameraMove"); + } + }); + + mapboxMap.setOnCameraMoveStartedistener(new MapboxMap.OnCameraMoveStartedListener() { + + private final String[] REASONS = {"REASON_API_GESTURE", "REASON_DEVELOPER_ANIMATION", "REASON_API_ANIMATION"}; + + @Override + public void onCameraMoveStarted(int reason) { + // reason ranges from 1 <-> 3 + Timber.e("OnCameraMoveStarted: %s", REASONS[reason - 1]); } }); diff --git a/platform/android/gradle/wrapper/gradle-wrapper.properties b/platform/android/gradle/wrapper/gradle-wrapper.properties index c7ad166b13..1d35abd7b2 100644 --- a/platform/android/gradle/wrapper/gradle-wrapper.properties +++ b/platform/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip \ No newline at end of file diff --git a/platform/android/src/style/sources/geojson_source.cpp b/platform/android/src/style/sources/geojson_source.cpp index 9b56446e31..780cc4b6f6 100644 --- a/platform/android/src/style/sources/geojson_source.cpp +++ b/platform/android/src/style/sources/geojson_source.cpp @@ -97,6 +97,11 @@ namespace android { source.as()->GeoJSONSource::setURL(jni::Make(env, url)); } + jni::String GeoJSONSource::getURL(jni::JNIEnv& env) { + optional url = source.as()->GeoJSONSource::getURL(); + return url ? jni::Make(env, *url) : jni::String(); + } + jni::Array> GeoJSONSource::querySourceFeatures(jni::JNIEnv& env, jni::Array> jfilter) { using namespace mbgl::android::conversion; @@ -133,6 +138,7 @@ namespace android { METHOD(&GeoJSONSource::setFeature, "nativeSetFeature"), METHOD(&GeoJSONSource::setGeometry, "nativeSetGeometry"), METHOD(&GeoJSONSource::setURL, "nativeSetUrl"), + METHOD(&GeoJSONSource::getURL, "nativeGetUrl"), METHOD(&GeoJSONSource::querySourceFeatures, "querySourceFeatures") ); } diff --git a/platform/android/src/style/sources/geojson_source.hpp b/platform/android/src/style/sources/geojson_source.hpp index 51ea452fb2..938a20612c 100644 --- a/platform/android/src/style/sources/geojson_source.hpp +++ b/platform/android/src/style/sources/geojson_source.hpp @@ -38,6 +38,8 @@ public: jni::Array> querySourceFeatures(jni::JNIEnv&, jni::Array> jfilter); + jni::String getURL(jni::JNIEnv&); + jni::jobject* createJavaPeer(jni::JNIEnv&); }; // class GeoJSONSource diff --git a/platform/android/src/style/sources/raster_source.cpp b/platform/android/src/style/sources/raster_source.cpp index 0234901a77..32fdb163b0 100644 --- a/platform/android/src/style/sources/raster_source.cpp +++ b/platform/android/src/style/sources/raster_source.cpp @@ -28,6 +28,11 @@ namespace android { RasterSource::~RasterSource() = default; + jni::String RasterSource::getURL(jni::JNIEnv& env) { + optional url = source.as()->RasterSource::getURL(); + return url ? jni::Make(env, *url) : jni::String(); + } + jni::Class RasterSource::javaClass; jni::jobject* RasterSource::createJavaPeer(jni::JNIEnv& env) { @@ -46,7 +51,8 @@ namespace android { env, RasterSource::javaClass, "nativePtr", std::make_unique, jni::jint>, "initialize", - "finalize" + "finalize", + METHOD(&RasterSource::getURL, "nativeGetUrl") ); } diff --git a/platform/android/src/style/sources/raster_source.hpp b/platform/android/src/style/sources/raster_source.hpp index 6600096f6d..a79ccc10a4 100644 --- a/platform/android/src/style/sources/raster_source.hpp +++ b/platform/android/src/style/sources/raster_source.hpp @@ -22,6 +22,8 @@ public: ~RasterSource(); + jni::String getURL(jni::JNIEnv&); + jni::jobject* createJavaPeer(jni::JNIEnv&); }; // class RasterSource diff --git a/platform/android/src/style/sources/vector_source.cpp b/platform/android/src/style/sources/vector_source.cpp index a8f74df142..e2d9f60dec 100644 --- a/platform/android/src/style/sources/vector_source.cpp +++ b/platform/android/src/style/sources/vector_source.cpp @@ -34,6 +34,11 @@ namespace android { VectorSource::~VectorSource() = default; + jni::String VectorSource::getURL(jni::JNIEnv& env) { + optional url = source.as()->VectorSource::getURL(); + return url ? jni::Make(env, *url) : jni::String(); + } + jni::Array> VectorSource::querySourceFeatures(jni::JNIEnv& env, jni::Array jSourceLayerIds, jni::Array> jfilter) { @@ -66,7 +71,8 @@ namespace android { std::make_unique>, "initialize", "finalize", - METHOD(&VectorSource::querySourceFeatures, "querySourceFeatures") + METHOD(&VectorSource::querySourceFeatures, "querySourceFeatures"), + METHOD(&VectorSource::getURL, "nativeGetUrl") ); } diff --git a/platform/android/src/style/sources/vector_source.hpp b/platform/android/src/style/sources/vector_source.hpp index cac687bb6f..643b468338 100644 --- a/platform/android/src/style/sources/vector_source.hpp +++ b/platform/android/src/style/sources/vector_source.hpp @@ -26,6 +26,8 @@ public: jni::Array> querySourceFeatures(jni::JNIEnv&, jni::Array, jni::Array> jfilter); + jni::String getURL(jni::JNIEnv&); + jni::jobject* createJavaPeer(jni::JNIEnv&); }; // class VectorSource diff --git a/platform/default/default_file_source.cpp b/platform/default/default_file_source.cpp index 27c3950e2a..7db0b85461 100644 --- a/platform/default/default_file_source.cpp +++ b/platform/default/default_file_source.cpp @@ -200,12 +200,16 @@ std::string DefaultFileSource::getAccessToken() const { } void DefaultFileSource::setResourceTransform(std::function transform) { - auto loop = util::RunLoop::Get(); - thread->invoke(&Impl::setResourceTransform, [loop, transform](Resource::Kind kind_, std::string&& url_, auto callback_) { - return loop->invokeWithCallback([transform](Resource::Kind kind, std::string&& url, auto callback) { - callback(transform(kind, std::move(url))); - }, kind_, std::move(url_), callback_); - }); + if (transform) { + auto loop = util::RunLoop::Get(); + thread->invoke(&Impl::setResourceTransform, [loop, transform](Resource::Kind kind_, std::string&& url_, auto callback_) { + return loop->invokeWithCallback([transform](Resource::Kind kind, std::string&& url, auto callback) { + callback(transform(kind, std::move(url))); + }, kind_, std::move(url_), callback_); + }); + } else { + thread->invoke(&Impl::setResourceTransform, nullptr); + } } std::unique_ptr DefaultFileSource::request(const Resource& resource, Callback callback) { -- cgit v1.2.1 From 59442167b16ec5b92c29aad4670340b740a0a9e4 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Mon, 15 May 2017 13:39:34 +0200 Subject: [android] - MarkerView deselect events with OnMarkerViewClickListener integration (#8996) --- .../java/com/mapbox/mapboxsdk/maps/AnnotationManager.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java index 6553b64592..e811470d64 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java @@ -670,12 +670,15 @@ class AnnotationManager { for (Marker nearbyMarker : nearbyMarkers) { for (Marker selectedMarker : selectedMarkers) { if (nearbyMarker.equals(selectedMarker)) { - if (onMarkerClickListener != null) { - // end developer has provided a custom click listener + if (nearbyMarker instanceof MarkerView) { + handledDefaultClick = markerViewManager.onClickMarkerView((MarkerView) nearbyMarker); + } else if (onMarkerClickListener != null) { handledDefaultClick = onMarkerClickListener.onMarkerClick(nearbyMarker); - if (!handledDefaultClick) { - deselectMarker(nearbyMarker); - } + } + + if (!handledDefaultClick) { + // only deselect marker if user didn't handle the click event themselves + deselectMarker(nearbyMarker); } return true; } -- cgit v1.2.1 From 627455c7cc6938e8a05508824450e34dfa75c15e Mon Sep 17 00:00:00 2001 From: Tobrun Date: Mon, 15 May 2017 14:39:11 +0200 Subject: [android] - publish SNAPSHOT from release 5.1.0 branch (#8995) --- circle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index 4ce00872b4..6bced990de 100644 --- a/circle.yml +++ b/circle.yml @@ -133,4 +133,4 @@ jobs: - deploy: name: Publish to Maven command: | - if [ "${CIRCLE_BRANCH}" == "release-android-v5.1.0-beta.2" ]; then make run-android-upload-archives ; fi + if [ "${CIRCLE_BRANCH}" == "release-ios-v3.6.0-android-v5.1.0" ]; then make run-android-upload-archives ; fi -- cgit v1.2.1 From c7acb5516b7575feb20f20d6f6cfaabede97c948 Mon Sep 17 00:00:00 2001 From: Jordan Kiley Date: Mon, 15 May 2017 11:27:10 -0700 Subject: [ios, macos] edited identity interpolation mode documentation (#8657) --- platform/darwin/src/MGLStyleValue.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/darwin/src/MGLStyleValue.h b/platform/darwin/src/MGLStyleValue.h index 70074c8a13..2bb3aca4f4 100644 --- a/platform/darwin/src/MGLStyleValue.h +++ b/platform/darwin/src/MGLStyleValue.h @@ -75,9 +75,9 @@ typedef NS_ENUM(NSUInteger, MGLInterpolationMode) { */ MGLInterpolationModeCategorical, /** - Values between two stops are not interpolated. Instead, values are set to their - input value. Use identity interpolation mode to show attribute values that can be - used as style values. + Values between two stops are not interpolated. Instead, for any given feature, the + style value matches a value in that feature’s attributes dictionary. Use identity + interpolation mode to show attribute values that can be used as style values. */ MGLInterpolationModeIdentity }; -- cgit v1.2.1 From 30b919196b72351c43a5834b66a36068c0588fe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Tue, 9 May 2017 18:36:20 -0700 Subject: [ios, macos] Factored out tile URL template guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Factored out redundant tile URL template documentation from the MGLRasterSource and MGLVectorSource documentation into a jazzy guide. This documentation used to live in one place, on a method on MGLTileSource, but that method had to be moved to MGLTileSource’s concrete subclasses. A jazzy guide is easier to link to, in any case. --- .../darwin/docs/guides/Tile URL Templates.md.ejs | 109 +++++++++++++++++++++ platform/darwin/scripts/generate-style-code.js | 13 ++- platform/darwin/src/MGLRasterSource.h | 91 +---------------- platform/darwin/src/MGLVectorSource.h | 91 +---------------- platform/ios/docs/guides/Tile URL Templates.md | 99 +++++++++++++++++++ platform/ios/jazzy.yml | 1 + platform/macos/docs/guides/Tile URL Templates.md | 98 ++++++++++++++++++ platform/macos/jazzy.yml | 1 + 8 files changed, 326 insertions(+), 177 deletions(-) create mode 100644 platform/darwin/docs/guides/Tile URL Templates.md.ejs create mode 100644 platform/ios/docs/guides/Tile URL Templates.md create mode 100644 platform/macos/docs/guides/Tile URL Templates.md diff --git a/platform/darwin/docs/guides/Tile URL Templates.md.ejs b/platform/darwin/docs/guides/Tile URL Templates.md.ejs new file mode 100644 index 0000000000..78fb297138 --- /dev/null +++ b/platform/darwin/docs/guides/Tile URL Templates.md.ejs @@ -0,0 +1,109 @@ +<% + const os = locals.os; + const iOS = os === 'iOS'; + //const macOS = os === 'macOS'; + //const cocoaPrefix = iOS ? 'UI' : 'NS'; +-%> + +# Tile URL Templates + +`MGLTileSource` objects, specifically `MGLRasterSource` and `MGLVectorSource` +objects, can be created using an initializer that accepts an array of tile URL +templates. Tile URL templates are strings that specify the URLs of the vector +tiles or raster tile images to load. A template resembles an absolute URL, but +with any number of placeholder strings that the source evaluates based on the +tile it needs to load. For example: + +* `http://www.example.com/tiles/{z}/{x}/{y}.pbf` could be + evaluated as `http://www.example.com/tiles/14/6/9.pbf`. +* `http://www.example.com/tiles/{z}/{x}/{y}{ratio}.png` could be + evaluated as `http://www.example.com/tiles/14/6/9@2x.png`. + +Tile URL templates are also used to define tilesets in TileJSON manifests or +[`raster`](https://www.mapbox.com/mapbox-gl-js/style-spec/#sources-raster-tiles) +and +[`vector`](https://www.mapbox.com/mapbox-gl-js/style-spec/#sources-vector-tiles) +sources in style JSON files. See the +[TileJSON specification](https://github.com/mapbox/tilejson-spec/tree/master/2.2.0) +for information about tile URL templates in the context of a TileJSON or style +JSON file. + +Tile sources support the following placeholder strings in tile URL templates, +all of which are optional: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Placeholder stringDescription
{x}The index of the tile along the map’s x axis according to Spherical + Mercator projection. If the value is 0, the tile’s left edge corresponds + to the 180th meridian west. If the value is 2z−1, + the tile’s right edge corresponds to the 180th meridian east.
{y}The index of the tile along the map’s y axis according to Spherical + Mercator projection. If the value is 0, the tile’s tile edge corresponds + to arctan(sinh(π)), or approximately 85.0511 degrees north. If the value + is 2z−1, the tile’s bottom edge corresponds to + −arctan(sinh(π)), or approximately 85.0511 degrees south. The y axis is + inverted if the options parameter contains + MGLTileSourceOptionTileCoordinateSystem with a value of + MGLTileCoordinateSystemTMS.
{z}The tile’s zoom level. At zoom level 0, each tile covers the entire + world map; at zoom level 1, it covers ¼ of the world; at zoom level 2, + 116 of the world, and so on. For tiles loaded by + a MGLRasterSource object, whether the tile zoom level + matches the map’s current zoom level depends on the value of the + source’s tile size as specified in the + MGLTileSourceOptionTileSize key of the options + parameter.
{bbox-epsg-3857}The tile’s bounding box, expressed as a comma-separated list of the + tile’s western, southern, eastern, and northern extents according to + Spherical Mercator (EPSG:3857) projection. The bounding box is typically + used with map services conforming to the + Web Map Service + protocol.
{quadkey}A quadkey indicating both the tile’s location and its zoom level. The + quadkey is typically used with + Bing Maps. +
{ratio}A suffix indicating the resolution of the tile image. The suffix is the + empty string for standard resolution displays and @2x for +<% if (iOS) { -%> + Retina displays, including displays for which UIScreen.scale + is 3. +<% } else { -%> + Retina displays. +<% } -%> +
{prefix}Two hexadecimal digits chosen such that each visible tile has a + different prefix. The prefix is typically used for domain sharding.
+ +For more information about the `{x}`, `{y}`, and `{z}` placeholder strings, +consult the +[OpenStreetMap Wiki](https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames). diff --git a/platform/darwin/scripts/generate-style-code.js b/platform/darwin/scripts/generate-style-code.js index 330a8f1d03..7efc8d441c 100644 --- a/platform/darwin/scripts/generate-style-code.js +++ b/platform/darwin/scripts/generate-style-code.js @@ -522,8 +522,9 @@ global.setSourceLayer = function() { const layerH = ejs.compile(fs.readFileSync('platform/darwin/src/MGLStyleLayer.h.ejs', 'utf8'), { strict: true }); const layerM = ejs.compile(fs.readFileSync('platform/darwin/src/MGLStyleLayer.mm.ejs', 'utf8'), { strict: true}); const testLayers = ejs.compile(fs.readFileSync('platform/darwin/test/MGLStyleLayerTests.mm.ejs', 'utf8'), { strict: true}); -const guideMD = ejs.compile(fs.readFileSync('platform/darwin/docs/guides/For Style Authors.md.ejs', 'utf8'), { strict: true }); +const forStyleAuthorsMD = ejs.compile(fs.readFileSync('platform/darwin/docs/guides/For Style Authors.md.ejs', 'utf8'), { strict: true }); const ddsGuideMD = ejs.compile(fs.readFileSync('platform/darwin/docs/guides/Using Style Functions at Runtime.md.ejs', 'utf8'), { strict: true }); +const templatesMD = ejs.compile(fs.readFileSync('platform/darwin/docs/guides/Tile URL Templates.md.ejs', 'utf8'), { strict: true }); const layers = _(spec.layer.type.values).map((value, layerType) => { const layoutProperties = Object.keys(spec[`layout_${layerType}`]).reduce((memo, name) => { @@ -635,12 +636,12 @@ global.guideExample = function (guide, exampleId, os) { return '```swift\n' + example + '\n```'; }; -fs.writeFileSync(`platform/ios/docs/guides/For Style Authors.md`, guideMD({ +fs.writeFileSync(`platform/ios/docs/guides/For Style Authors.md`, forStyleAuthorsMD({ os: 'iOS', renamedProperties: renamedPropertiesByLayerType, layers: layers, })); -fs.writeFileSync(`platform/macos/docs/guides/For Style Authors.md`, guideMD({ +fs.writeFileSync(`platform/macos/docs/guides/For Style Authors.md`, forStyleAuthorsMD({ os: 'macOS', renamedProperties: renamedPropertiesByLayerType, layers: layers, @@ -651,3 +652,9 @@ fs.writeFileSync(`platform/ios/docs/guides/Using Style Functions at Runtime.md`, fs.writeFileSync(`platform/macos/docs/guides/Using Style Functions at Runtime.md`, ddsGuideMD({ os: 'macOS', })); +fs.writeFileSync(`platform/ios/docs/guides/Tile URL Templates.md`, templatesMD({ + os: 'iOS', +})); +fs.writeFileSync(`platform/macos/docs/guides/Tile URL Templates.md`, templatesMD({ + os: 'macOS', +})); diff --git a/platform/darwin/src/MGLRasterSource.h b/platform/darwin/src/MGLRasterSource.h index 519784f4f1..4f4b7c96c3 100644 --- a/platform/darwin/src/MGLRasterSource.h +++ b/platform/darwin/src/MGLRasterSource.h @@ -108,96 +108,13 @@ MGL_EXPORT Returns a raster source initialized an identifier, tile URL templates, and options. + Tile URL templates are strings that specify the URLs of the raster tile images + to load. See the “Tile URL Templates” + guide for information about the format of a tile URL template. + After initializing and configuring the source, add it to a map view’s style using the `-[MGLStyle addSource:]` method. - #### Tile URL templates - - Tile URL templates are strings that specify the URLs of the tile images to - load. Each template resembles an absolute URL, but with any number of - placeholder strings that the source evaluates based on the tile it needs to - load. For example: - -

    -
  • http://www.example.com/tiles/{z}/{x}/{y}.pbf could be - evaluated as http://www.example.com/tiles/14/6/9.pbf.
  • -
  • http://www.example.com/tiles/{z}/{x}/{y}{ratio}.png could be - evaluated as http://www.example.com/tiles/14/6/9@2x.png.
  • -
- - Tile sources support the following placeholder strings in tile URL templates, - all of which are optional: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Placeholder stringDescription
{x}The index of the tile along the map’s x axis according to Spherical - Mercator projection. If the value is 0, the tile’s left edge corresponds - to the 180th meridian west. If the value is 2z−1, - the tile’s right edge corresponds to the 180th meridian east.
{y}The index of the tile along the map’s y axis according to Spherical - Mercator projection. If the value is 0, the tile’s tile edge corresponds - to arctan(sinh(π)), or approximately 85.0511 degrees north. If the value - is 2z−1, the tile’s bottom edge corresponds to - −arctan(sinh(π)), or approximately 85.0511 degrees south. The y axis is - inverted if the options parameter contains - MGLTileSourceOptionTileCoordinateSystem with a value of - MGLTileCoordinateSystemTMS.
{z}The tile’s zoom level. At zoom level 0, each tile covers the entire - world map; at zoom level 1, it covers ¼ of the world; at zoom level 2, - 116 of the world, and so on. For tiles loaded by - a MGLRasterSource object, whether the tile zoom level - matches the map’s current zoom level depends on the value of the - source’s tile size as specified in the - MGLTileSourceOptionTileSize key of the - options parameter.
{bbox-epsg-3857}The tile’s bounding box, expressed as a comma-separated list of the - tile’s western, southern, eastern, and northern extents according to - Spherical Mercator (EPSG:3857) projection. The bounding box is typically - used with map services conforming to the - Web Map Service - protocol.
{quadkey}A quadkey indicating both the tile’s location and its zoom level. The - quadkey is typically used with - Bing Maps. -
{ratio}A suffix indicating the resolution of the tile image. The suffix is the - empty string for standard resolution displays and @2x for - Retina displays, including displays for which - NSScreen.backingScaleFactor or UIScreen.scale - is 3.
{prefix}Two hexadecimal digits chosen such that each visible tile has a - different prefix. The prefix is typically used for domain sharding.
- - For more information about the `{x}`, `{y}`, and `{z}` placeholder strings, - consult the - OpenStreetMap Wiki. - @param identifier A string that uniquely identifies the source in the style to which it is added. @param tileURLTemplates An array of tile URL template strings. Only the first diff --git a/platform/darwin/src/MGLVectorSource.h b/platform/darwin/src/MGLVectorSource.h index a48434f7a3..968be3c0e0 100644 --- a/platform/darwin/src/MGLVectorSource.h +++ b/platform/darwin/src/MGLVectorSource.h @@ -74,96 +74,13 @@ MGL_EXPORT Returns a vector source initialized an identifier, tile URL templates, and options. + Tile URL templates are strings that specify the URLs of the vector tiles to + load. See the “Tile URL Templates” + guide for information about the format of a tile URL template. + After initializing and configuring the source, add it to a map view’s style using the `-[MGLStyle addSource:]` method. - #### Tile URL templates - - Tile URL templates are strings that specify the URLs of the tile images to - load. Each template resembles an absolute URL, but with any number of - placeholder strings that the source evaluates based on the tile it needs to - load. For example: - -
    -
  • http://www.example.com/tiles/{z}/{x}/{y}.pbf could be - evaluated as http://www.example.com/tiles/14/6/9.pbf.
  • -
  • http://www.example.com/tiles/{z}/{x}/{y}{ratio}.png could be - evaluated as http://www.example.com/tiles/14/6/9@2x.png.
  • -
- - Tile sources support the following placeholder strings in tile URL templates, - all of which are optional: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Placeholder stringDescription
{x}The index of the tile along the map’s x axis according to Spherical - Mercator projection. If the value is 0, the tile’s left edge corresponds - to the 180th meridian west. If the value is 2z−1, - the tile’s right edge corresponds to the 180th meridian east.
{y}The index of the tile along the map’s y axis according to Spherical - Mercator projection. If the value is 0, the tile’s tile edge corresponds - to arctan(sinh(π)), or approximately 85.0511 degrees north. If the value - is 2z−1, the tile’s bottom edge corresponds to - −arctan(sinh(π)), or approximately 85.0511 degrees south. The y axis is - inverted if the options parameter contains - MGLTileSourceOptionTileCoordinateSystem with a value of - MGLTileCoordinateSystemTMS.
{z}The tile’s zoom level. At zoom level 0, each tile covers the entire - world map; at zoom level 1, it covers ¼ of the world; at zoom level 2, - 116 of the world, and so on. For tiles loaded by - a MGLRasterSource object, whether the tile zoom level - matches the map’s current zoom level depends on the value of the - source’s tile size as specified in the - MGLTileSourceOptionTileSize key of the - options parameter.
{bbox-epsg-3857}The tile’s bounding box, expressed as a comma-separated list of the - tile’s western, southern, eastern, and northern extents according to - Spherical Mercator (EPSG:3857) projection. The bounding box is typically - used with map services conforming to the - Web Map Service - protocol.
{quadkey}A quadkey indicating both the tile’s location and its zoom level. The - quadkey is typically used with - Bing Maps. -
{ratio}A suffix indicating the resolution of the tile image. The suffix is the - empty string for standard resolution displays and @2x for - Retina displays, including displays for which - NSScreen.backingScaleFactor or UIScreen.scale - is 3.
{prefix}Two hexadecimal digits chosen such that each visible tile has a - different prefix. The prefix is typically used for domain sharding.
- - For more information about the `{x}`, `{y}`, and `{z}` placeholder strings, - consult the - OpenStreetMap Wiki. - @param identifier A string that uniquely identifies the source in the style to which it is added. @param tileURLTemplates An array of tile URL template strings. Only the first diff --git a/platform/ios/docs/guides/Tile URL Templates.md b/platform/ios/docs/guides/Tile URL Templates.md new file mode 100644 index 0000000000..f61d2ea33a --- /dev/null +++ b/platform/ios/docs/guides/Tile URL Templates.md @@ -0,0 +1,99 @@ + +# Tile URL Templates + +`MGLTileSource` objects, specifically `MGLRasterSource` and `MGLVectorSource` +objects, can be created using an initializer that accepts an array of tile URL +templates. Tile URL templates are strings that specify the URLs of the vector +tiles or raster tile images to load. A template resembles an absolute URL, but +with any number of placeholder strings that the source evaluates based on the +tile it needs to load. For example: + +* `http://www.example.com/tiles/{z}/{x}/{y}.pbf` could be + evaluated as `http://www.example.com/tiles/14/6/9.pbf`. +* `http://www.example.com/tiles/{z}/{x}/{y}{ratio}.png` could be + evaluated as `http://www.example.com/tiles/14/6/9@2x.png`. + +Tile URL templates are also used to define tilesets in TileJSON manifests or +[`raster`](https://www.mapbox.com/mapbox-gl-js/style-spec/#sources-raster-tiles) +and +[`vector`](https://www.mapbox.com/mapbox-gl-js/style-spec/#sources-vector-tiles) +sources in style JSON files. See the +[TileJSON specification](https://github.com/mapbox/tilejson-spec/tree/master/2.2.0) +for information about tile URL templates in the context of a TileJSON or style +JSON file. + +Tile sources support the following placeholder strings in tile URL templates, +all of which are optional: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Placeholder stringDescription
{x}The index of the tile along the map’s x axis according to Spherical + Mercator projection. If the value is 0, the tile’s left edge corresponds + to the 180th meridian west. If the value is 2z−1, + the tile’s right edge corresponds to the 180th meridian east.
{y}The index of the tile along the map’s y axis according to Spherical + Mercator projection. If the value is 0, the tile’s tile edge corresponds + to arctan(sinh(π)), or approximately 85.0511 degrees north. If the value + is 2z−1, the tile’s bottom edge corresponds to + −arctan(sinh(π)), or approximately 85.0511 degrees south. The y axis is + inverted if the options parameter contains + MGLTileSourceOptionTileCoordinateSystem with a value of + MGLTileCoordinateSystemTMS.
{z}The tile’s zoom level. At zoom level 0, each tile covers the entire + world map; at zoom level 1, it covers ¼ of the world; at zoom level 2, + 116 of the world, and so on. For tiles loaded by + a MGLRasterSource object, whether the tile zoom level + matches the map’s current zoom level depends on the value of the + source’s tile size as specified in the + MGLTileSourceOptionTileSize key of the options + parameter.
{bbox-epsg-3857}The tile’s bounding box, expressed as a comma-separated list of the + tile’s western, southern, eastern, and northern extents according to + Spherical Mercator (EPSG:3857) projection. The bounding box is typically + used with map services conforming to the + Web Map Service + protocol.
{quadkey}A quadkey indicating both the tile’s location and its zoom level. The + quadkey is typically used with + Bing Maps. +
{ratio}A suffix indicating the resolution of the tile image. The suffix is the + empty string for standard resolution displays and @2x for + Retina displays, including displays for which UIScreen.scale + is 3. +
{prefix}Two hexadecimal digits chosen such that each visible tile has a + different prefix. The prefix is typically used for domain sharding.
+ +For more information about the `{x}`, `{y}`, and `{z}` placeholder strings, +consult the +[OpenStreetMap Wiki](https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames). diff --git a/platform/ios/jazzy.yml b/platform/ios/jazzy.yml index e0ce29beba..638abaaf6c 100644 --- a/platform/ios/jazzy.yml +++ b/platform/ios/jazzy.yml @@ -23,6 +23,7 @@ custom_categories: - Working with Mapbox Studio - Working with GeoJSON Data - For Style Authors + - Tile URL Templates - Info.plist Keys - Gesture Recognizers - name: Maps diff --git a/platform/macos/docs/guides/Tile URL Templates.md b/platform/macos/docs/guides/Tile URL Templates.md new file mode 100644 index 0000000000..01672c6686 --- /dev/null +++ b/platform/macos/docs/guides/Tile URL Templates.md @@ -0,0 +1,98 @@ + +# Tile URL Templates + +`MGLTileSource` objects, specifically `MGLRasterSource` and `MGLVectorSource` +objects, can be created using an initializer that accepts an array of tile URL +templates. Tile URL templates are strings that specify the URLs of the vector +tiles or raster tile images to load. A template resembles an absolute URL, but +with any number of placeholder strings that the source evaluates based on the +tile it needs to load. For example: + +* `http://www.example.com/tiles/{z}/{x}/{y}.pbf` could be + evaluated as `http://www.example.com/tiles/14/6/9.pbf`. +* `http://www.example.com/tiles/{z}/{x}/{y}{ratio}.png` could be + evaluated as `http://www.example.com/tiles/14/6/9@2x.png`. + +Tile URL templates are also used to define tilesets in TileJSON manifests or +[`raster`](https://www.mapbox.com/mapbox-gl-js/style-spec/#sources-raster-tiles) +and +[`vector`](https://www.mapbox.com/mapbox-gl-js/style-spec/#sources-vector-tiles) +sources in style JSON files. See the +[TileJSON specification](https://github.com/mapbox/tilejson-spec/tree/master/2.2.0) +for information about tile URL templates in the context of a TileJSON or style +JSON file. + +Tile sources support the following placeholder strings in tile URL templates, +all of which are optional: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Placeholder stringDescription
{x}The index of the tile along the map’s x axis according to Spherical + Mercator projection. If the value is 0, the tile’s left edge corresponds + to the 180th meridian west. If the value is 2z−1, + the tile’s right edge corresponds to the 180th meridian east.
{y}The index of the tile along the map’s y axis according to Spherical + Mercator projection. If the value is 0, the tile’s tile edge corresponds + to arctan(sinh(π)), or approximately 85.0511 degrees north. If the value + is 2z−1, the tile’s bottom edge corresponds to + −arctan(sinh(π)), or approximately 85.0511 degrees south. The y axis is + inverted if the options parameter contains + MGLTileSourceOptionTileCoordinateSystem with a value of + MGLTileCoordinateSystemTMS.
{z}The tile’s zoom level. At zoom level 0, each tile covers the entire + world map; at zoom level 1, it covers ¼ of the world; at zoom level 2, + 116 of the world, and so on. For tiles loaded by + a MGLRasterSource object, whether the tile zoom level + matches the map’s current zoom level depends on the value of the + source’s tile size as specified in the + MGLTileSourceOptionTileSize key of the options + parameter.
{bbox-epsg-3857}The tile’s bounding box, expressed as a comma-separated list of the + tile’s western, southern, eastern, and northern extents according to + Spherical Mercator (EPSG:3857) projection. The bounding box is typically + used with map services conforming to the + Web Map Service + protocol.
{quadkey}A quadkey indicating both the tile’s location and its zoom level. The + quadkey is typically used with + Bing Maps. +
{ratio}A suffix indicating the resolution of the tile image. The suffix is the + empty string for standard resolution displays and @2x for + Retina displays. +
{prefix}Two hexadecimal digits chosen such that each visible tile has a + different prefix. The prefix is typically used for domain sharding.
+ +For more information about the `{x}`, `{y}`, and `{z}` placeholder strings, +consult the +[OpenStreetMap Wiki](https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames). diff --git a/platform/macos/jazzy.yml b/platform/macos/jazzy.yml index 3c24b351cc..53f260b242 100644 --- a/platform/macos/jazzy.yml +++ b/platform/macos/jazzy.yml @@ -20,6 +20,7 @@ custom_categories: - Working with GeoJSON Data - For Style Authors - Using Style Functions at Runtime + - Tile URL Templates - Info.plist Keys - name: Maps children: -- cgit v1.2.1 From 4f90d7a56608d6962cfb86505dfeba92b8cd3154 Mon Sep 17 00:00:00 2001 From: Jordan Kiley Date: Wed, 17 May 2017 15:46:27 -0700 Subject: [ios] Telemetry button in modal view controllers (#9027) Fixes #8980. --- platform/ios/src/MGLMapView.mm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index a4c9f5194c..4054099dbd 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -1999,9 +1999,10 @@ public: }]; [alertController addAction:participateAction]; - [self.window.rootViewController presentViewController:alertController - animated:YES - completion:NULL]; + UIViewController *viewController = [self.window.rootViewController mgl_topMostViewController]; + [viewController presentViewController:alertController + animated:YES + completion:NULL]; } #pragma mark - Properties - -- cgit v1.2.1 From eb83c7250933b7d3705a3508976c69571a9b9d4c Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 19 May 2017 09:14:54 +0200 Subject: [android] - bump tools and support lib version due to SNAPSHOT dependencies (#9046) * [android] - bump tools and support lib version for SNAPSHOT dependencies * revert unsupported Circle CI build tools version --- platform/android/MapboxGLAndroidSDK/build.gradle | 4 +--- platform/android/dependencies.gradle | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/build.gradle b/platform/android/MapboxGLAndroidSDK/build.gradle index fca36237c3..5e19e94f5d 100644 --- a/platform/android/MapboxGLAndroidSDK/build.gradle +++ b/platform/android/MapboxGLAndroidSDK/build.gradle @@ -6,9 +6,7 @@ dependencies { compile rootProject.ext.dep.supportDesign compile rootProject.ext.dep.timber compile rootProject.ext.dep.okhttp3 - compile(rootProject.ext.dep.lost) { - exclude module: 'support-compat' - } + compile rootProject.ext.dep.lost // Mapbox Android Services (GeoJSON support) compile(rootProject.ext.dep.mapboxJavaGeoJSON) { diff --git a/platform/android/dependencies.gradle b/platform/android/dependencies.gradle index bbf1fb075d..eb717ba600 100644 --- a/platform/android/dependencies.gradle +++ b/platform/android/dependencies.gradle @@ -8,7 +8,7 @@ ext { versionName = "5.0.0" mapboxServicesVersion = "2.2.0-SNAPSHOT" - supportLibVersion = "25.1.0" + supportLibVersion = "25.3.1" wearableVersion = '2.0.0' espressoVersion = '2.2.2' testRunnerVersion = '0.5' -- cgit v1.2.1 From f0b0167640fa6cbd852ec1bed237277ee7c5f06d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Thu, 18 May 2017 12:39:03 +0200 Subject: [core] Make destructor virtual to avoid object splicing during destruction --- src/mbgl/style/sources/geojson_source_impl.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mbgl/style/sources/geojson_source_impl.hpp b/src/mbgl/style/sources/geojson_source_impl.hpp index e8b881d05e..dece1269f8 100644 --- a/src/mbgl/style/sources/geojson_source_impl.hpp +++ b/src/mbgl/style/sources/geojson_source_impl.hpp @@ -13,6 +13,7 @@ namespace style { class GeoJSONData { public: + virtual ~GeoJSONData() = default; virtual mapbox::geometry::feature_collection getTile(const CanonicalTileID&) = 0; }; -- cgit v1.2.1 From b52e171b6737522fe5e7739646f523becd315381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Thu, 18 May 2017 14:30:20 +0200 Subject: [core] add error for non-virtual destructor deletes + add virtual dtors --- CMakeLists.txt | 2 +- include/mbgl/map/map_observer.hpp | 2 ++ src/mbgl/programs/symbol_program.hpp | 8 +++++--- src/mbgl/sprite/sprite_atlas.hpp | 1 + src/mbgl/text/glyph_atlas.hpp | 1 + 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f8757d0c88..f0c7a2ac57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,7 +66,7 @@ endif(WITH_COVERAGE) set(CMAKE_CONFIGURATION_TYPES Debug Release) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -ftemplate-depth=1024 -Wall -Wextra -Wshadow -Werror -Wno-variadic-macros -Wno-unknown-pragmas") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -ftemplate-depth=1024 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Werror -Wno-variadic-macros -Wno-unknown-pragmas") if(APPLE) # -Wno-error=unused-command-line-argument is required due to https://llvm.org/bugs/show_bug.cgi?id=7798 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=unused-command-line-argument") diff --git a/include/mbgl/map/map_observer.hpp b/include/mbgl/map/map_observer.hpp index 4fefb79121..f63e5f2af3 100644 --- a/include/mbgl/map/map_observer.hpp +++ b/include/mbgl/map/map_observer.hpp @@ -10,6 +10,8 @@ namespace mbgl { class MapObserver { public: + virtual ~MapObserver() = default; + static MapObserver& nullObserver() { static MapObserver mapObserver; return mapObserver; diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index 1cac99bfc2..46f532e5c4 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -93,6 +93,8 @@ public: // particular attribute & uniform logic needed by each possible type of the {Text,Icon}Size properties. class SymbolSizeBinder { public: + virtual ~SymbolSizeBinder() = default; + using Uniforms = gl::Uniforms< uniforms::u_is_size_zoom_constant, uniforms::u_is_size_feature_constant, @@ -129,7 +131,7 @@ Range getCoveringStops(Stops s, float lowerZoom, float upperZoom) { }; } -class ConstantSymbolSizeBinder : public SymbolSizeBinder { +class ConstantSymbolSizeBinder final : public SymbolSizeBinder { public: using PropertyValue = variant>; @@ -198,7 +200,7 @@ public: optional> function; }; -class SourceFunctionSymbolSizeBinder : public SymbolSizeBinder { +class SourceFunctionSymbolSizeBinder final : public SymbolSizeBinder { public: using Vertex = gl::detail::Vertex>; using VertexVector = gl::VertexVector; @@ -251,7 +253,7 @@ public: optional buffer; }; -class CompositeFunctionSymbolSizeBinder: public SymbolSizeBinder { +class CompositeFunctionSymbolSizeBinder final : public SymbolSizeBinder { public: using Vertex = SymbolSizeAttributes::Vertex; using VertexVector = gl::VertexVector; diff --git a/src/mbgl/sprite/sprite_atlas.hpp b/src/mbgl/sprite/sprite_atlas.hpp index 5afddaebce..c3efeff44b 100644 --- a/src/mbgl/sprite/sprite_atlas.hpp +++ b/src/mbgl/sprite/sprite_atlas.hpp @@ -43,6 +43,7 @@ typedef std::set IconDependencies; class IconRequestor { public: + virtual ~IconRequestor() = default; virtual void onIconsAvailable(IconMap) = 0; }; diff --git a/src/mbgl/text/glyph_atlas.hpp b/src/mbgl/text/glyph_atlas.hpp index f4c4601530..ad9cf35adc 100644 --- a/src/mbgl/text/glyph_atlas.hpp +++ b/src/mbgl/text/glyph_atlas.hpp @@ -30,6 +30,7 @@ class Context; class GlyphRequestor { public: + virtual ~GlyphRequestor() = default; virtual void onGlyphsAvailable(GlyphPositionMap) = 0; }; -- cgit v1.2.1 From f4f587f46dbde355bebd70e57cacf2ad788d0fd9 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 19 May 2017 12:23:47 +0200 Subject: [android] - remove marker from selected markers when removing marker from annotation manager. (#9047) --- .../main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java index e811470d64..3694668a7e 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java @@ -92,6 +92,10 @@ class AnnotationManager { if (annotation instanceof Marker) { Marker marker = (Marker) annotation; marker.hideInfoWindow(); + if (selectedMarkers.contains(marker)) { + selectedMarkers.remove(marker); + } + if (marker instanceof MarkerView) { markerViewManager.removeMarkerView((MarkerView) marker); } @@ -118,6 +122,10 @@ class AnnotationManager { if (annotation instanceof Marker) { Marker marker = (Marker) annotation; marker.hideInfoWindow(); + if (selectedMarkers.contains(marker)) { + selectedMarkers.remove(marker); + } + if (marker instanceof MarkerView) { markerViewManager.removeMarkerView((MarkerView) marker); } @@ -138,6 +146,7 @@ class AnnotationManager { Annotation annotation; int count = annotations.size(); long[] ids = new long[count]; + selectedMarkers.clear(); for (int i = 0; i < count; i++) { ids[i] = annotations.keyAt(i); annotation = annotations.get(ids[i]); -- cgit v1.2.1 From 3b109c8540ebd4da943e81beff5d9ae1483500c3 Mon Sep 17 00:00:00 2001 From: Fredrik Karlsson Date: Fri, 19 May 2017 14:01:35 +0200 Subject: Observe layout guides (#7716) * [ios] observe layout guides * [ios] update changelog --- platform/ios/CHANGELOG.md | 1 + platform/ios/src/MGLMapView.mm | 218 +++++++++++++++++++--------------------- platform/ios/src/MGLScaleBar.mm | 6 ++ 3 files changed, 111 insertions(+), 114 deletions(-) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 922b7b6486..ed3cb18b1b 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -32,6 +32,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Fixed a crash or console spew when MGLMapView is initialized with a frame smaller than 64 points wide by 64 points tall. ([#8562](https://github.com/mapbox/mapbox-gl-native/pull/8562)) * The error passed into `-[MGLMapViewDelegate mapViewDidFailLoadingMap:withError:]` now includes a more specific description and failure reason. ([#8418](https://github.com/mapbox/mapbox-gl-native/pull/8418)) * Fixed an issue rendering polylines that contain duplicate vertices. ([#8808](https://github.com/mapbox/mapbox-gl-native/pull/8808)) +* Fixed a bug which caused the compass and other ornaments to underlap navigation and tab bars. ([#7716](https://github.com/mapbox/mapbox-gl-native/pull/7716)) ## 3.5.2 - April 7, 2017 diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 4054099dbd..5acb600797 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -131,6 +131,9 @@ const CGFloat MGLAnnotationImagePaddingForCallout = 1; const CGSize MGLAnnotationAccessibilityElementMinimumSize = CGSizeMake(10, 10); +// Context for KVO observing UILayoutGuides. +static void * MGLLayoutGuidesUpdatedContext = &MGLLayoutGuidesUpdatedContext; + /// Unique identifier representing a single annotation in mbgl. typedef uint32_t MGLAnnotationTag; @@ -233,13 +236,9 @@ public: @property (nonatomic) GLKView *glView; @property (nonatomic) UIImageView *glSnapshotView; @property (nonatomic, readwrite) MGLScaleBar *scaleBar; -@property (nonatomic) NS_MUTABLE_ARRAY_OF(NSLayoutConstraint *) *scaleBarConstraints; @property (nonatomic, readwrite) UIImageView *compassView; -@property (nonatomic) NS_MUTABLE_ARRAY_OF(NSLayoutConstraint *) *compassViewConstraints; @property (nonatomic, readwrite) UIImageView *logoView; -@property (nonatomic) NS_MUTABLE_ARRAY_OF(NSLayoutConstraint *) *logoViewConstraints; @property (nonatomic, readwrite) UIButton *attributionButton; -@property (nonatomic) NS_MUTABLE_ARRAY_OF(NSLayoutConstraint *) *attributionButtonConstraints; @property (nonatomic, readwrite) MGLStyle *style; @property (nonatomic) UITapGestureRecognizer *singleTapGestureRecognizer; @property (nonatomic) UITapGestureRecognizer *doubleTap; @@ -294,7 +293,8 @@ public: NSDate *_userLocationAnimationCompletionDate; /// True if a willChange notification has been issued for shape annotation layers and a didChange notification is pending. BOOL _isChangingAnnotationLayers; - + BOOL _isObservingTopLayoutGuide; + BOOL _isObservingBottomLayoutGuide; BOOL _isWaitingForRedundantReachableNotification; BOOL _isTargetingInterfaceBuilder; @@ -471,9 +471,7 @@ public: _logoView = [[UIImageView alloc] initWithImage:logo]; _logoView.accessibilityTraits = UIAccessibilityTraitStaticText; _logoView.accessibilityLabel = NSLocalizedStringWithDefaultValue(@"LOGO_A11Y_LABEL", nil, nil, @"Mapbox", @"Accessibility label"); - _logoView.translatesAutoresizingMaskIntoConstraints = NO; [self addSubview:_logoView]; - _logoViewConstraints = [NSMutableArray array]; // setup attribution // @@ -481,9 +479,7 @@ public: _attributionButton.accessibilityLabel = NSLocalizedStringWithDefaultValue(@"INFO_A11Y_LABEL", nil, nil, @"About this map", @"Accessibility label"); _attributionButton.accessibilityHint = NSLocalizedStringWithDefaultValue(@"INFO_A11Y_HINT", nil, nil, @"Shows credits, a feedback form, and more", @"Accessibility hint"); [_attributionButton addTarget:self action:@selector(showAttribution) forControlEvents:UIControlEventTouchUpInside]; - _attributionButton.translatesAutoresizingMaskIntoConstraints = NO; [self addSubview:_attributionButton]; - _attributionButtonConstraints = [NSMutableArray array]; [_attributionButton addObserver:self forKeyPath:@"hidden" options:NSKeyValueObservingOptionNew context:NULL]; // setup compass @@ -495,16 +491,12 @@ public: _compassView.accessibilityTraits = UIAccessibilityTraitButton; _compassView.accessibilityLabel = NSLocalizedStringWithDefaultValue(@"COMPASS_A11Y_LABEL", nil, nil, @"Compass", @"Accessibility label"); _compassView.accessibilityHint = NSLocalizedStringWithDefaultValue(@"COMPASS_A11Y_HINT", nil, nil, @"Rotates the map to face due north", @"Accessibility hint"); - _compassView.translatesAutoresizingMaskIntoConstraints = NO; [self addSubview:_compassView]; - _compassViewConstraints = [NSMutableArray array]; // setup scale control // _scaleBar = [[MGLScaleBar alloc] init]; - _scaleBar.translatesAutoresizingMaskIntoConstraints = NO; [self addSubview:_scaleBar]; - _scaleBarConstraints = [NSMutableArray array]; // setup interaction // @@ -672,6 +664,14 @@ public: [[NSNotificationCenter defaultCenter] removeObserver:self]; [_attributionButton removeObserver:self forKeyPath:@"hidden"]; + if (_isObservingTopLayoutGuide) { + [(NSObject *)self.viewControllerForLayoutGuides.topLayoutGuide removeObserver:self forKeyPath:@"bounds" context:(void *)&MGLLayoutGuidesUpdatedContext]; + } + + if (_isObservingBottomLayoutGuide) { + [(NSObject *)self.viewControllerForLayoutGuides.bottomLayoutGuide removeObserver:self forKeyPath:@"bounds" context:(void *)&MGLLayoutGuidesUpdatedContext]; + } + // Removing the annotations unregisters any outstanding KVO observers. NSArray *annotations = self.annotations; if (annotations) @@ -697,11 +697,6 @@ public: { [EAGLContext setCurrentContext:nil]; } - - [self.logoViewConstraints removeAllObjects]; - self.logoViewConstraints = nil; - [self.attributionButtonConstraints removeAllObjects]; - self.attributionButtonConstraints = nil; } - (void)setDelegate:(nullable id)delegate @@ -786,105 +781,31 @@ public: - (void)updateConstraints { - // scale control - // - [self removeConstraints:self.scaleBarConstraints]; - [self.scaleBarConstraints removeAllObjects]; + [super updateConstraints]; - [self.scaleBarConstraints addObject: - [NSLayoutConstraint constraintWithItem:self.scaleBar - attribute:NSLayoutAttributeTop - relatedBy:NSLayoutRelationEqual - toItem:self - attribute:NSLayoutAttributeTop - multiplier:1 - constant:5+self.contentInset.top]]; + // If we have a view controller reference and its automaticallyAdjustsScrollViewInsets + // is set to YES, -[MGLMapView adjustContentInset] takes top and bottom layout + // guides into account. To get notified about changes to the layout guides, + // we need to observe their bounds and re-layout accordingly. - [self.scaleBarConstraints addObject: - [NSLayoutConstraint constraintWithItem:self.scaleBar - attribute:NSLayoutAttributeLeading - relatedBy:NSLayoutRelationEqual - toItem:self - attribute:NSLayoutAttributeLeading - multiplier:1 - constant:8 + self.contentInset.left]]; + UIViewController *viewController = self.viewControllerForLayoutGuides; + BOOL useLayoutGuides = viewController.view && viewController.automaticallyAdjustsScrollViewInsets; - [self addConstraints:self.scaleBarConstraints]; + if (useLayoutGuides && viewController.topLayoutGuide && !_isObservingTopLayoutGuide) { + [(NSObject *)viewController.topLayoutGuide addObserver:self forKeyPath:@"bounds" options:0 context:(void *)&MGLLayoutGuidesUpdatedContext]; + _isObservingTopLayoutGuide = YES; + } else if (!useLayoutGuides && _isObservingTopLayoutGuide) { + [(NSObject *)viewController.topLayoutGuide removeObserver:self forKeyPath:@"bounds" context:(void *)&MGLLayoutGuidesUpdatedContext]; + _isObservingTopLayoutGuide = NO; + } - // compass - // - [self removeConstraints:self.compassViewConstraints]; - [self.compassViewConstraints removeAllObjects]; - - [self.compassViewConstraints addObject: - [NSLayoutConstraint constraintWithItem:self.compassView - attribute:NSLayoutAttributeTop - relatedBy:NSLayoutRelationEqual - toItem:self - attribute:NSLayoutAttributeTop - multiplier:1 - constant:5 + self.contentInset.top]]; - - [self.compassViewConstraints addObject: - [NSLayoutConstraint constraintWithItem:self - attribute:NSLayoutAttributeTrailing - relatedBy:NSLayoutRelationEqual - toItem:self.compassView - attribute:NSLayoutAttributeTrailing - multiplier:1 - constant:5 + self.contentInset.right]]; - - [self addConstraints:self.compassViewConstraints]; - - // logo bug - // - [self removeConstraints:self.logoViewConstraints]; - [self.logoViewConstraints removeAllObjects]; - - [self.logoViewConstraints addObject: - [NSLayoutConstraint constraintWithItem:self - attribute:NSLayoutAttributeBottom - relatedBy:NSLayoutRelationEqual - toItem:self.logoView - attribute:NSLayoutAttributeBaseline - multiplier:1 - constant:8 + self.contentInset.bottom]]; - - [self.logoViewConstraints addObject: - [NSLayoutConstraint constraintWithItem:self.logoView - attribute:NSLayoutAttributeLeading - relatedBy:NSLayoutRelationEqual - toItem:self - attribute:NSLayoutAttributeLeading - multiplier:1 - constant:8 + self.contentInset.left]]; - [self addConstraints:self.logoViewConstraints]; - - // attribution button - // - [self removeConstraints:self.attributionButtonConstraints]; - [self.attributionButtonConstraints removeAllObjects]; - - [self.attributionButtonConstraints addObject: - [NSLayoutConstraint constraintWithItem:self - attribute:NSLayoutAttributeBottom - relatedBy:NSLayoutRelationEqual - toItem:self.attributionButton - attribute:NSLayoutAttributeBaseline - multiplier:1 - constant:8 + self.contentInset.bottom]]; - - [self.attributionButtonConstraints addObject: - [NSLayoutConstraint constraintWithItem:self - attribute:NSLayoutAttributeTrailing - relatedBy:NSLayoutRelationEqual - toItem:self.attributionButton - attribute:NSLayoutAttributeTrailing - multiplier:1 - constant:8 + self.contentInset.right]]; - [self addConstraints:self.attributionButtonConstraints]; - - [super updateConstraints]; + if (useLayoutGuides && viewController.bottomLayoutGuide && !_isObservingBottomLayoutGuide) { + [(NSObject *)viewController.bottomLayoutGuide addObserver:self forKeyPath:@"bounds" options:0 context:(void *)&MGLLayoutGuidesUpdatedContext]; + _isObservingBottomLayoutGuide = YES; + } else if (!useLayoutGuides && _isObservingBottomLayoutGuide) { + [(NSObject *)viewController.bottomLayoutGuide removeObserver:self forKeyPath:@"bounds" context:(void *)&MGLLayoutGuidesUpdatedContext]; + _isObservingBottomLayoutGuide = NO; + } } - (BOOL)isOpaque @@ -917,6 +838,10 @@ public: [super layoutSubviews]; [self adjustContentInset]; + + [self observeLayoutGuidesIfNeeded]; + + [self layoutOrnaments]; if (!_isTargetingInterfaceBuilder) { _mbglMap->setSize([self size]); @@ -931,6 +856,39 @@ public: [self updateUserLocationAnnotationView]; } +- (void)layoutOrnaments +{ + // scale bar + self.scaleBar.frame = { + self.contentInset.left+8, + self.contentInset.top+5, + CGRectGetWidth(self.scaleBar.frame), + CGRectGetHeight(self.scaleBar.frame) + }; + + // compass + self.compassView.center = { + .x = CGRectGetWidth(self.bounds)-CGRectGetMidX(self.compassView.bounds)-self.contentInset.right-5, + .y = CGRectGetMidY(self.compassView.bounds)+self.contentInset.top+5 + }; + + // logo bug + self.logoView.frame = { + self.contentInset.left+5, + CGRectGetHeight(self.bounds)-5-self.contentInset.bottom-CGRectGetHeight(self.logoView.bounds), + CGRectGetWidth(self.logoView.bounds), + CGRectGetHeight(self.logoView.bounds) + }; + + // attribution + self.attributionButton.frame = { + CGRectGetWidth(self.bounds)-CGRectGetWidth(self.attributionButton.bounds)-self.contentInset.right-8, + CGRectGetHeight(self.bounds)-CGRectGetHeight(self.attributionButton.bounds)-self.contentInset.bottom-8, + CGRectGetWidth(self.attributionButton.bounds), + CGRectGetHeight(self.attributionButton.bounds) + }; +} + /// Updates `contentInset` to reflect the current window geometry. - (void)adjustContentInset { @@ -970,6 +928,34 @@ public: self.contentInset = contentInset; } +- (void)observeLayoutGuidesIfNeeded +{ + UIViewController *viewController = self.viewControllerForLayoutGuides; + BOOL useLayoutGuides = viewController.view && viewController.automaticallyAdjustsScrollViewInsets; + + if (!_isObservingTopLayoutGuide && useLayoutGuides && viewController.topLayoutGuide) + { + [(NSObject *)viewController.topLayoutGuide addObserver:self forKeyPath:@"bounds" options:0 context:MGLLayoutGuidesUpdatedContext]; + _isObservingTopLayoutGuide = YES; + } + else if (!useLayoutGuides && _isObservingTopLayoutGuide) + { + [(NSObject *)viewController.topLayoutGuide removeObserver:self forKeyPath:@"bounds" context:MGLLayoutGuidesUpdatedContext]; + _isObservingTopLayoutGuide = NO; + } + + if (!_isObservingBottomLayoutGuide && useLayoutGuides && viewController.bottomLayoutGuide) + { + [(NSObject *)viewController.bottomLayoutGuide addObserver:self forKeyPath:@"bounds" options:0 context:MGLLayoutGuidesUpdatedContext]; + _isObservingBottomLayoutGuide = YES; + } + else if (!useLayoutGuides && _isObservingBottomLayoutGuide) + { + [(NSObject *)viewController.bottomLayoutGuide removeObserver:self forKeyPath:@"bounds" context:MGLLayoutGuidesUpdatedContext]; + _isObservingBottomLayoutGuide = NO; + } +} + - (void)setContentInset:(UIEdgeInsets)contentInset { [self setContentInset:contentInset animated:NO]; @@ -1000,7 +986,7 @@ public: } // Compass, logo and attribution button constraints needs to be updated. - [self setNeedsUpdateConstraints]; + [self setNeedsLayout]; } /// Returns the frame of inset content within the map view. @@ -2066,6 +2052,10 @@ public: [self updateCalloutView]; } } + else if (context == MGLLayoutGuidesUpdatedContext && [keyPath isEqualToString:@"bounds"]) + { + [self setNeedsLayout]; + } } + (NS_SET_OF(NSString *) *)keyPathsForValuesAffectingZoomEnabled diff --git a/platform/ios/src/MGLScaleBar.mm b/platform/ios/src/MGLScaleBar.mm index 1216e400b3..cd88c1e08e 100644 --- a/platform/ios/src/MGLScaleBar.mm +++ b/platform/ios/src/MGLScaleBar.mm @@ -220,6 +220,12 @@ static const CGFloat MGLFeetPerMeter = 3.28084; self.row = [self preferredRow]; + CGSize size = self.intrinsicContentSize; + self.frame = CGRectMake(CGRectGetMinX(self.frame), + CGRectGetMinY(self.frame), + size.width, + size.height); + [self invalidateIntrinsicContentSize]; [self setNeedsLayout]; } -- cgit v1.2.1 From 7612e23dff48453abd00434b4fe8ba6645235875 Mon Sep 17 00:00:00 2001 From: Jesse Bounds Date: Wed, 17 May 2017 14:52:19 -0700 Subject: [ios, macos] Change == to = in style function initializers --- platform/darwin/src/MGLStyleValue.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/darwin/src/MGLStyleValue.mm b/platform/darwin/src/MGLStyleValue.mm index 33b6babadf..4dd6b550d8 100644 --- a/platform/darwin/src/MGLStyleValue.mm +++ b/platform/darwin/src/MGLStyleValue.mm @@ -128,7 +128,7 @@ const MGLStyleFunctionOption MGLStyleFunctionOptionDefaultValue = @"MGLStyleFunc return {}; } - if (self == [super init]) { + if (self = [super init]) { self.interpolationMode = interpolationMode; self.stops = stops; @@ -181,7 +181,7 @@ const MGLStyleFunctionOption MGLStyleFunctionOptionDefaultValue = @"MGLStyleFunc } - (instancetype)initWithInterpolationMode:(MGLInterpolationMode)interpolationMode stops:(NSDictionary *)stops attributeName:(NSString *)attributeName options:(NSDictionary *)options { - if (self == [super init]) { + if (self = [super init]) { self.interpolationMode = interpolationMode; self.stops = stops; _attributeName = attributeName; @@ -251,7 +251,7 @@ const MGLStyleFunctionOption MGLStyleFunctionOptionDefaultValue = @"MGLStyleFunc } - (instancetype)initWithInterpolationMode:(MGLInterpolationMode)interpolationMode stops:(NSDictionary *)stops attributeName:(NSString *)attributeName options:(NSDictionary *)options { - if (self == [super init]) { + if (self = [super init]) { self.interpolationMode = interpolationMode; self.stops = stops; _attributeName = attributeName; -- cgit v1.2.1 From 554b1cf3e2c8ba21fd3e2259d04915811668a3ac Mon Sep 17 00:00:00 2001 From: Jesse Bounds Date: Fri, 19 May 2017 09:35:09 -0700 Subject: [ios] Add annotation view initializer with annotation and reuse id (#9029) --- platform/ios/CHANGELOG.md | 1 + platform/ios/src/MGLAnnotationView.h | 30 ++++++++++++++++++++++++++++++ platform/ios/src/MGLAnnotationView.mm | 18 +++++++++++------- platform/ios/test/MGLAnnotationViewTests.m | 2 +- 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index ed3cb18b1b..b09b1587d5 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -17,6 +17,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT ### Annotations +* Added a new initializer to `MGLAnnotationView` so that it is possible to create a new instance with an associated annotation object. ([#9029](https://github.com/mapbox/mapbox-gl-native/pull/9029)) * Fixed an issue causing a view-backed annotation to disappear immediately instead of animating when the annotation’s `coordinate` property is set to a value outside the current viewport. ([#8565](https://github.com/mapbox/mapbox-gl-native/pull/8565)) * Fixed an issue in which `MGLMapView` overrode the tint colors of its annotation views. ([#8789](https://github.com/mapbox/mapbox-gl-native/pull/8789)) diff --git a/platform/ios/src/MGLAnnotationView.h b/platform/ios/src/MGLAnnotationView.h index 184efdb324..9b17f05a6e 100644 --- a/platform/ios/src/MGLAnnotationView.h +++ b/platform/ios/src/MGLAnnotationView.h @@ -73,6 +73,36 @@ typedef NS_ENUM(NSUInteger, MGLAnnotationViewDragState) { */ - (instancetype)initWithReuseIdentifier:(nullable NSString *)reuseIdentifier; +/** + Initializes and returns a new annotation view object. + + Providing an annotation allows you to explicitly associate the annotation instance + with the new view and, in custom subclasses of `MGLAnnotationView`, customize the view + based on properties of the annotation instance in an overridden initializer. However, + annotation views that are reused will not necessarily be associated with the + same annotation they were initialized with. Also, annotation views that are in + the reuse queue will have a nil value for the annotation property. Passing an annotation + instance to the view is optional and the map view will automatically associate annotations + with views when views are provided to the map via the `-[MGLMapViewDelegate mapView:viewForAnnotation:]` + method. + + The reuse identifier provides a way for you to improve performance by recycling + annotation views as they enter and leave the map’s viewport. As an annotation + leaves the viewport, the map view moves its associated view to a reuse queue. + When a new annotation becomes visible, you can request a view for that + annotation by passing the appropriate reuse identifier string to the + `-[MGLMapView dequeueReusableAnnotationViewWithIdentifier:]` method. + + @param annotation The annotation object to associate with the new view. + @param reuseIdentifier A unique string identifier for this view that allows you + to reuse this view with multiple similar annotations. You can set this + parameter to `nil` if you don’t intend to reuse the view, but it is a good + idea in general to specify a reuse identifier to avoid creating redundant + views. + @return The initialized annotation view object. + */ +- (instancetype)initWithAnnotation:(nullable id)annotation reuseIdentifier:(nullable NSString *)reuseIdentifier; + /** Called when the view is removed from the reuse queue. diff --git a/platform/ios/src/MGLAnnotationView.mm b/platform/ios/src/MGLAnnotationView.mm index 5e0ae3b848..9e1212b4fb 100644 --- a/platform/ios/src/MGLAnnotationView.mm +++ b/platform/ios/src/MGLAnnotationView.mm @@ -19,12 +19,20 @@ @implementation MGLAnnotationView -- (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier -{ - self = [self initWithFrame:CGRectZero]; ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier { + return [self initWithAnnotation:nil reuseIdentifier:reuseIdentifier]; +} + +- (instancetype)initWithAnnotation:(nullable id)annotation reuseIdentifier:(nullable NSString *)reuseIdentifier { + self = [super initWithFrame:CGRectZero]; if (self) { _lastAppliedScaleTransform = CATransform3DIdentity; + _annotation = annotation; _reuseIdentifier = [reuseIdentifier copy]; _scalesWithViewingDistance = YES; _enabled = YES; @@ -32,10 +40,6 @@ return self; } -+ (BOOL)supportsSecureCoding { - return YES; -} - - (instancetype)initWithCoder:(NSCoder *)decoder { if (self = [super initWithCoder:decoder]) { _reuseIdentifier = [decoder decodeObjectOfClass:[NSString class] forKey:@"reuseIdentifier"]; diff --git a/platform/ios/test/MGLAnnotationViewTests.m b/platform/ios/test/MGLAnnotationViewTests.m index c0978eaf65..88ca755476 100644 --- a/platform/ios/test/MGLAnnotationViewTests.m +++ b/platform/ios/test/MGLAnnotationViewTests.m @@ -85,7 +85,7 @@ static NSString * const MGLTestAnnotationReuseIdentifer = @"MGLTestAnnotationReu if (!annotationView) { - annotationView = [[MGLAnnotationView alloc] initWithReuseIdentifier:MGLTestAnnotationReuseIdentifer]; + annotationView = [[MGLAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:MGLTestAnnotationReuseIdentifer]; } _annotationView = annotationView; -- cgit v1.2.1 From b9d3ccc99506efcadd90bc6b1fc4b9831dfd32df Mon Sep 17 00:00:00 2001 From: Jesse Bounds Date: Fri, 19 May 2017 11:27:46 -0700 Subject: [ios] Remove annotation view from container view when annotation removed (#9025) The annotation container view keeps an array of annotation views that is separate from the array of subviews that is a property of the UIView parent class. This removes an annotation view from that container view array when the associated annotation is removed. This avoids issue related to previously removed annotation views continuing to be involved in map view logic around annotation view selection due to taps. --- platform/ios/CHANGELOG.md | 1 + platform/ios/src/MGLMapView.mm | 1 + 2 files changed, 2 insertions(+) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index b09b1587d5..332ec06ab4 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -20,6 +20,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Added a new initializer to `MGLAnnotationView` so that it is possible to create a new instance with an associated annotation object. ([#9029](https://github.com/mapbox/mapbox-gl-native/pull/9029)) * Fixed an issue causing a view-backed annotation to disappear immediately instead of animating when the annotation’s `coordinate` property is set to a value outside the current viewport. ([#8565](https://github.com/mapbox/mapbox-gl-native/pull/8565)) * Fixed an issue in which `MGLMapView` overrode the tint colors of its annotation views. ([#8789](https://github.com/mapbox/mapbox-gl-native/pull/8789)) +* Fixed an issue causing annotation views to persist in the map's annotation container view even after their associated annotations were removed. ([#9025](https://github.com/mapbox/mapbox-gl-native/pull/9025)) ### User interaction diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 5acb600797..720c1d506a 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -3492,6 +3492,7 @@ public: annotationView.annotation = nil; [annotationView removeFromSuperview]; + [self.annotationContainerView.annotationViews removeObject:annotationView]; if (annotationTag == _selectedAnnotationTag) { -- cgit v1.2.1 From 4d8625b13ca32dc8c9ca9484db663bf3aba52a6d Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 19 May 2017 20:38:23 +0200 Subject: [android] - correct bearing conversion when animating the map with jumpTo, easeTo and animateTo. (#9050) --- platform/android/src/map/camera_position.cpp | 2 +- platform/android/src/native_map_view.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/android/src/map/camera_position.cpp b/platform/android/src/map/camera_position.cpp index aa5873b273..f059fbd413 100644 --- a/platform/android/src/map/camera_position.cpp +++ b/platform/android/src/map/camera_position.cpp @@ -12,7 +12,7 @@ jni::Object CameraPosition::New(jni::JNIEnv &env, mbgl::CameraOp center.wrap(); // convert bearing, core ranges from [−π rad, π rad], android from 0 to 360 degrees - double bearing_degrees = options.angle.value_or(0) * 180.0 / M_PI; + double bearing_degrees = (options.angle.value_or(0) * 180.0 / M_PI) + 180; while (bearing_degrees > 360) { bearing_degrees -= 360; } diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index 1e2464f1a0..3dbfd6809a 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -385,7 +385,7 @@ void NativeMapView::moveBy(jni::JNIEnv&, jni::jdouble dx, jni::jdouble dy, jni:: void NativeMapView::jumpTo(jni::JNIEnv&, jni::jdouble angle, jni::jdouble latitude, jni::jdouble longitude, jni::jdouble pitch, jni::jdouble zoom) { mbgl::CameraOptions options; if (angle != -1) { - options.angle = (-angle * M_PI) / 180; + options.angle = (angle - 180 * M_PI) / 180; } options.center = mbgl::LatLng(latitude, longitude); options.padding = insets; @@ -402,7 +402,7 @@ void NativeMapView::jumpTo(jni::JNIEnv&, jni::jdouble angle, jni::jdouble latitu void NativeMapView::easeTo(jni::JNIEnv&, jni::jdouble angle, jni::jdouble latitude, jni::jdouble longitude, jni::jlong duration, jni::jdouble pitch, jni::jdouble zoom, jni::jboolean easing) { mbgl::CameraOptions cameraOptions; if (angle != -1) { - cameraOptions.angle = (-angle * M_PI) / 180; + cameraOptions.angle = (angle - 180 * M_PI) / 180; } cameraOptions.center = mbgl::LatLng(latitude, longitude); cameraOptions.padding = insets; @@ -426,7 +426,7 @@ void NativeMapView::easeTo(jni::JNIEnv&, jni::jdouble angle, jni::jdouble latitu void NativeMapView::flyTo(jni::JNIEnv&, jni::jdouble angle, jni::jdouble latitude, jni::jdouble longitude, jni::jlong duration, jni::jdouble pitch, jni::jdouble zoom) { mbgl::CameraOptions cameraOptions; if (angle != -1) { - cameraOptions.angle = (-angle * M_PI) / 180 ; + cameraOptions.angle = (angle - 180 * M_PI / 180); } cameraOptions.center = mbgl::LatLng(latitude, longitude); cameraOptions.padding = insets; -- cgit v1.2.1 From 13dee80e2e90f06ee6cb2883dda16f7c4442aca5 Mon Sep 17 00:00:00 2001 From: Jordan Kiley Date: Mon, 1 May 2017 15:42:54 -0700 Subject: [ios, macos] Updated `maximumZoomLevel` description, cherry-picked #8818 (#8842) Cherry-picked from a3e4e67ea68c455178d5c5ef3d864972fcf41147. --- platform/darwin/src/MGLStyleLayer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/darwin/src/MGLStyleLayer.h b/platform/darwin/src/MGLStyleLayer.h index d68aee29bc..7d181667d6 100644 --- a/platform/darwin/src/MGLStyleLayer.h +++ b/platform/darwin/src/MGLStyleLayer.h @@ -45,12 +45,12 @@ MGL_EXPORT @property (nonatomic, assign, getter=isVisible) BOOL visible; /** - The maximum zoom level at which the layer gets parsed and appears. + The maximum zoom level at which the layer gets parsed and appears. This value is a floating-point number. */ @property (nonatomic, assign) float maximumZoomLevel; /** - The minimum zoom level at which the layer gets parsed and appears. + The minimum zoom level at which the layer gets parsed and appears. This value is a floating-point number. */ @property (nonatomic, assign) float minimumZoomLevel; -- cgit v1.2.1 From ade7b0e1fdd111eeb5d83fe34ba216248db15384 Mon Sep 17 00:00:00 2001 From: Jordan Kiley Date: Tue, 2 May 2017 16:28:00 -0700 Subject: [ios] Updated podspecs and changelog for v3.5.3 (#8870) Cherry-picked from 25c19902a22e240da4e7ebf1974125b7e67bd21e. --- platform/ios/CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 332ec06ab4..cb3175935f 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -36,6 +36,9 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Fixed an issue rendering polylines that contain duplicate vertices. ([#8808](https://github.com/mapbox/mapbox-gl-native/pull/8808)) * Fixed a bug which caused the compass and other ornaments to underlap navigation and tab bars. ([#7716](https://github.com/mapbox/mapbox-gl-native/pull/7716)) +## 3.5.3 - May 2, 2017 +* Fixed an issue that prevented the attribution `UIAlertController` from showing in modal hierarchies. ([#8837](https://github.com/mapbox/mapbox-gl-native/pull/8837)) + ## 3.5.2 - April 7, 2017 * Fixed an issue that caused a crash when the user location annotation was presenting a callout view and the map was moved. ([#8686](https://github.com/mapbox/mapbox-gl-native/pull/8686)) -- cgit v1.2.1 From 9ae73714f15def72ab1f0189be98aaa13b7125db Mon Sep 17 00:00:00 2001 From: Jesse Bounds Date: Tue, 9 May 2017 13:41:56 -0700 Subject: [ios] Update podspecs and changelog for iOS v3.5.4 Cherry-picked from db7bb509e95d737199efa73a47bdcc973966ed97. --- platform/ios/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index cb3175935f..3a4890c17d 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -36,7 +36,12 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Fixed an issue rendering polylines that contain duplicate vertices. ([#8808](https://github.com/mapbox/mapbox-gl-native/pull/8808)) * Fixed a bug which caused the compass and other ornaments to underlap navigation and tab bars. ([#7716](https://github.com/mapbox/mapbox-gl-native/pull/7716)) +## 3.5.4 - May 9, 2017 + +* Fixed an issue that caused view backed annotations to become detached from the map view during pan gestures combined with animations of annotation view size or when the annotation view had no size but contained subviews with a non-zero size. ([#8926](https://github.com/mapbox/mapbox-gl-native/pull/8926)) + ## 3.5.3 - May 2, 2017 + * Fixed an issue that prevented the attribution `UIAlertController` from showing in modal hierarchies. ([#8837](https://github.com/mapbox/mapbox-gl-native/pull/8837)) ## 3.5.2 - April 7, 2017 -- cgit v1.2.1 From e630e8c1839c6e23532d18cb7f86e584531ebb5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Thu, 18 May 2017 20:25:28 -0700 Subject: [ios, macos] Updated changelogs --- platform/ios/CHANGELOG.md | 4 +++- platform/macos/CHANGELOG.md | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 3a4890c17d..ca9d22f230 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -2,7 +2,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONTRIBUTING.md](../../CONTRIBUTING.md) to get started. -## master +## 3.6.0 ### Styles @@ -11,6 +11,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Added class methods to MGLStyle that correspond to the new [Traffic Day and Traffic Night](https://www.mapbox.com/blog/live-traffic-maps/) styles. ([#6301](https://github.com/mapbox/mapbox-gl-native/pull/6301)) * MGLSymbolStyleLayer’s `iconImageName`, `iconScale`, `textFontSize`, `textOffset`, and `textRotation` properties can now be set to a source or composite function. ([#8544](https://github.com/mapbox/mapbox-gl-native/pull/8544), [#8590](https://github.com/mapbox/mapbox-gl-native/pull/8590), [#8592](https://github.com/mapbox/mapbox-gl-native/pull/8592), [#8593](https://github.com/mapbox/mapbox-gl-native/pull/8593)) * Fixed an issue where setting the `MGLVectorStyleLayer.predicate` property failed to take effect if the relevant source was not in use by a visible layer at the time. ([#8653](https://github.com/mapbox/mapbox-gl-native/pull/8653)) +* Fixed an issue preventing programmatically added style layers from appearing in already cached tiles. ([#8954](https://github.com/mapbox/mapbox-gl-native/pull/8954)) * Fixed an issue causing a composite function’s highest zoom level stop to be misinterpreted. ([#8613](https://github.com/mapbox/mapbox-gl-native/pull/8613), [#8790](https://github.com/mapbox/mapbox-gl-native/pull/8790)) * Fixed an issue where re-adding a layer that had been previously removed from a style would reset its paint properties. Moved initializers for `MGLTileSource`, `MGLStyleLayer`, and `MGLForegroundStyleLayer` to their concrete subclasses; because these classes were already intended for initialization only via concrete subclasses, this should have no developer impact. ([#8626](https://github.com/mapbox/mapbox-gl-native/pull/8626)) * Feature querying results now account for any changes to a feature’s size caused by a source or composite style function. ([#8665](https://github.com/mapbox/mapbox-gl-native/pull/8665)) @@ -26,6 +27,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Added a scale bar to `MGLMapView` that indicates the scale of the map. ([#7631](https://github.com/mapbox/mapbox-gl-native/pull/7631)) * Fixed an issue where gesture recognizers associated with map view interactivity were not disabled when their related interactions were disabled. ([#8304](https://github.com/mapbox/mapbox-gl-native/pull/8304)) +* Fixed an issue preventing the Mapbox Telemetry confirmation dialog from appearing when opened from within a map view in a modal view controller. ([#9027](https://github.com/mapbox/mapbox-gl-native/pull/9027)) ### Other changes diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index 632bcfa44b..ba09002d14 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog for Mapbox macOS SDK -## master +## 3.6.0 ### Styles @@ -9,6 +9,7 @@ * Added class methods to MGLStyle that correspond to the new [Traffic Day and Traffic Night](https://www.mapbox.com/blog/live-traffic-maps/) styles. ([#6301](https://github.com/mapbox/mapbox-gl-native/pull/6301)) * MGLSymbolStyleLayer’s `iconImageName`, `iconScale`, `textFontSize`, `textOffset`, and `textRotation` properties can now be set to a source or composite function. ([#8544](https://github.com/mapbox/mapbox-gl-native/pull/8544), [#8590](https://github.com/mapbox/mapbox-gl-native/pull/8590), [#8592](https://github.com/mapbox/mapbox-gl-native/pull/8592), [#8593](https://github.com/mapbox/mapbox-gl-native/pull/8593)) * Fixed an issue where setting the `MGLVectorStyleLayer.predicate` property failed to take effect if the relevant source was not in use by a visible layer at the time. ([#8653](https://github.com/mapbox/mapbox-gl-native/pull/8653)) +* Fixed an issue preventing programmatically added style layers from appearing in already cached tiles. ([#8954](https://github.com/mapbox/mapbox-gl-native/pull/8954)) * Fixed an issue causing a composite function’s highest zoom level stop to be misinterpreted. ([#8613](https://github.com/mapbox/mapbox-gl-native/pull/8613), [#8790](https://github.com/mapbox/mapbox-gl-native/pull/8790)) * Fixed an issue where re-adding a layer that had been previously removed from a style would reset its paint properties. Moved initializers for `MGLTileSource`, `MGLStyleLayer`, and `MGLForegroundStyleLayer` to their concrete subclasses; because these classes were already intended for initialization only via concrete subclasses, this should have no developer impact. ([#8626](https://github.com/mapbox/mapbox-gl-native/pull/8626)) * Feature querying results now account for any changes to a feature’s size caused by a source or composite style function. ([#8665](https://github.com/mapbox/mapbox-gl-native/pull/8665)) -- cgit v1.2.1 From a19fd817300abf00b81cba5765fda62c48057efa Mon Sep 17 00:00:00 2001 From: Jordan Kiley Date: Fri, 19 May 2017 16:08:03 -0700 Subject: [ios, macos] changed TRUE -> 'true' (#9059) fixes #9056 --- platform/darwin/src/MGLFillExtrusionStyleLayer.h | 2 +- platform/darwin/test/MGLDocumentationExampleTests.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/darwin/src/MGLFillExtrusionStyleLayer.h b/platform/darwin/src/MGLFillExtrusionStyleLayer.h index 84f6bedde4..c4fb9aa77e 100644 --- a/platform/darwin/src/MGLFillExtrusionStyleLayer.h +++ b/platform/darwin/src/MGLFillExtrusionStyleLayer.h @@ -46,7 +46,7 @@ typedef NS_ENUM(NSUInteger, MGLFillExtrusionTranslationAnchor) { layer.sourceLayerIdentifier = "building" layer.fillExtrusionHeight = MGLStyleValue(interpolationMode: .identity, sourceStops: nil, attributeName: "height", options: nil) layer.fillExtrusionBase = MGLStyleValue(interpolationMode: .identity, sourceStops: nil, attributeName: "min_height", options: nil) - layer.predicate = NSPredicate(format: "extrude == TRUE") + layer.predicate = NSPredicate(format: "extrude == 'true'") mapView.style?.addLayer(layer) ``` */ diff --git a/platform/darwin/test/MGLDocumentationExampleTests.swift b/platform/darwin/test/MGLDocumentationExampleTests.swift index 6d2dc597a9..48e6b17f44 100644 --- a/platform/darwin/test/MGLDocumentationExampleTests.swift +++ b/platform/darwin/test/MGLDocumentationExampleTests.swift @@ -168,7 +168,7 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate { layer.sourceLayerIdentifier = "building" layer.fillExtrusionHeight = MGLStyleValue(interpolationMode: .identity, sourceStops: nil, attributeName: "height", options: nil) layer.fillExtrusionBase = MGLStyleValue(interpolationMode: .identity, sourceStops: nil, attributeName: "min_height", options: nil) - layer.predicate = NSPredicate(format: "extrude == TRUE") + layer.predicate = NSPredicate(format: "extrude == 'true'") mapView.style?.addLayer(layer) //#-end-example-code -- cgit v1.2.1 From e52249c17fb529c476569b6d7ef141be1bff7d7f Mon Sep 17 00:00:00 2001 From: Fabian Guerra Soto Date: Tue, 23 May 2017 10:59:24 -0400 Subject: [ios, macos] Light property implementation in MGLStyle (#9043) * [ios, macos] Add MGLLight to MGLStyle * [ios, macos] Implement Objc bindings for Light object * [ios, macos] Remove rawLight from MGLLight and re-implement it as value class * [ios, macos] Fix build on macos * [ios, macos] Add MGLLight documentation, Move MGLLightPosition to MGLLight * [ios, macos] Add MGLLight tests. * [ios, macos] Update changelogs * [ios, macos] Fix misspelling * [ios, macos] Fix MGLLightAnchor enum property names * [ios, macos] Update documentation. Improve varialble naming. * [ios, macos] Rename MGLLightPosition to MGLSphericalPosition * [ios, macos] Update data types of MGLSphericalPosition --- platform/darwin/src/MGLLight.h | 125 ++++++++++++ platform/darwin/src/MGLLight.mm | 117 ++++++++++++ platform/darwin/src/MGLLight_Private.h | 23 +++ platform/darwin/src/MGLStyle.h | 9 + platform/darwin/src/MGLStyle.mm | 17 ++ platform/darwin/src/MGLStyleValue_Private.h | 14 ++ platform/darwin/src/MGLTypes.h | 1 + platform/darwin/src/NSValue+MGLAdditions.h | 29 +++ platform/darwin/src/NSValue+MGLAdditions.m | 23 +++ .../src/NSValue+MGLStyleAttributeAdditions.h | 1 + .../src/NSValue+MGLStyleAttributeAdditions.mm | 15 +- platform/darwin/test/MGLLightTest.mm | 211 +++++++++++++++++++++ platform/ios/ios.xcodeproj/project.pbxproj | 22 +++ platform/ios/src/Mapbox.h | 1 + platform/macos/macos.xcodeproj/project.pbxproj | 16 ++ platform/macos/src/Mapbox.h | 1 + 16 files changed, 624 insertions(+), 1 deletion(-) create mode 100644 platform/darwin/src/MGLLight.h create mode 100644 platform/darwin/src/MGLLight.mm create mode 100644 platform/darwin/src/MGLLight_Private.h create mode 100644 platform/darwin/test/MGLLightTest.mm diff --git a/platform/darwin/src/MGLLight.h b/platform/darwin/src/MGLLight.h new file mode 100644 index 0000000000..d9a22d60fa --- /dev/null +++ b/platform/darwin/src/MGLLight.h @@ -0,0 +1,125 @@ +#import + +#import "MGLFoundation.h" +#import "MGLStyleValue.h" + +NS_ASSUME_NONNULL_BEGIN + + +/** Options to specify extruded geometries are lit relative to the map or viewport. */ +typedef NS_ENUM(NSUInteger, MGLLightAnchor) { + /** The position of the light source is aligned to the rotation of the map. */ + MGLLightAnchorMap, + /** The position of the light source is aligned to the rotation of the viewport. */ + MGLLightAnchorViewport +}; + +/** + A structure containing information about the position of the light source + relative to lit geometries. + */ +typedef struct MGLSphericalPosition { + /** Distance from the center of the base of an object to its light. */ + CLLocationDistance radial; + /** Position of the light relative to 0° (0° when `MGLLight.anchor` is set to viewport corresponds + to the top of the viewport, or 0° when `MGLLight.anchor` is set to map corresponds to due north, + and degrees proceed clockwise). */ + CLLocationDirection azimuthal; + /** Indicates the height of the light (from 0°, directly above, to 180°, directly below). */ + CLLocationDirection polar; +} MGLSphericalPosition; + +/** + Creates a new `MGLSphericalPosition` from the given radial, azimuthal, polar. + + @param radial The radial coordinate. + @param azimuthal The azimuthal angle. + @param polar The polar angle. + + @return Returns a `MGLSphericalPosition` struct containing the position attributes. + */ +NS_INLINE MGLSphericalPosition MGLSphericalPositionMake(CLLocationDistance radial, CLLocationDirection azimuthal, CLLocationDirection polar) { + MGLSphericalPosition position; + position.radial = radial; + position.azimuthal = azimuthal; + position.polar = polar; + + return position; +} + +/** + An `MGLLight` object represents the light source for extruded geometries in `MGLStyle`. + */ +MGL_EXPORT +@interface MGLLight : NSObject + +/** + `anchor` Whether extruded geometries are lit relative to the map or viewport. + + This property corresponds to the anchor + light property in the Mapbox Style Specification. + */ +@property (nonatomic) MGLLightAnchor anchor; + +/** + Values describing animated transitions to `anchor` property. + */ +@property (nonatomic) MGLTransition anchorTransition; + + +/** + Position of the light source relative to lit (extruded) geometries. + + This property corresponds to the position + light property in the Mapbox Style Specification. + */ +@property (nonatomic) MGLStyleValue * position; + +/** + Values describing animated transitions to `position` property. + */ +@property (nonatomic) MGLTransition positionTransiton; + + +#if TARGET_OS_IPHONE +/** + Color tint for lighting extruded geometries. + + This property corresponds to the color + light property in the Mapbox Style Specification. + */ +@property (nonatomic) MGLStyleValue *color; +#else + +/** + Color tint for lighting extruded geometries. + */ +@property (nonatomic) MGLStyleValue *color; +#endif + +/** + Values describing animated transitions to `color` property. + */ +@property (nonatomic) MGLTransition colorTransiton; + + +/** + Intensity of lighting (on a scale from 0 to 1). Higher numbers will present as more extreme contrast. + + This property corresponds to the intensity + light property in the Mapbox Style Specification. + */ +@property(nonatomic) MGLStyleValue *intensity; + +/** + Values describing animated transitions to `intensity` property. + */ +@property (nonatomic) MGLTransition intensityTransition; + +@end + +NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLLight.mm b/platform/darwin/src/MGLLight.mm new file mode 100644 index 0000000000..02d55e76ed --- /dev/null +++ b/platform/darwin/src/MGLLight.mm @@ -0,0 +1,117 @@ +#import "MGLLight.h" + +#import "MGLTypes.h" +#import "NSDate+MGLAdditions.h" +#import "MGLStyleValue_Private.h" +#import "NSValue+MGLAdditions.h" + +#import +#import + +namespace mbgl { + + MBGL_DEFINE_ENUM(MGLLightAnchor, { + { MGLLightAnchorMap, "map" }, + { MGLLightAnchorViewport, "viewport" }, + }); + +} + +NS_INLINE MGLTransition MGLTransitionFromOptions(const mbgl::style::TransitionOptions& options) { + MGLTransition transition; + transition.duration = MGLTimeIntervalFromDuration(options.duration.value_or(mbgl::Duration::zero())); + transition.delay = MGLTimeIntervalFromDuration(options.delay.value_or(mbgl::Duration::zero())); + + return transition; +} + +NS_INLINE mbgl::style::TransitionOptions MGLOptionsFromTransition(MGLTransition transition) { + mbgl::style::TransitionOptions options { { MGLDurationFromTimeInterval(transition.duration) }, { MGLDurationFromTimeInterval(transition.delay) } }; + return options; +} + +@interface MGLLight() + +@end + +@implementation MGLLight + +- (instancetype)initWithMBGLLight:(const mbgl::style::Light *)mbglLight +{ + if (self = [super init]) { + auto anchor = mbglLight->getAnchor(); + MGLStyleValue *anchorStyleValue; + if (anchor.isUndefined()) { + mbgl::style::PropertyValue defaultAnchor = mbglLight->getDefaultAnchor(); + anchorStyleValue = MGLStyleValueTransformer().toEnumStyleValue(defaultAnchor); + } else { + anchorStyleValue = MGLStyleValueTransformer().toEnumStyleValue(anchor); + } + + NSAssert([anchorStyleValue isKindOfClass:[MGLConstantStyleValue class]], @"Anchor isn’t a constant."); + NSValue *anchorValue = ((MGLConstantStyleValue *)anchorStyleValue).rawValue; + _anchor = [anchorValue MGLLightAnchorValue]; + + _anchorTransition = MGLTransitionFromOptions(mbglLight->getAnchorTransition()); + + auto positionValue = mbglLight->getPosition(); + if (positionValue.isUndefined()) { + _position = MGLStyleValueTransformer().toStyleValue(mbglLight->getDefaultPosition()); + } else { + _position = MGLStyleValueTransformer().toStyleValue(positionValue); + } + + _positionTransiton = MGLTransitionFromOptions(mbglLight->getPositionTransition()); + + auto colorValue = mbglLight->getColor(); + if (colorValue.isUndefined()) { + _color = MGLStyleValueTransformer().toStyleValue(mbglLight->getDefaultColor()); + } else { + _color = MGLStyleValueTransformer().toStyleValue(colorValue); + } + + _colorTransiton = MGLTransitionFromOptions(mbglLight->getColorTransition()); + + auto intensityValue = mbglLight->getIntensity(); + if (intensityValue.isUndefined()) { + _intensity = MGLStyleValueTransformer().toStyleValue(mbglLight->getDefaultIntensity()); + } else { + _intensity = MGLStyleValueTransformer().toStyleValue(intensityValue); + } + + _intensityTransition = MGLTransitionFromOptions(mbglLight->getIntensityTransition()); + } + + return self; +} + +- (mbgl::style::Light)mbglLight +{ + mbgl::style::Light mbglLight; + + MGLStyleValue *anchorType = [MGLStyleValue valueWithRawValue:[NSValue valueWithMGLLightAnchor:self.anchor]]; + auto anchor = MGLStyleValueTransformer().toEnumPropertyValue(anchorType); + mbglLight.setAnchor(anchor); + + + mbglLight.setAnchorTransition(MGLOptionsFromTransition(self.anchorTransition)); + + auto position = MGLStyleValueTransformer().toInterpolatablePropertyValue(self.position); + mbglLight.setPosition(position); + + mbglLight.setPositionTransition(MGLOptionsFromTransition(self.positionTransiton)); + + auto color = MGLStyleValueTransformer().toInterpolatablePropertyValue(self.color); + mbglLight.setColor(color); + + mbglLight.setColorTransition(MGLOptionsFromTransition(self.colorTransiton)); + + auto intensity = MGLStyleValueTransformer().toInterpolatablePropertyValue(self.intensity); + mbglLight.setIntensity(intensity); + + mbglLight.setIntensityTransition(MGLOptionsFromTransition(self.intensityTransition)); + + return mbglLight; +} + +@end diff --git a/platform/darwin/src/MGLLight_Private.h b/platform/darwin/src/MGLLight_Private.h new file mode 100644 index 0000000000..dbc29c1eff --- /dev/null +++ b/platform/darwin/src/MGLLight_Private.h @@ -0,0 +1,23 @@ +#import + +#import "MGLLight.h" + +namespace mbgl { + namespace style { + class Light; + } +} + +@interface MGLLight (Private) + +/** + Initializes and returns a `MGLLight` associated with a style's light. + */ +- (instancetype)initWithMBGLLight:(const mbgl::style::Light *)mbglLight; + +/** + Returns an `mbgl::style::Light` representation of the `MGLLight`. + */ +- (mbgl::style::Light)mbglLight; + +@end diff --git a/platform/darwin/src/MGLStyle.h b/platform/darwin/src/MGLStyle.h index 26434eb492..08c6c047f1 100644 --- a/platform/darwin/src/MGLStyle.h +++ b/platform/darwin/src/MGLStyle.h @@ -6,6 +6,7 @@ #import "MGLTypes.h" @class MGLSource; +@class MGLLight; NS_ASSUME_NONNULL_BEGIN @@ -564,6 +565,14 @@ MGL_EXPORT */ - (void)removeImageForName:(NSString *)name; + +#pragma mark Managing the Style's Light + +/** + Provides global light source for the style. + */ +@property (nonatomic, strong) MGLLight *light; + @end NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm index af02c31b6d..eb838085d7 100644 --- a/platform/darwin/src/MGLStyle.mm +++ b/platform/darwin/src/MGLStyle.mm @@ -14,6 +14,7 @@ #import "MGLStyle_Private.h" #import "MGLStyleLayer_Private.h" #import "MGLSource_Private.h" +#import "MGLLight_Private.h" #import "NSDate+MGLAdditions.h" @@ -28,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -584,6 +586,21 @@ static NSURL *MGLStyleURL_emerald; return transition; } +#pragma mark Style light + +- (void)setLight:(MGLLight *)light +{ + std::unique_ptr mbglLight = std::make_unique([light mbglLight]); + self.mapView.mbglMap->setLight(std::move(mbglLight)); +} + +- (MGLLight *)light +{ + auto mbglLight = self.mapView.mbglMap->getLight(); + MGLLight *light = [[MGLLight alloc] initWithMBGLLight:mbglLight]; + return light; +} + - (NSString *)description { return [NSString stringWithFormat:@"<%@: %p; name = %@, URL = %@>", diff --git a/platform/darwin/src/MGLStyleValue_Private.h b/platform/darwin/src/MGLStyleValue_Private.h index 263b54d7e5..2155c657bd 100644 --- a/platform/darwin/src/MGLStyleValue_Private.h +++ b/platform/darwin/src/MGLStyleValue_Private.h @@ -3,11 +3,13 @@ #import "MGLStyleValue.h" #import "NSValue+MGLStyleAttributeAdditions.h" +#import "NSValue+MGLAdditions.h" #import "MGLTypes.h" #import "MGLConversion.h" #include #include +#import #import @@ -415,6 +417,12 @@ private: // Private utilities for converting from mgl to mbgl values mbglValue.push_back(mbglElement); } } + + void getMBGLValue(NSValue *rawValue, mbgl::style::Position &mbglValue) { + auto spherical = rawValue.mgl_lightPositionArrayValue; + mbgl::style::Position position(spherical); + mbglValue = position; + } // Enumerations template spherical = mbglStopValue.getSpherical(); + MGLSphericalPosition position = MGLSphericalPositionMake(spherical[0], spherical[1], spherical[2]); + return [NSValue valueWithMGLSphericalPosition:position]; + } // Enumerations template diff --git a/platform/darwin/src/MGLTypes.h b/platform/darwin/src/MGLTypes.h index c06fd8b0e7..16f510b5a6 100644 --- a/platform/darwin/src/MGLTypes.h +++ b/platform/darwin/src/MGLTypes.h @@ -1,4 +1,5 @@ #import +#import #import "MGLFoundation.h" diff --git a/platform/darwin/src/NSValue+MGLAdditions.h b/platform/darwin/src/NSValue+MGLAdditions.h index e6755021d0..0aaa2a337a 100644 --- a/platform/darwin/src/NSValue+MGLAdditions.h +++ b/platform/darwin/src/NSValue+MGLAdditions.h @@ -1,6 +1,7 @@ #import #import "MGLGeometry.h" +#import "MGLLight.h" #import "MGLOfflinePack.h" #import "MGLTypes.h" @@ -87,6 +88,34 @@ NS_ASSUME_NONNULL_BEGIN */ @property (readonly) MGLTransition MGLTransitionValue; +/** + Creates a new value object containing the given `MGLSphericalPosition` + structure. + + @param lightPosition The value for the new object. + @return A new value object that contains the light position information. + */ ++ (instancetype)valueWithMGLSphericalPosition:(MGLSphericalPosition)lightPosition; + +/** + The `MGLSphericalPosition` structure representation of the value. + */ +@property (readonly) MGLSphericalPosition MGLSphericalPositionValue; + +/** + Creates a new value object containing the given `MGLLightAnchor` + enum. + + @param lightAnchor The value for the new object. + @return A new value object that contains the light anchor information. + */ ++ (NSValue *)valueWithMGLLightAnchor:(MGLLightAnchor)lightAnchor; + +/** + The `MGLLightAnchor` enum representation of the value. + */ +@property (readonly) MGLLightAnchor MGLLightAnchorValue; + @end NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/NSValue+MGLAdditions.m b/platform/darwin/src/NSValue+MGLAdditions.m index a95ef23941..ef894f0eb4 100644 --- a/platform/darwin/src/NSValue+MGLAdditions.m +++ b/platform/darwin/src/NSValue+MGLAdditions.m @@ -58,4 +58,27 @@ return transition; } ++ (NSValue *)valueWithMGLSphericalPosition:(MGLSphericalPosition)lightPosition +{ + return [NSValue value:&lightPosition withObjCType:@encode(MGLSphericalPosition)]; +} + +- (MGLSphericalPosition)MGLSphericalPositionValue +{ + MGLSphericalPosition lightPosition; + [self getValue:&lightPosition]; + return lightPosition; +} + ++ (NSValue *)valueWithMGLLightAnchor:(MGLLightAnchor)lightAnchor { + return [NSValue value:&lightAnchor withObjCType:@encode(MGLLightAnchor)]; +} + +- (MGLLightAnchor)MGLLightAnchorValue +{ + MGLLightAnchor achorType; + [self getValue:&achorType]; + return achorType; +} + @end diff --git a/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.h b/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.h index 60c1ee4075..0f1e511694 100644 --- a/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.h +++ b/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.h @@ -9,5 +9,6 @@ - (std::array)mgl_offsetArrayValue; - (std::array)mgl_paddingArrayValue; +- (std::array)mgl_lightPositionArrayValue; @end diff --git a/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.mm b/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.mm index e66145aec1..a41950b6b3 100644 --- a/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.mm +++ b/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.mm @@ -1,5 +1,5 @@ #import "NSValue+MGLStyleAttributeAdditions.h" - +#import "MGLLight.h" #if TARGET_OS_IPHONE #import #define MGLEdgeInsets UIEdgeInsets @@ -61,4 +61,17 @@ }; } +- (std::array)mgl_lightPositionArrayValue +{ + NSAssert(strcmp(self.objCType, @encode(MGLSphericalPosition)) == 0, @"Value does not represent an MGLSphericalPosition"); + MGLSphericalPosition lightPosition; + [self getValue:&lightPosition]; + // Style specification defines padding in clockwise order: top, right, bottom, left. + return { + static_cast(lightPosition.radial), + static_cast(lightPosition.azimuthal), + static_cast(lightPosition.polar), + }; +} + @end diff --git a/platform/darwin/test/MGLLightTest.mm b/platform/darwin/test/MGLLightTest.mm new file mode 100644 index 0000000000..4639b13cde --- /dev/null +++ b/platform/darwin/test/MGLLightTest.mm @@ -0,0 +1,211 @@ +#import +#import + +#import "MGLLight_Private.h" + +#import "../../darwin/src/NSDate+MGLAdditions.h" + +#import +#import +#include + +@interface MGLLightTest : XCTestCase + +@end + +@implementation MGLLightTest + +- (void)testProperties { + + MGLTransition defaultTransition = MGLTransitionMake(0, 0); + MGLTransition transition = MGLTransitionMake(6, 3); + mbgl::style::TransitionOptions transitionOptions { { MGLDurationFromTimeInterval(6) }, { MGLDurationFromTimeInterval(3) } }; + + // anchor + { + mbgl::style::Light light; + MGLLight *mglLight = [[MGLLight alloc] initWithMBGLLight:&light]; + XCTAssertEqual(mglLight.anchor, MGLLightAnchorViewport); + XCTAssertEqual(mglLight.anchorTransition.delay, defaultTransition.delay); + XCTAssertEqual(mglLight.anchorTransition.duration, defaultTransition.duration); + + auto lightFromMGLlight = [mglLight mbglLight]; + + XCTAssertEqual(light.getDefaultAnchor(), lightFromMGLlight.getAnchor().asConstant()); + auto anchorTransition = lightFromMGLlight.getAnchorTransition(); + XCTAssert(anchorTransition.delay && MGLTimeIntervalFromDuration(*anchorTransition.delay) == defaultTransition.delay); + XCTAssert(anchorTransition.duration && MGLTimeIntervalFromDuration(*anchorTransition.duration) == defaultTransition.duration); + + mglLight.anchor = MGLLightAnchorMap; + mglLight.anchorTransition = transition; + + XCTAssertEqual(mglLight.anchor, MGLLightAnchorMap); + XCTAssertEqual(mglLight.anchorTransition.delay, transition.delay); + XCTAssertEqual(mglLight.anchorTransition.duration, transition.duration); + + mbgl::style::PropertyValue anchorProperty = { mbgl::style::LightAnchorType::Map }; + light.setAnchor(anchorProperty); + light.setAnchorTransition(transitionOptions); + + lightFromMGLlight = [mglLight mbglLight]; + + XCTAssertEqual(light.getAnchor().asConstant(), lightFromMGLlight.getAnchor().asConstant()); + anchorTransition = lightFromMGLlight.getAnchorTransition(); + XCTAssert(anchorTransition.delay && MGLTimeIntervalFromDuration(*anchorTransition.delay) == transition.delay); + XCTAssert(anchorTransition.duration && MGLTimeIntervalFromDuration(*anchorTransition.duration) == transition.duration); + + } + + // position + { + mbgl::style::Light light; + MGLLight *mglLight = [[MGLLight alloc] initWithMBGLLight:&light]; + NSAssert([mglLight.position isKindOfClass:[MGLConstantStyleValue class]], @"mglLight.position isn’t a MGLConstantStyleValue."); + NSValue *positionValue = ((MGLConstantStyleValue *)mglLight.position).rawValue; + auto positionArray = light.getDefaultPosition().getSpherical(); + MGLSphericalPosition defaultPosition = MGLSphericalPositionMake(positionArray[0], positionArray[1], positionArray[2]); + + XCTAssert(defaultPosition.radial == positionValue.MGLSphericalPositionValue.radial); + XCTAssert(defaultPosition.azimuthal == positionValue.MGLSphericalPositionValue.azimuthal); + XCTAssert(defaultPosition.polar == positionValue.MGLSphericalPositionValue.polar); + XCTAssertEqual(mglLight.positionTransiton.delay, defaultTransition.delay); + XCTAssertEqual(mglLight.positionTransiton.duration, defaultTransition.duration); + + auto lightFromMGLlight = [mglLight mbglLight]; + + XCTAssertEqual(positionArray, lightFromMGLlight.getPosition().asConstant().getSpherical()); + auto positionTransition = lightFromMGLlight.getPositionTransition(); + XCTAssert(positionTransition.delay && MGLTimeIntervalFromDuration(*positionTransition.delay) == defaultTransition.delay); + XCTAssert(positionTransition.duration && MGLTimeIntervalFromDuration(*positionTransition.duration) == defaultTransition.duration); + + defaultPosition = MGLSphericalPositionMake(6, 180, 90); + MGLStyleValue *positionStyleValue = [MGLStyleValue valueWithRawValue:[NSValue valueWithMGLSphericalPosition:defaultPosition]]; + mglLight.position = positionStyleValue; + mglLight.positionTransiton = transition; + + NSAssert([mglLight.position isKindOfClass:[MGLConstantStyleValue class]], @"mglLight.position isn’t a MGLConstantStyleValue."); + positionValue = ((MGLConstantStyleValue *)mglLight.position).rawValue; + + XCTAssert(defaultPosition.radial == positionValue.MGLSphericalPositionValue.radial); + XCTAssert(defaultPosition.azimuthal == positionValue.MGLSphericalPositionValue.azimuthal); + XCTAssert(defaultPosition.polar == positionValue.MGLSphericalPositionValue.polar); + XCTAssertEqual(mglLight.positionTransiton.delay, transition.delay); + XCTAssertEqual(mglLight.positionTransiton.duration, transition.duration); + + lightFromMGLlight = [mglLight mbglLight]; + + positionArray = { { 6, 180, 90 } }; + mbgl::style::Position position = { positionArray }; + mbgl::style::PropertyValue positionProperty = { position }; + light.setPosition(positionProperty); + light.setPositionTransition(transitionOptions); + + XCTAssertEqual(positionArray, lightFromMGLlight.getPosition().asConstant().getSpherical()); + positionTransition = lightFromMGLlight.getPositionTransition(); + XCTAssert(positionTransition.delay && MGLTimeIntervalFromDuration(*positionTransition.delay) == transition.delay); + XCTAssert(positionTransition.duration && MGLTimeIntervalFromDuration(*positionTransition.duration) == transition.duration); + + } + + // color + { + mbgl::style::Light light; + MGLLight *mglLight = [[MGLLight alloc] initWithMBGLLight:&light]; + NSAssert([mglLight.color isKindOfClass:[MGLConstantStyleValue class]], @"mglLight.color isn’t a MGLConstantStyleValue."); + MGLColor *colorValue = ((MGLConstantStyleValue *)mglLight.color).rawValue; + auto color = light.getDefaultColor(); + const CGFloat *colorComponents = CGColorGetComponents(colorValue.CGColor); + + XCTAssert(color.r == colorComponents[0] && color.g == colorComponents[1] && color.b == colorComponents[2] && + color.a == colorComponents[3]); + XCTAssertEqual(mglLight.colorTransiton.delay, defaultTransition.delay); + XCTAssertEqual(mglLight.colorTransiton.duration, defaultTransition.duration); + + auto lightFromMGLlight = [mglLight mbglLight]; + + XCTAssertEqual(color, lightFromMGLlight.getColor().asConstant()); + auto colorTransition = lightFromMGLlight.getColorTransition(); + XCTAssert(colorTransition.delay && MGLTimeIntervalFromDuration(*colorTransition.delay) == defaultTransition.delay); + XCTAssert(colorTransition.duration && MGLTimeIntervalFromDuration(*colorTransition.duration) == defaultTransition.duration); + + MGLStyleValue *colorStyleValue = [MGLStyleValue valueWithRawValue:[MGLColor blackColor]]; + mglLight.color = colorStyleValue; + mglLight.colorTransiton = transition; + + NSAssert([mglLight.color isKindOfClass:[MGLConstantStyleValue class]], @"mglLight.color isn’t a MGLConstantStyleValue."); + colorValue = ((MGLConstantStyleValue *)mglLight.color).rawValue; + + XCTAssertEqual([MGLColor blackColor], colorValue); + XCTAssertEqual(mglLight.colorTransiton.delay, transition.delay); + XCTAssertEqual(mglLight.colorTransiton.duration, transition.duration); + + mbgl::style::PropertyValue colorProperty = { { 0, 0, 0, 1 } }; + light.setColor(colorProperty); + light.setColorTransition(transitionOptions); + + lightFromMGLlight = [mglLight mbglLight]; + + colorComponents = CGColorGetComponents(colorValue.CGColor); + color = lightFromMGLlight.getColor().asConstant(); + XCTAssertEqual(light.getColor().asConstant(),lightFromMGLlight.getColor().asConstant()); + colorTransition = lightFromMGLlight.getColorTransition(); + XCTAssert(colorTransition.delay && MGLTimeIntervalFromDuration(*colorTransition.delay) == transition.delay); + XCTAssert(colorTransition.duration && MGLTimeIntervalFromDuration(*colorTransition.duration) == transition.duration); + } + + // intensity + { + mbgl::style::Light light; + MGLLight *mglLight = [[MGLLight alloc] initWithMBGLLight:&light]; + NSAssert([mglLight.intensity isKindOfClass:[MGLConstantStyleValue class]], @"mglLight.intensity isn’t a MGLConstantStyleValue."); + NSNumber *intensityNumber = ((MGLConstantStyleValue *)mglLight.intensity).rawValue; + auto intensity = light.getDefaultIntensity(); + + XCTAssert(intensityNumber.floatValue == intensity); + XCTAssertEqual(mglLight.intensityTransition.delay, defaultTransition.delay); + XCTAssertEqual(mglLight.intensityTransition.duration, defaultTransition.duration); + + auto lightFromMGLlight = [mglLight mbglLight]; + + XCTAssertEqual(intensity, lightFromMGLlight.getIntensity().asConstant()); + auto intensityTransition = lightFromMGLlight.getIntensityTransition(); + XCTAssert(intensityTransition.delay && MGLTimeIntervalFromDuration(*intensityTransition.delay) == defaultTransition.delay); + XCTAssert(intensityTransition.duration && MGLTimeIntervalFromDuration(*intensityTransition.duration) == defaultTransition.duration); + + NSNumber *intensityValue = @0.4; + MGLStyleValue *intensityStyleValue = [MGLStyleValue valueWithRawValue:intensityValue]; + mglLight.intensity = intensityStyleValue; + mglLight.intensityTransition = transition; + + NSAssert([mglLight.intensity isKindOfClass:[MGLConstantStyleValue class]], @"mglLight.intensity isn’t a MGLConstantStyleValue."); + intensityNumber = ((MGLConstantStyleValue *)mglLight.intensity).rawValue; + XCTAssert(intensityNumber.floatValue == intensityValue.floatValue); + XCTAssertEqual(mglLight.intensityTransition.delay, transition.delay); + XCTAssertEqual(mglLight.intensityTransition.duration, transition.duration); + + mbgl::style::PropertyValue intensityProperty = { 0.4 }; + light.setIntensity(intensityProperty); + light.setIntensityTransition(transitionOptions); + + lightFromMGLlight = [mglLight mbglLight]; + + XCTAssertEqual(light.getIntensity().asConstant(), lightFromMGLlight.getIntensity().asConstant()); + intensityTransition = lightFromMGLlight.getIntensityTransition(); + XCTAssert(intensityTransition.delay && MGLTimeIntervalFromDuration(*intensityTransition.delay) == transition.delay); + XCTAssert(intensityTransition.duration && MGLTimeIntervalFromDuration(*intensityTransition.duration) == transition.duration); + + } + +} + +- (void)testValueAdditions { + MGLSphericalPosition position = MGLSphericalPositionMake(1.15, 210, 30); + + XCTAssertEqual([NSValue valueWithMGLSphericalPosition:position].MGLSphericalPositionValue.radial, position.radial); + XCTAssertEqual([NSValue valueWithMGLSphericalPosition:position].MGLSphericalPositionValue.azimuthal, position.azimuthal); + XCTAssertEqual([NSValue valueWithMGLSphericalPosition:position].MGLSphericalPositionValue.polar, position.polar); + XCTAssertEqual([NSValue valueWithMGLLightAnchor:MGLLightAnchorMap].MGLLightAnchorValue, MGLLightAnchorMap); + XCTAssertEqual([NSValue valueWithMGLLightAnchor:MGLLightAnchorViewport].MGLLightAnchorValue, MGLLightAnchorViewport); +} + +@end diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index 215d31810d..27582c1acf 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -9,6 +9,13 @@ /* Begin PBXBuildFile section */ 1753ED421E53CE6F00A9FD90 /* MGLConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 1753ED411E53CE6F00A9FD90 /* MGLConversion.h */; }; 1753ED431E53CE6F00A9FD90 /* MGLConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 1753ED411E53CE6F00A9FD90 /* MGLConversion.h */; }; + 1F06668A1EC64F8E001C16D7 /* MGLLight.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F0666881EC64F8E001C16D7 /* MGLLight.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F06668D1EC64F8E001C16D7 /* MGLLight.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F0666891EC64F8E001C16D7 /* MGLLight.mm */; }; + 1F7454921ECBB42C00021D39 /* MGLLight.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F0666891EC64F8E001C16D7 /* MGLLight.mm */; }; + 1F7454931ECBB43F00021D39 /* MGLLight.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F0666881EC64F8E001C16D7 /* MGLLight.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F7454961ECD450D00021D39 /* MGLLight_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F7454941ECD450D00021D39 /* MGLLight_Private.h */; }; + 1F7454971ECD450D00021D39 /* MGLLight_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F7454941ECD450D00021D39 /* MGLLight_Private.h */; }; + 1F7454A91ED08AB400021D39 /* MGLLightTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F7454A61ED08AB400021D39 /* MGLLightTest.mm */; }; 1F95931D1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F95931C1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm */; }; 30E578171DAA85520050F07E /* UIImage+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 30E578111DAA7D690050F07E /* UIImage+MGLAdditions.h */; }; 30E578181DAA85520050F07E /* UIImage+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 30E578111DAA7D690050F07E /* UIImage+MGLAdditions.h */; }; @@ -545,6 +552,10 @@ /* Begin PBXFileReference section */ 1753ED411E53CE6F00A9FD90 /* MGLConversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLConversion.h; sourceTree = ""; }; + 1F0666881EC64F8E001C16D7 /* MGLLight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLLight.h; sourceTree = ""; }; + 1F0666891EC64F8E001C16D7 /* MGLLight.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLLight.mm; sourceTree = ""; }; + 1F7454941ECD450D00021D39 /* MGLLight_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLLight_Private.h; sourceTree = ""; }; + 1F7454A61ED08AB400021D39 /* MGLLightTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLLightTest.mm; path = ../../darwin/test/MGLLightTest.mm; sourceTree = ""; }; 1F95931C1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLNSDateAdditionsTests.mm; path = ../../darwin/test/MGLNSDateAdditionsTests.mm; sourceTree = ""; }; 20DABE861DF78148007AC5FF /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Foundation.strings"; sourceTree = ""; }; 20DABE881DF78148007AC5FF /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; @@ -1039,6 +1050,9 @@ 35599DB81D46AD7F0048254D /* Categories */, 353933F01D3FB6BA003F57D7 /* Layers */, 35136D491D4277EA00C20EFD /* Sources */, + 1F0666881EC64F8E001C16D7 /* MGLLight.h */, + 1F0666891EC64F8E001C16D7 /* MGLLight.mm */, + 1F7454941ECD450D00021D39 /* MGLLight_Private.h */, DAAF72291DA903C700312FA4 /* MGLStyleValue.h */, DAAF722A1DA903C700312FA4 /* MGLStyleValue_Private.h */, 35599DEA1D46F14E0048254D /* MGLStyleValue.mm */, @@ -1069,6 +1083,7 @@ children = ( 3575798F1D513EF1000B822E /* Layers */, 40CFA64E1D78754A008103BD /* Sources */, + 1F7454A61ED08AB400021D39 /* MGLLightTest.mm */, 357F09091DF84F3800941873 /* MGLStyleValueTests.h */, 3599A3E51DF708BC00E77FB2 /* MGLStyleValueTests.m */, DA2207BE1DC0805F0002F84D /* MGLStyleValueTests.swift */, @@ -1657,6 +1672,7 @@ DA8847F01CBAFA5100AB86E3 /* MGLAnnotation.h in Headers */, 7E016D841D9E890300A29A21 /* MGLPolygon+MGLAdditions.h in Headers */, 400533011DB0862B0069F638 /* NSArray+MGLAdditions.h in Headers */, + 1F06668A1EC64F8E001C16D7 /* MGLLight.h in Headers */, 4049C29D1DB6CD6C00B3F799 /* MGLPointCollection.h in Headers */, 40CF6DBB1DAC3C6600A4D18B /* MGLShape_Private.h in Headers */, 4018B1CA1CDC288E00F666AF /* MGLAnnotationView.h in Headers */, @@ -1705,6 +1721,7 @@ 353933F21D3FB753003F57D7 /* MGLCircleStyleLayer.h in Headers */, DA8847F31CBAFA5100AB86E3 /* MGLMultiPoint.h in Headers */, 30E578171DAA85520050F07E /* UIImage+MGLAdditions.h in Headers */, + 1F7454961ECD450D00021D39 /* MGLLight_Private.h in Headers */, DAD1656C1CF41981001FF4B9 /* MGLFeature.h in Headers */, 40EDA1C01CFE0E0200D9EA68 /* MGLAnnotationContainerView.h in Headers */, 9620BB381E69FE1700705A1D /* MGLSDKUpdateChecker.h in Headers */, @@ -1783,6 +1800,7 @@ 35CE61831D4165D9004F2359 /* UIColor+MGLAdditions.h in Headers */, DABFB8671CBE99E500D62B32 /* MGLPolygon.h in Headers */, 404C26E81D89C55D000AA13D /* MGLTileSource_Private.h in Headers */, + 1F7454931ECBB43F00021D39 /* MGLLight.h in Headers */, DAAF722C1DA903C700312FA4 /* MGLStyleValue.h in Headers */, DABFB8651CBE99E500D62B32 /* MGLOverlay.h in Headers */, 35E79F211D41266300957B9E /* MGLStyleLayer_Private.h in Headers */, @@ -1816,6 +1834,7 @@ DA35A2BC1CCA9A6900E826B2 /* MGLClockDirectionFormatter.h in Headers */, 35D13AC41D3D19DD00AFB4E0 /* MGLFillStyleLayer.h in Headers */, DABFB86E1CBE9A0F00D62B32 /* MGLCalloutView.h in Headers */, + 1F7454971ECD450D00021D39 /* MGLLight_Private.h in Headers */, DABFB8601CBE99E500D62B32 /* MGLMapCamera.h in Headers */, DA737EE21D056A4E005BDA16 /* MGLMapViewDelegate.h in Headers */, DAF0D8191DFE6B2800B28378 /* MGLAttributionInfo_Private.h in Headers */, @@ -2166,6 +2185,7 @@ DAE7DEC21E245455007505A6 /* MGLNSStringAdditionsTests.m in Sources */, 4085AF091D933DEA00F11B22 /* MGLTileSetTests.mm in Sources */, DAEDC4341D603417000224FF /* MGLAttributionInfoTests.m in Sources */, + 1F7454A91ED08AB400021D39 /* MGLLightTest.mm in Sources */, 357579851D502AF5000B822E /* MGLSymbolStyleLayerTests.mm in Sources */, 357579871D502AFE000B822E /* MGLLineStyleLayerTests.mm in Sources */, 357579891D502B06000B822E /* MGLCircleStyleLayerTests.mm in Sources */, @@ -2221,6 +2241,7 @@ 3566C76E1D4A8DFA008152BC /* MGLRasterSource.mm in Sources */, DA88488C1CBB037E00AB86E3 /* SMCalloutView.m in Sources */, 35136D4E1D4277FC00C20EFD /* MGLSource.mm in Sources */, + 1F06668D1EC64F8E001C16D7 /* MGLLight.mm in Sources */, DA35A2B81CCA9A5D00E826B2 /* MGLClockDirectionFormatter.m in Sources */, DAD1657A1CF4CDFF001FF4B9 /* MGLShapeCollection.mm in Sources */, 35136D451D42275100C20EFD /* MGLSymbolStyleLayer.mm in Sources */, @@ -2328,6 +2349,7 @@ DAA4E4321CBB730400178DFB /* MGLMapView.mm in Sources */, DAA4E41E1CBB730400178DFB /* MGLMapCamera.mm in Sources */, FA68F14E1E9D656600F9F6C2 /* MGLFillExtrusionStyleLayer.mm in Sources */, + 1F7454921ECBB42C00021D39 /* MGLLight.mm in Sources */, 404C26E51D89B877000AA13D /* MGLTileSource.mm in Sources */, 355AE0021E9281DA00F3939D /* MGLScaleBar.mm in Sources */, 4018B1C81CDC287F00F666AF /* MGLAnnotationView.mm in Sources */, diff --git a/platform/ios/src/Mapbox.h b/platform/ios/src/Mapbox.h index 9a9dc702ca..67a26e8ed4 100644 --- a/platform/ios/src/Mapbox.h +++ b/platform/ios/src/Mapbox.h @@ -19,6 +19,7 @@ FOUNDATION_EXPORT MGL_EXPORT const unsigned char MapboxVersionString[]; #import "MGLDistanceFormatter.h" #import "MGLFeature.h" #import "MGLGeometry.h" +#import "MGLLight.h" #import "MGLMapCamera.h" #import "MGLMapView.h" #import "MGLMapView+IBAdditions.h" diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj index 9a18ce4a0e..1127524098 100644 --- a/platform/macos/macos.xcodeproj/project.pbxproj +++ b/platform/macos/macos.xcodeproj/project.pbxproj @@ -8,6 +8,10 @@ /* Begin PBXBuildFile section */ 1753ED401E53CE6100A9FD90 /* MGLConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 1753ED3F1E53CE5200A9FD90 /* MGLConversion.h */; }; + 1F7454A31ECFB00300021D39 /* MGLLight_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F7454A01ECFB00300021D39 /* MGLLight_Private.h */; }; + 1F7454A41ECFB00300021D39 /* MGLLight.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F7454A11ECFB00300021D39 /* MGLLight.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F7454A51ECFB00300021D39 /* MGLLight.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F7454A21ECFB00300021D39 /* MGLLight.mm */; }; + 1F7454AB1ED1DDBD00021D39 /* MGLLightTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F7454AA1ED1DDBD00021D39 /* MGLLightTest.mm */; }; 1F95931B1E6DE2B600D5B294 /* MGLNSDateAdditionsTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F95931A1E6DE2B600D5B294 /* MGLNSDateAdditionsTests.mm */; }; 30E5781B1DAA857E0050F07E /* NSImage+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 30E578141DAA7D920050F07E /* NSImage+MGLAdditions.h */; }; 3508EC641D749D39009B0EE4 /* NSExpression+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3508EC621D749D39009B0EE4 /* NSExpression+MGLAdditions.h */; }; @@ -268,6 +272,10 @@ /* Begin PBXFileReference section */ 1753ED3F1E53CE5200A9FD90 /* MGLConversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLConversion.h; sourceTree = ""; }; + 1F7454A01ECFB00300021D39 /* MGLLight_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLLight_Private.h; sourceTree = ""; }; + 1F7454A11ECFB00300021D39 /* MGLLight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLLight.h; sourceTree = ""; }; + 1F7454A21ECFB00300021D39 /* MGLLight.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLLight.mm; sourceTree = ""; }; + 1F7454AA1ED1DDBD00021D39 /* MGLLightTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLLightTest.mm; sourceTree = ""; }; 1F95931A1E6DE2B600D5B294 /* MGLNSDateAdditionsTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLNSDateAdditionsTests.mm; path = ../../darwin/test/MGLNSDateAdditionsTests.mm; sourceTree = ""; }; 30E578141DAA7D920050F07E /* NSImage+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSImage+MGLAdditions.h"; path = "src/NSImage+MGLAdditions.h"; sourceTree = SOURCE_ROOT; }; 3508EC621D749D39009B0EE4 /* NSExpression+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSExpression+MGLAdditions.h"; sourceTree = ""; }; @@ -670,6 +678,9 @@ 352742771D4C220900A1ECE6 /* MGLStyleValue.h */, DA8F259B1D51CB000010E6B5 /* MGLStyleValue_Private.h */, 3527429E1D4C25BD00A1ECE6 /* MGLStyleValue.mm */, + 1F7454A11ECFB00300021D39 /* MGLLight.h */, + 1F7454A21ECFB00300021D39 /* MGLLight.mm */, + 1F7454A01ECFB00300021D39 /* MGLLight_Private.h */, ); name = Styling; sourceTree = ""; @@ -810,6 +821,7 @@ children = ( DA8F257C1D51C5F40010E6B5 /* Layers */, DA87A99A1DC9D88800810D09 /* Sources */, + 1F7454AA1ED1DDBD00021D39 /* MGLLightTest.mm */, 353722EB1DF850ED004D2F3F /* MGLStyleValueTests.h */, 3599A3E71DF70E2000E77FB2 /* MGLStyleValueTests.m */, DA2207BB1DC076940002F84D /* MGLStyleValueTests.swift */, @@ -1133,6 +1145,7 @@ DA8F258B1D51CA540010E6B5 /* MGLLineStyleLayer.h in Headers */, 35C6DF841E214C0400ACA483 /* MGLDistanceFormatter.h in Headers */, DA8F25B21D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.h in Headers */, + 1F7454A31ECFB00300021D39 /* MGLLight_Private.h in Headers */, 359819591E02F611008FC139 /* NSCoder+MGLAdditions.h in Headers */, DAE6C38E1CC31E2A00DB3429 /* MGLOfflineStorage_Private.h in Headers */, 408AA8661DAEEE3600022900 /* MGLPolyline+MGLAdditions.h in Headers */, @@ -1166,6 +1179,7 @@ DACC22181CF3D4F700D220D9 /* MGLFeature_Private.h in Headers */, DA6408D71DA4E5DA00908C90 /* MGLVectorStyleLayer.h in Headers */, 352742891D4C245800A1ECE6 /* MGLShapeSource.h in Headers */, + 1F7454A41ECFB00300021D39 /* MGLLight.h in Headers */, 408AA8671DAEEE3900022900 /* NSDictionary+MGLAdditions.h in Headers */, DAE6C3671CC31E0400DB3429 /* MGLStyle.h in Headers */, ); @@ -1380,6 +1394,7 @@ DAE6C38C1CC31E2A00DB3429 /* MGLOfflinePack.mm in Sources */, 35D65C5B1D65AD5500722C23 /* NSDate+MGLAdditions.mm in Sources */, DD0902B21DB1AC6400C5BDCE /* MGLNetworkConfiguration.m in Sources */, + 1F7454A51ECFB00300021D39 /* MGLLight.mm in Sources */, DAE6C3B11CC31EF300DB3429 /* MGLAnnotationImage.m in Sources */, 3508EC651D749D39009B0EE4 /* NSExpression+MGLAdditions.mm in Sources */, DACC22151CF3D3E200D220D9 /* MGLFeature.mm in Sources */, @@ -1446,6 +1461,7 @@ DA35A2C21CCA9F4A00E826B2 /* MGLClockDirectionFormatterTests.m in Sources */, DAE6C3D41CC34C9900DB3429 /* MGLOfflineRegionTests.m in Sources */, DAE6C3D61CC34C9900DB3429 /* MGLStyleTests.mm in Sources */, + 1F7454AB1ED1DDBD00021D39 /* MGLLightTest.mm in Sources */, DAEDC4371D606291000224FF /* MGLAttributionButtonTests.m in Sources */, 920A3E591E6F859D00C16EFC /* MGLSourceQueryTests.m in Sources */, DA35A2B61CCA14D700E826B2 /* MGLCompassDirectionFormatterTests.m in Sources */, diff --git a/platform/macos/src/Mapbox.h b/platform/macos/src/Mapbox.h index dcb5b50b8f..0f47dace70 100644 --- a/platform/macos/src/Mapbox.h +++ b/platform/macos/src/Mapbox.h @@ -17,6 +17,7 @@ FOUNDATION_EXPORT MGL_EXPORT const unsigned char MapboxVersionString[]; #import "MGLDistanceFormatter.h" #import "MGLFeature.h" #import "MGLGeometry.h" +#import "MGLLight.h" #import "MGLMapCamera.h" #import "MGLMapView.h" #import "MGLMapView+IBAdditions.h" -- cgit v1.2.1 From 71b686517298e100f8021dca62db65a2ca9baad2 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Tue, 23 May 2017 17:14:18 +0200 Subject: [android] - horizontally rotated in snapshot (#9083) --- platform/android/src/map/camera_position.cpp | 7 ++++--- platform/android/src/native_map_view.cpp | 12 ++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/platform/android/src/map/camera_position.cpp b/platform/android/src/map/camera_position.cpp index f059fbd413..27b19f7ad6 100644 --- a/platform/android/src/map/camera_position.cpp +++ b/platform/android/src/map/camera_position.cpp @@ -11,8 +11,9 @@ jni::Object CameraPosition::New(jni::JNIEnv &env, mbgl::CameraOp auto center = options.center.value(); center.wrap(); - // convert bearing, core ranges from [−π rad, π rad], android from 0 to 360 degrees - double bearing_degrees = (options.angle.value_or(0) * 180.0 / M_PI) + 180; + // convert bearing, measured in radians counterclockwise from true north. + // Wrapped to [−π rad, π rad). Android binding from 0 to 360 degrees + double bearing_degrees = -options.angle.value_or(-M_PI) * util::RAD2DEG; while (bearing_degrees > 360) { bearing_degrees -= 360; } @@ -21,7 +22,7 @@ jni::Object CameraPosition::New(jni::JNIEnv &env, mbgl::CameraOp } // convert tilt, core ranges from [0 rad, 1,0472 rad], android ranges from 0 to 60 - double tilt_degrees = options.pitch.value_or(0) * 180 / M_PI; + double tilt_degrees = options.pitch.value_or(0) * util::RAD2DEG; return CameraPosition::javaClass.New(env, constructor, LatLng::New(env, center), options.zoom.value_or(0), tilt_degrees, bearing_degrees); } diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index 3dbfd6809a..1012a0e9d8 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -385,12 +385,12 @@ void NativeMapView::moveBy(jni::JNIEnv&, jni::jdouble dx, jni::jdouble dy, jni:: void NativeMapView::jumpTo(jni::JNIEnv&, jni::jdouble angle, jni::jdouble latitude, jni::jdouble longitude, jni::jdouble pitch, jni::jdouble zoom) { mbgl::CameraOptions options; if (angle != -1) { - options.angle = (angle - 180 * M_PI) / 180; + options.angle = -angle * util::DEG2RAD; } options.center = mbgl::LatLng(latitude, longitude); options.padding = insets; if (pitch != -1) { - options.pitch = pitch * M_PI / 180; + options.pitch = pitch * util::DEG2RAD; } if (zoom != -1) { options.zoom = zoom; @@ -402,12 +402,12 @@ void NativeMapView::jumpTo(jni::JNIEnv&, jni::jdouble angle, jni::jdouble latitu void NativeMapView::easeTo(jni::JNIEnv&, jni::jdouble angle, jni::jdouble latitude, jni::jdouble longitude, jni::jlong duration, jni::jdouble pitch, jni::jdouble zoom, jni::jboolean easing) { mbgl::CameraOptions cameraOptions; if (angle != -1) { - cameraOptions.angle = (angle - 180 * M_PI) / 180; + cameraOptions.angle = -angle * util::DEG2RAD; } cameraOptions.center = mbgl::LatLng(latitude, longitude); cameraOptions.padding = insets; if (pitch != -1) { - cameraOptions.pitch = pitch * M_PI / 180; + cameraOptions.pitch = pitch * util::DEG2RAD; } if (zoom != -1) { cameraOptions.zoom = zoom; @@ -426,12 +426,12 @@ void NativeMapView::easeTo(jni::JNIEnv&, jni::jdouble angle, jni::jdouble latitu void NativeMapView::flyTo(jni::JNIEnv&, jni::jdouble angle, jni::jdouble latitude, jni::jdouble longitude, jni::jlong duration, jni::jdouble pitch, jni::jdouble zoom) { mbgl::CameraOptions cameraOptions; if (angle != -1) { - cameraOptions.angle = (angle - 180 * M_PI / 180); + cameraOptions.angle = -angle * util::DEG2RAD; } cameraOptions.center = mbgl::LatLng(latitude, longitude); cameraOptions.padding = insets; if (pitch != -1) { - cameraOptions.pitch = pitch * M_PI / 180; + cameraOptions.pitch = pitch * util::DEG2RAD; } if (zoom != -1) { cameraOptions.zoom = zoom; -- cgit v1.2.1 From fe17f7e8db266a125ac05d805003f5d2bf1548c6 Mon Sep 17 00:00:00 2001 From: Fabian Guerra Soto Date: Tue, 23 May 2017 12:02:09 -0400 Subject: Cherry-pick arabic text to release branch v3.6.0 (#9071) * [core] Throttle tiles to redo symbol placement at most once every 300ms. Fixes issue #8435 and prepares for pitch-scaling changes in issue #8967. * [core] Disable letter-spacing for Arabic labels (issue #9057) --- cmake/core-files.cmake | 2 ++ src/mbgl/layout/symbol_layout.cpp | 2 +- src/mbgl/tile/geometry_tile.cpp | 12 ++++++++++-- src/mbgl/tile/geometry_tile.hpp | 5 +++++ src/mbgl/util/i18n.cpp | 19 ++++++++++++++----- src/mbgl/util/i18n.hpp | 4 ++++ src/mbgl/util/throttler.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/mbgl/util/throttler.hpp | 22 ++++++++++++++++++++++ 8 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 src/mbgl/util/throttler.cpp create mode 100644 src/mbgl/util/throttler.hpp diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index e9d7442e5d..4779abba86 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -583,6 +583,8 @@ set(MBGL_CORE_FILES src/mbgl/util/thread_context.cpp src/mbgl/util/thread_context.hpp src/mbgl/util/thread_local.hpp + src/mbgl/util/throttler.cpp + src/mbgl/util/throttler.hpp src/mbgl/util/tile_coordinate.hpp src/mbgl/util/tile_cover.cpp src/mbgl/util/tile_cover.hpp diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index aa91eb1688..2accac281b 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -237,7 +237,7 @@ void SymbolLayout::prepare(const GlyphPositionMap& glyphs, const IconMap& icons) /* horizontalAlign */ horizontalAlign, /* verticalAlign */ verticalAlign, /* justify */ justify, - /* spacing: ems */ layout.get() * oneEm, + /* spacing: ems */ util::i18n::allowsLetterSpacing(*feature.text) ? layout.get() * oneEm : 0.0f, /* translate */ Point(layout.evaluate(zoom, feature)[0] * oneEm, layout.evaluate(zoom, feature)[1] * oneEm), /* verticalHeight */ oneEm, /* writingMode */ writingMode, diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp index a8eda38284..29ba7d42cd 100644 --- a/src/mbgl/tile/geometry_tile.cpp +++ b/src/mbgl/tile/geometry_tile.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -41,7 +42,8 @@ GeometryTile::GeometryTile(const OverscaledTileID& id_, obsolete, parameters.mode), glyphAtlas(glyphAtlas_), - spriteAtlas(spriteAtlas_) { + spriteAtlas(spriteAtlas_), + placementThrottler(Milliseconds(300), [this] { invokePlacement(); }) { } GeometryTile::~GeometryTile() { @@ -81,7 +83,13 @@ void GeometryTile::setPlacementConfig(const PlacementConfig& desiredConfig) { ++correlationID; requestedConfig = desiredConfig; - worker.invoke(&GeometryTileWorker::setPlacementConfig, desiredConfig, correlationID); + placementThrottler.invoke(); +} + +void GeometryTile::invokePlacement() { + if (requestedConfig) { + worker.invoke(&GeometryTileWorker::setPlacementConfig, *requestedConfig, correlationID); + } } void GeometryTile::redoLayout() { diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp index 594952d329..ed5d8d87bf 100644 --- a/src/mbgl/tile/geometry_tile.hpp +++ b/src/mbgl/tile/geometry_tile.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -87,6 +88,8 @@ protected: } private: + void invokePlacement(); + const std::string sourceID; style::Style& style; @@ -108,6 +111,8 @@ private: std::unordered_map> symbolBuckets; std::unique_ptr collisionTile; + + util::Throttler placementThrottler; }; } // namespace mbgl diff --git a/src/mbgl/util/i18n.cpp b/src/mbgl/util/i18n.cpp index 8e56877a64..6cfdc697e3 100644 --- a/src/mbgl/util/i18n.cpp +++ b/src/mbgl/util/i18n.cpp @@ -1,5 +1,6 @@ #include "i18n.hpp" +#include #include namespace { @@ -29,14 +30,14 @@ DEFINE_IS_IN_UNICODE_BLOCK(Latin1Supplement, 0x0080, 0x00FF) // DEFINE_IS_IN_UNICODE_BLOCK(CyrillicSupplement, 0x0500, 0x052F) // DEFINE_IS_IN_UNICODE_BLOCK(Armenian, 0x0530, 0x058F) // DEFINE_IS_IN_UNICODE_BLOCK(Hebrew, 0x0590, 0x05FF) -// DEFINE_IS_IN_UNICODE_BLOCK(Arabic, 0x0600, 0x06FF) +DEFINE_IS_IN_UNICODE_BLOCK(Arabic, 0x0600, 0x06FF) // DEFINE_IS_IN_UNICODE_BLOCK(Syriac, 0x0700, 0x074F) -// DEFINE_IS_IN_UNICODE_BLOCK(ArabicSupplement, 0x0750, 0x077F) +DEFINE_IS_IN_UNICODE_BLOCK(ArabicSupplement, 0x0750, 0x077F) // DEFINE_IS_IN_UNICODE_BLOCK(Thaana, 0x0780, 0x07BF) // DEFINE_IS_IN_UNICODE_BLOCK(NKo, 0x07C0, 0x07FF) // DEFINE_IS_IN_UNICODE_BLOCK(Samaritan, 0x0800, 0x083F) // DEFINE_IS_IN_UNICODE_BLOCK(Mandaic, 0x0840, 0x085F) -// DEFINE_IS_IN_UNICODE_BLOCK(ArabicExtendedA, 0x08A0, 0x08FF) +DEFINE_IS_IN_UNICODE_BLOCK(ArabicExtendedA, 0x08A0, 0x08FF) // DEFINE_IS_IN_UNICODE_BLOCK(Devanagari, 0x0900, 0x097F) // DEFINE_IS_IN_UNICODE_BLOCK(Bengali, 0x0980, 0x09FF) // DEFINE_IS_IN_UNICODE_BLOCK(Gurmukhi, 0x0A00, 0x0A7F) @@ -169,13 +170,13 @@ DEFINE_IS_IN_UNICODE_BLOCK(HangulJamoExtendedB, 0xD7B0, 0xD7FF) DEFINE_IS_IN_UNICODE_BLOCK(PrivateUseArea, 0xE000, 0xF8FF) DEFINE_IS_IN_UNICODE_BLOCK(CJKCompatibilityIdeographs, 0xF900, 0xFAFF) // DEFINE_IS_IN_UNICODE_BLOCK(AlphabeticPresentationForms, 0xFB00, 0xFB4F) -// DEFINE_IS_IN_UNICODE_BLOCK(ArabicPresentationFormsA, 0xFB50, 0xFDFF) +DEFINE_IS_IN_UNICODE_BLOCK(ArabicPresentationFormsA, 0xFB50, 0xFDFF) // DEFINE_IS_IN_UNICODE_BLOCK(VariationSelectors, 0xFE00, 0xFE0F) DEFINE_IS_IN_UNICODE_BLOCK(VerticalForms, 0xFE10, 0xFE1F) // DEFINE_IS_IN_UNICODE_BLOCK(CombiningHalfMarks, 0xFE20, 0xFE2F) DEFINE_IS_IN_UNICODE_BLOCK(CJKCompatibilityForms, 0xFE30, 0xFE4F) DEFINE_IS_IN_UNICODE_BLOCK(SmallFormVariants, 0xFE50, 0xFE6F) -// DEFINE_IS_IN_UNICODE_BLOCK(ArabicPresentationFormsB, 0xFE70, 0xFEFF) +DEFINE_IS_IN_UNICODE_BLOCK(ArabicPresentationFormsB, 0xFE70, 0xFEFF) DEFINE_IS_IN_UNICODE_BLOCK(HalfwidthandFullwidthForms, 0xFF00, 0xFFEF) // DEFINE_IS_IN_UNICODE_BLOCK(Specials, 0xFFF0, 0xFFFF) // DEFINE_IS_IN_UNICODE_BLOCK(LinearBSyllabary, 0x10000, 0x1007F) @@ -332,6 +333,14 @@ bool allowsWordBreaking(char16_t chr) { || chr == 0x2013 /* en dash */); } +bool charAllowsLetterSpacing(char16_t chr) { + return !(isInArabic(chr) || isInArabicSupplement(chr) || isInArabicExtendedA(chr) || isInArabicPresentationFormsA(chr) || isInArabicPresentationFormsB(chr)); +} + +bool allowsLetterSpacing(const std::u16string& string) { + return std::all_of(string.begin(), string.end(), charAllowsLetterSpacing); +} + bool allowsIdeographicBreaking(const std::u16string& string) { for (char16_t chr : string) { if (!allowsIdeographicBreaking(chr)) { diff --git a/src/mbgl/util/i18n.hpp b/src/mbgl/util/i18n.hpp index 186212f50d..61c5a1ea96 100644 --- a/src/mbgl/util/i18n.hpp +++ b/src/mbgl/util/i18n.hpp @@ -10,6 +10,10 @@ namespace i18n { by the given Unicode codepoint due to word breaking. */ bool allowsWordBreaking(char16_t chr); +/** Returns whether the given string can be displayed with letter-spacing. + False for Arabic scripts, where letter-spacing will break ligatures. */ +bool allowsLetterSpacing(const std::u16string& string); + /** Returns whether a line break can be inserted after any character in the given string. If false, line breaking should occur on word boundaries instead. */ diff --git a/src/mbgl/util/throttler.cpp b/src/mbgl/util/throttler.cpp new file mode 100644 index 0000000000..910810ce2f --- /dev/null +++ b/src/mbgl/util/throttler.cpp @@ -0,0 +1,36 @@ +#include + +namespace mbgl { +namespace util { + +Throttler::Throttler(Duration frequency_, std::function&& function_) + : frequency(frequency_) + , function(std::move(function_)) + , pendingInvocation(false) + , lastInvocation(TimePoint::min()) +{} + +void Throttler::invoke() { + if (pendingInvocation) { + return; + } + + Duration timeToNextInvocation = lastInvocation == TimePoint::min() + ? Duration::zero() + : (lastInvocation + frequency) - Clock::now(); + + if (timeToNextInvocation <= Duration::zero()) { + lastInvocation = Clock::now(); + function(); + } else { + pendingInvocation = true; + timer.start(timeToNextInvocation, Duration::zero(), [this]{ + pendingInvocation = false; + lastInvocation = Clock::now(); + function(); + }); + } +} + +} // namespace util +} // namespace mbgl diff --git a/src/mbgl/util/throttler.hpp b/src/mbgl/util/throttler.hpp new file mode 100644 index 0000000000..175de7ccaf --- /dev/null +++ b/src/mbgl/util/throttler.hpp @@ -0,0 +1,22 @@ +#include +#include + +namespace mbgl { +namespace util { + +class Throttler { +public: + Throttler(Duration frequency, std::function&& function); + + void invoke(); +private: + Duration frequency; + std::function function; + + Timer timer; + bool pendingInvocation; + TimePoint lastInvocation; +}; + +} // namespace util +} // namespace mbgl -- cgit v1.2.1 From a57e9bc41093eb8f028dcab3593c3921d887bdc0 Mon Sep 17 00:00:00 2001 From: Fabian Guerra Soto Date: Tue, 23 May 2017 12:32:18 -0400 Subject: [ios,macos] multipolygon coordinate (#8713) * [ios] MGLMultiPolygon's coordinate property implemented * [ios,macos] Add polylabalel to project config * [ios,macos] Change coordinate property for MGLPolyline,MGLPolygon,MGLMultiPolygon * [macos] Change project configuration to support polilabel * [ios,macos] Add MGLLocationCoordinate2DFromPoint * [ios, macos] Update changelogs * [ios, macos] remove unnecesary variables * [ios, macos] Add radians conversions * [ios, macos] Add coordinate calc to MGLPolyline * [ios, macos] Move radian fuctions to MGLGeometry_Private.h * [ios, macos] Fix code style * [ios, macos] Fix code indentation * [ios, macos] Fix radian per meters constant * [ios, macos] Add test scenarios to testPolyline * [ios, macos] Fix test accuracy --- platform/darwin/src/MGLGeometry_Private.h | 64 +++++++++++++ platform/darwin/src/MGLPolygon.mm | 20 ++++- platform/darwin/src/MGLPolyline.mm | 65 ++++++++++++++ platform/darwin/test/MGLCodingTests.m | 119 ++++++++++++++++++++++++- platform/ios/CHANGELOG.md | 1 + platform/ios/ios.xcodeproj/project.pbxproj | 30 +++++-- platform/macos/CHANGELOG.md | 1 + platform/macos/macos.xcodeproj/project.pbxproj | 20 ++++- scripts/config.xcconfig.in | 1 + 9 files changed, 307 insertions(+), 14 deletions(-) diff --git a/platform/darwin/src/MGLGeometry_Private.h b/platform/darwin/src/MGLGeometry_Private.h index 3e029e8ee0..7ad8314a79 100644 --- a/platform/darwin/src/MGLGeometry_Private.h +++ b/platform/darwin/src/MGLGeometry_Private.h @@ -8,6 +8,26 @@ #import #import +typedef double MGLLocationRadians; +typedef double MGLRadianDistance; +typedef double MGLRadianDirection; + +/** Defines the coordinate by a `MGLRadianCoordinate2D`. */ +typedef struct MGLRadianCoordinate2D { + MGLLocationRadians latitude; + MGLLocationRadians longitude; +} MGLRadianCoordinate2D; + +/** + Creates a new `MGLRadianCoordinate2D` from the given latitudinal and longitudinal. + */ +NS_INLINE MGLRadianCoordinate2D MGLRadianCoordinate2DMake(MGLLocationRadians latitude, MGLLocationRadians longitude) { + MGLRadianCoordinate2D radianCoordinate; + radianCoordinate.latitude = latitude; + radianCoordinate.longitude = longitude; + return radianCoordinate; +} + /// Returns the smallest rectangle that contains both the given rectangle and /// the given point. CGRect MGLExtendRect(CGRect rect, CGPoint point); @@ -18,6 +38,10 @@ NS_INLINE mbgl::Point MGLPointFromLocationCoordinate2D(CLLocationCoordin return mbgl::Point(coordinate.longitude, coordinate.latitude); } +NS_INLINE CLLocationCoordinate2D MGLLocationCoordinate2DFromPoint(mbgl::Point point) { + return CLLocationCoordinate2DMake(point.y, point.x); +} + NS_INLINE CLLocationCoordinate2D MGLLocationCoordinate2DFromLatLng(mbgl::LatLng latLng) { return CLLocationCoordinate2DMake(latLng.latitude(), latLng.longitude()); } @@ -59,3 +83,43 @@ CLLocationDistance MGLAltitudeForZoomLevel(double zoomLevel, CGFloat pitch, CLLo @param size The size of the viewport. @return A zero-based zoom level. */ double MGLZoomLevelForAltitude(CLLocationDistance altitude, CGFloat pitch, CLLocationDegrees latitude, CGSize size); + +/** Returns MGLRadianCoordinate2D, converted from CLLocationCoordinate2D. */ +NS_INLINE MGLRadianCoordinate2D MGLRadianCoordinateFromLocationCoordinate(CLLocationCoordinate2D locationCoordinate) { + return MGLRadianCoordinate2DMake(MGLRadiansFromDegrees(locationCoordinate.latitude), + MGLRadiansFromDegrees(locationCoordinate.longitude)); +} + +/* + Returns the distance in radians given two coordinates. + */ +NS_INLINE MGLRadianDistance MGLDistanceBetweenRadianCoordinates(MGLRadianCoordinate2D from, MGLRadianCoordinate2D to) +{ + double a = pow(sin((to.latitude - from.latitude) / 2), 2) + + pow(sin((to.longitude - from.longitude) / 2), 2) * cos(from.latitude) * cos(to.latitude); + + return 2 * atan2(sqrt(a), sqrt(1 - a)); +} + +/* + Returns direction in radians given two coordinates. + */ +NS_INLINE MGLRadianDirection MGLRadianCoordinatesDirection(MGLRadianCoordinate2D from, MGLRadianCoordinate2D to) { + double a = sin(to.longitude - from.longitude) * cos(to.latitude); + double b = cos(from.latitude) * sin(to.latitude) + - sin(from.latitude) * cos(to.latitude) * cos(to.longitude - from.longitude); + return atan2(a, b); +} + +/* + Returns coordinate at a given distance and direction away from coordinate. + */ +NS_INLINE MGLRadianCoordinate2D MGLRadianCoordinateAtDistanceFacingDirection(MGLRadianCoordinate2D coordinate, + MGLRadianDistance distance, + MGLRadianDirection direction) { + double otherLatitude = asin(sin(coordinate.latitude) * cos(distance) + + cos(coordinate.latitude) * sin(distance) * cos(direction)); + double otherLongitude = coordinate.longitude + atan2(sin(direction) * sin(distance) * cos(coordinate.latitude), + cos(distance) - sin(coordinate.latitude) * sin(otherLatitude)); + return MGLRadianCoordinate2DMake(otherLatitude, otherLongitude); +} diff --git a/platform/darwin/src/MGLPolygon.mm b/platform/darwin/src/MGLPolygon.mm index ceafe873bf..d966ff13ce 100644 --- a/platform/darwin/src/MGLPolygon.mm +++ b/platform/darwin/src/MGLPolygon.mm @@ -6,6 +6,7 @@ #import "MGLPolygon+MGLAdditions.h" #import +#import @implementation MGLPolygon @@ -54,6 +55,13 @@ return [super hash] + [[self geoJSONDictionary] hash]; } +- (CLLocationCoordinate2D)coordinate { + // pole of inaccessibility + auto poi = mapbox::polylabel([self polygon]); + + return MGLLocationCoordinate2DFromPoint(poi); +} + - (mbgl::LinearRing)ring { NSUInteger count = self.pointCount; CLLocationCoordinate2D *coordinates = self.coordinates; @@ -155,11 +163,17 @@ return hash; } +- (CLLocationCoordinate2D)coordinate { + MGLPolygon *firstPolygon = self.polygons.firstObject; + + return firstPolygon.coordinate; +} + - (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds { return MGLCoordinateBoundsIntersectsCoordinateBounds(_overlayBounds, overlayBounds); } -- (mbgl::Geometry)geometryObject { +- (mbgl::MultiPolygon)multiPolygon { mbgl::MultiPolygon multiPolygon; multiPolygon.reserve(self.polygons.count); for (MGLPolygon *polygon in self.polygons) { @@ -173,6 +187,10 @@ return multiPolygon; } +- (mbgl::Geometry)geometryObject { + return [self multiPolygon]; +} + - (NSDictionary *)geoJSONDictionary { NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:self.polygons.count]; for (MGLPolygonFeature *feature in self.polygons) { diff --git a/platform/darwin/src/MGLPolyline.mm b/platform/darwin/src/MGLPolyline.mm index ae4fbe61de..fd75dc2795 100644 --- a/platform/darwin/src/MGLPolyline.mm +++ b/platform/darwin/src/MGLPolyline.mm @@ -6,6 +6,7 @@ #import "MGLPolyline+MGLAdditions.h" #import +#import @implementation MGLPolyline @@ -52,6 +53,61 @@ return self == other || ([other isKindOfClass:[MGLPolyline class]] && [super isEqual:other]); } +- (CLLocationCoordinate2D)coordinate { + NSUInteger count = self.pointCount; + NSAssert(count > 0, @"Polyline must have coordinates"); + + CLLocationCoordinate2D *coordinates = self.coordinates; + CLLocationDistance middle = [self length] / 2.0; + CLLocationDistance traveled = 0.0; + + if (count > 1 || middle > traveled) { + for (NSUInteger i = 0; i < count; i++) { + + MGLRadianCoordinate2D from = MGLRadianCoordinateFromLocationCoordinate(coordinates[i]); + MGLRadianCoordinate2D to = MGLRadianCoordinateFromLocationCoordinate(coordinates[i + 1]); + + if (traveled >= middle) { + double overshoot = middle - traveled; + if (overshoot == 0) { + return coordinates[i]; + } + to = MGLRadianCoordinateFromLocationCoordinate(coordinates[i - 1]); + CLLocationDirection direction = [self direction:from to:to] - 180; + MGLRadianCoordinate2D otherCoordinate = MGLRadianCoordinateAtDistanceFacingDirection(from, + overshoot/mbgl::util::EARTH_RADIUS_M, + MGLRadiansFromDegrees(direction)); + return CLLocationCoordinate2DMake(MGLDegreesFromRadians(otherCoordinate.latitude), + MGLDegreesFromRadians(otherCoordinate.longitude)); + } + + traveled += (MGLDistanceBetweenRadianCoordinates(from, to) * mbgl::util::EARTH_RADIUS_M); + + } + } + + return coordinates[count - 1]; +} + +- (CLLocationDistance)length +{ + CLLocationDistance length = 0.0; + + NSUInteger count = self.pointCount; + CLLocationCoordinate2D *coordinates = self.coordinates; + + for (NSUInteger i = 0; i < count - 1; i++) { + length += (MGLDistanceBetweenRadianCoordinates(MGLRadianCoordinateFromLocationCoordinate(coordinates[i]), MGLRadianCoordinateFromLocationCoordinate(coordinates[i + 1])) * mbgl::util::EARTH_RADIUS_M); + } + + return length; +} + +- (CLLocationDirection)direction:(MGLRadianCoordinate2D)from to:(MGLRadianCoordinate2D)to +{ + return MGLDegreesFromRadians(MGLRadianCoordinatesDirection(from, to)); +} + @end @interface MGLMultiPolyline () @@ -114,6 +170,15 @@ return hash; } +- (CLLocationCoordinate2D)coordinate { + MGLPolyline *polyline = self.polylines.firstObject; + CLLocationCoordinate2D *coordinates = polyline.coordinates; + NSAssert([polyline pointCount] > 0, @"Polyline must have coordinates"); + CLLocationCoordinate2D firstCoordinate = coordinates[0]; + + return firstCoordinate; +} + - (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds { return MGLCoordinateBoundsIntersectsCoordinateBounds(_overlayBounds, overlayBounds); } diff --git a/platform/darwin/test/MGLCodingTests.m b/platform/darwin/test/MGLCodingTests.m index ff0d674ad1..ac61672b76 100644 --- a/platform/darwin/test/MGLCodingTests.m +++ b/platform/darwin/test/MGLCodingTests.m @@ -66,12 +66,54 @@ [unarchivedPolyline replaceCoordinatesInRange:NSMakeRange(0, 1) withCoordinates:otherCoordinates]; XCTAssertNotEqualObjects(polyline, unarchivedPolyline); + + CLLocationCoordinate2D multiLineCoordinates[] = { + CLLocationCoordinate2DMake(51.000000, 0.000000), + CLLocationCoordinate2DMake(51.000000, 1.000000), + CLLocationCoordinate2DMake(51.000000, 2.000000), + }; + + NSUInteger multiLineCoordinatesCount = sizeof(multiLineCoordinates) / sizeof(CLLocationCoordinate2D); + MGLPolyline *multiLine = [MGLPolyline polylineWithCoordinates:multiLineCoordinates count:multiLineCoordinatesCount]; + CLLocationCoordinate2D multiLineCenter = CLLocationCoordinate2DMake(51.000000, 1.000000); + + XCTAssertEqual([multiLine coordinate].latitude, multiLineCenter.latitude); + XCTAssertEqual([multiLine coordinate].longitude, multiLineCenter.longitude); + + CLLocationCoordinate2D segmentCoordinates[] = { + CLLocationCoordinate2DMake(35.040390, -85.311477), + CLLocationCoordinate2DMake(35.040390, -85.209510), + }; + + NSUInteger segmentCoordinatesCount = sizeof(segmentCoordinates) / sizeof(CLLocationCoordinate2D); + MGLPolyline *segmentLine = [MGLPolyline polylineWithCoordinates:segmentCoordinates count:segmentCoordinatesCount]; + CLLocationCoordinate2D segmentCenter = CLLocationCoordinate2DMake(35.0404006631, -85.2604935); + + XCTAssertEqualWithAccuracy([segmentLine coordinate].latitude, segmentCenter.latitude, 0.0001); + XCTAssertEqualWithAccuracy([segmentLine coordinate].longitude, segmentCenter.longitude, 0.0001); + + CLLocationCoordinate2D sfToBerkeleyCoordinates[] = { + CLLocationCoordinate2DMake(37.782440, -122.397111), + CLLocationCoordinate2DMake(37.818384, -122.352994), + CLLocationCoordinate2DMake(37.831401, -122.274545), + CLLocationCoordinate2DMake(37.862172, -122.262700), + }; + + NSUInteger sfToBerkeleyCoordinatesCount = sizeof(sfToBerkeleyCoordinates) / sizeof(CLLocationCoordinate2D); + MGLPolyline *sfToBerkeleyLine = [MGLPolyline polylineWithCoordinates:sfToBerkeleyCoordinates count:sfToBerkeleyCoordinatesCount]; + CLLocationCoordinate2D sfToBerkeleyCenter = CLLocationCoordinate2DMake(37.8230575118,-122.324867587); + + XCTAssertEqualWithAccuracy([sfToBerkeleyLine coordinate].latitude, sfToBerkeleyCenter.latitude, 0.0001); + XCTAssertEqualWithAccuracy([sfToBerkeleyLine coordinate].longitude, sfToBerkeleyCenter.longitude, 0.0001); + } - (void)testPolygon { CLLocationCoordinate2D coordinates[] = { - CLLocationCoordinate2DMake(0.664482398, 1.8865675), - CLLocationCoordinate2DMake(2.13224687, 3.9984632) + CLLocationCoordinate2DMake(35.090745, -85.300259), + CLLocationCoordinate2DMake(35.092035, -85.298885), + CLLocationCoordinate2DMake(35.090639, -85.297416), + CLLocationCoordinate2DMake(35.089112, -85.298928) }; NSUInteger numberOfCoordinates = sizeof(coordinates) / sizeof(CLLocationCoordinate2D); @@ -84,8 +126,24 @@ [NSKeyedArchiver archiveRootObject:polygon toFile:filePath]; MGLPolygon *unarchivedPolygon = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; + [unarchivedPolygon coordinate]; XCTAssertEqualObjects(polygon, unarchivedPolygon); + + CLLocationCoordinate2D squareCoordinates[] = { + CLLocationCoordinate2DMake(100.0, 0.0), + CLLocationCoordinate2DMake(101.0, 0.0), + CLLocationCoordinate2DMake(101.0, 1.0), + CLLocationCoordinate2DMake(100.0, 1.0), + }; + + NSUInteger squareCoordinatesCount = sizeof(squareCoordinates) / sizeof(CLLocationCoordinate2D); + MGLPolygon *squarePolygon = [MGLPolygon polygonWithCoordinates:squareCoordinates count:squareCoordinatesCount]; + CLLocationCoordinate2D squareCenter = CLLocationCoordinate2DMake(100.5, 0.5); + + XCTAssertEqual([squarePolygon coordinate].latitude, squareCenter.latitude); + XCTAssertEqual([squarePolygon coordinate].longitude, squareCenter.longitude); + } - (void)testPolygonWithInteriorPolygons { @@ -169,6 +227,11 @@ NSUInteger numberOfCoordinates = sizeof(coordinates) / sizeof(CLLocationCoordinate2D); MGLPointCollection *pointCollection = [MGLPointCollection pointCollectionWithCoordinates:coordinates count:numberOfCoordinates]; + CLLocationCoordinate2D pointsCenter = CLLocationCoordinate2DMake(0, 1); + + XCTAssertEqual([pointCollection coordinate].latitude, pointsCenter.latitude); + XCTAssertEqual([pointCollection coordinate].longitude, pointsCenter.longitude); + NSString *filePath = [self temporaryFilePathForClass:[MGLPointCollection class]]; [NSKeyedArchiver archiveRootObject:pointCollection toFile:filePath]; @@ -218,6 +281,30 @@ CLLocationCoordinate2DMake(20, 21), CLLocationCoordinate2DMake(30, 31), }; + + CLLocationCoordinate2D line1[] = { + CLLocationCoordinate2DMake(100, 40), + CLLocationCoordinate2DMake(105, 45), + CLLocationCoordinate2DMake(110, 55) + }; + + CLLocationCoordinate2D line2[] = { + CLLocationCoordinate2DMake(105, 40), + CLLocationCoordinate2DMake(110, 45), + CLLocationCoordinate2DMake(115, 55) + }; + + NSUInteger road1CoordinatesCount = sizeof(line1) / sizeof(CLLocationCoordinate2D); + NSUInteger road2CoordinatesCount = sizeof(line2) / sizeof(CLLocationCoordinate2D); + + MGLPolyline *road1Polyline = [MGLPolyline polylineWithCoordinates:line1 count:road1CoordinatesCount]; + MGLPolyline *road2Polyline = [MGLPolyline polylineWithCoordinates:line1 count:road2CoordinatesCount]; + + MGLMultiPolyline *roads = [MGLMultiPolyline multiPolylineWithPolylines:@[road1Polyline, road2Polyline]]; + CLLocationCoordinate2D roadCenter = CLLocationCoordinate2DMake(100, 40); + + XCTAssertEqual([roads coordinate].latitude, roadCenter.latitude); + XCTAssertEqual([roads coordinate].longitude, roadCenter.longitude); NSUInteger numberOfCoordinates = sizeof(coordinates) / sizeof(CLLocationCoordinate2D); @@ -248,6 +335,31 @@ CLLocationCoordinate2DMake(20, 21), CLLocationCoordinate2DMake(30, 31), }; + + CLLocationCoordinate2D outerSquare[] = { + CLLocationCoordinate2DMake(100.0, 0.0), + CLLocationCoordinate2DMake(101.0, 0.0), + CLLocationCoordinate2DMake(101.0, 1.0), + CLLocationCoordinate2DMake(100.0, 1.0), + }; + + CLLocationCoordinate2D innerSquare[] = { + CLLocationCoordinate2DMake(100.35, 0.35), + CLLocationCoordinate2DMake(100.65, 0.35), + CLLocationCoordinate2DMake(100.65, 0.65), + CLLocationCoordinate2DMake(100.35, 0.65), + }; + + NSUInteger outerCoordinatesCount = sizeof(outerSquare) / sizeof(CLLocationCoordinate2D); + NSUInteger innerCoordinatesCount = sizeof(innerSquare) / sizeof(CLLocationCoordinate2D); + + MGLPolygon *innerPolygonSquare = [MGLPolygon polygonWithCoordinates:innerSquare count:innerCoordinatesCount]; + MGLPolygon *outerPolygonSquare = [MGLPolygon polygonWithCoordinates:outerSquare count:outerCoordinatesCount interiorPolygons:@[innerPolygonSquare]]; + MGLMultiPolygon *squares = [MGLMultiPolygon multiPolygonWithPolygons:@[outerPolygonSquare, innerPolygonSquare]]; + CLLocationCoordinate2D squareCenter = CLLocationCoordinate2DMake(100.5, 0.5); + + XCTAssertEqual([squares coordinate].latitude, squareCenter.latitude); + XCTAssertEqual([squares coordinate].longitude, squareCenter.longitude); NSUInteger numberOfCoordinates = sizeof(coordinates) / sizeof(CLLocationCoordinate2D); @@ -265,9 +377,10 @@ MGLMultiPolygon *unarchivedMultiPolygon = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; MGLMultiPolygon *anotherMultiPolygon = [MGLMultiPolygon multiPolygonWithPolygons:[polygons subarrayWithRange:NSMakeRange(0, polygons.count/2)]]; - + XCTAssertEqualObjects(multiPolygon, unarchivedMultiPolygon); XCTAssertNotEqualObjects(anotherMultiPolygon, unarchivedMultiPolygon); + } - (void)testShapeCollection { diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index ca9d22f230..15e3c7a081 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -32,6 +32,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT ### Other changes * Xcode 8.0 or higher is now recommended for using this SDK. ([#8775](https://github.com/mapbox/mapbox-gl-native/pull/8775)) +* Fixed a crash when calling `MGLMultiPolygon.coordinate` [#8713](https://github.com/mapbox/mapbox-gl-native/pull/8713) * Updated MGLMapView’s logo view to display [the new Mapbox logo](https://www.mapbox.com/blog/new-mapbox-logo/). ([#8771](https://github.com/mapbox/mapbox-gl-native/pull/8771), [#8773](https://github.com/mapbox/mapbox-gl-native/pull/8773)) * Fixed a crash or console spew when MGLMapView is initialized with a frame smaller than 64 points wide by 64 points tall. ([#8562](https://github.com/mapbox/mapbox-gl-native/pull/8562)) * The error passed into `-[MGLMapViewDelegate mapViewDidFailLoadingMap:withError:]` now includes a more specific description and failure reason. ([#8418](https://github.com/mapbox/mapbox-gl-native/pull/8418)) diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index 27582c1acf..ef57eac140 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -2703,7 +2703,10 @@ baseConfigurationReference = 55D8C9941D0F133500F42F10 /* config.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; - HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; + HEADER_SEARCH_PATHS = ( + "$(mbgl_core_INCLUDE_DIRECTORIES)", + "$(polylabel_INCLUDE_DIRECTORIES)", + ); INFOPLIST_FILE = test/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -2727,7 +2730,10 @@ baseConfigurationReference = 55D8C9941D0F133500F42F10 /* config.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; - HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; + HEADER_SEARCH_PATHS = ( + "$(mbgl_core_INCLUDE_DIRECTORIES)", + "$(polylabel_INCLUDE_DIRECTORIES)", + ); INFOPLIST_FILE = test/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -2755,7 +2761,10 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; + HEADER_SEARCH_PATHS = ( + "$(mbgl_core_INCLUDE_DIRECTORIES)", + "$(polylabel_INCLUDE_DIRECTORIES)", + ); INFOPLIST_FILE = framework/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; @@ -2789,7 +2798,10 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; + HEADER_SEARCH_PATHS = ( + "$(mbgl_core_INCLUDE_DIRECTORIES)", + "$(polylabel_INCLUDE_DIRECTORIES)", + ); INFOPLIST_FILE = framework/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; @@ -2840,7 +2852,10 @@ baseConfigurationReference = 55D8C9941D0F133500F42F10 /* config.xcconfig */; buildSettings = { BITCODE_GENERATION_MODE = bitcode; - HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; + HEADER_SEARCH_PATHS = ( + "$(mbgl_core_INCLUDE_DIRECTORIES)", + "$(polylabel_INCLUDE_DIRECTORIES)", + ); OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "$(sqlite_cflags)", @@ -2866,7 +2881,10 @@ baseConfigurationReference = 55D8C9941D0F133500F42F10 /* config.xcconfig */; buildSettings = { BITCODE_GENERATION_MODE = bitcode; - HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; + HEADER_SEARCH_PATHS = ( + "$(mbgl_core_INCLUDE_DIRECTORIES)", + "$(polylabel_INCLUDE_DIRECTORIES)", + ); OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "$(sqlite_cflags)", diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index ba09002d14..a1515e9d7a 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -17,6 +17,7 @@ ### Other changes * Xcode 8.0 or higher is now recommended for using this SDK. ([#8775](https://github.com/mapbox/mapbox-gl-native/pull/8775)) +* Fixed a crash when calling `MGLMultiPolygon.coordinate` [#8713](https://github.com/mapbox/mapbox-gl-native/pull/8713) * Updated MGLMapView’s logo view to display [the new Mapbox logo](https://www.mapbox.com/blog/new-mapbox-logo/). ([#8771](https://github.com/mapbox/mapbox-gl-native/pull/8771), [#8773](https://github.com/mapbox/mapbox-gl-native/pull/8773)) * Fixed an issue causing attribution button text to appear blue instead of black. ([#8701](https://github.com/mapbox/mapbox-gl-native/pull/8701)) * Fixed a crash or console spew when MGLMapView is initialized with a frame smaller than 64 points wide by 64 points tall. ([#8562](https://github.com/mapbox/mapbox-gl-native/pull/8562)) diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj index 1127524098..564d81afb2 100644 --- a/platform/macos/macos.xcodeproj/project.pbxproj +++ b/platform/macos/macos.xcodeproj/project.pbxproj @@ -1779,7 +1779,10 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_VERSION = A; - HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; + HEADER_SEARCH_PATHS = ( + "$(mbgl_core_INCLUDE_DIRECTORIES)", + "$(polylabel_INCLUDE_DIRECTORIES)", + ); INFOPLIST_FILE = "$(SRCROOT)/sdk/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; @@ -1813,7 +1816,10 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_VERSION = A; - HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; + HEADER_SEARCH_PATHS = ( + "$(mbgl_core_INCLUDE_DIRECTORIES)", + "$(polylabel_INCLUDE_DIRECTORIES)", + ); INFOPLIST_FILE = "$(SRCROOT)/sdk/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; @@ -1837,7 +1843,10 @@ buildSettings = { CLANG_ENABLE_MODULES = YES; COMBINE_HIDPI_IMAGES = YES; - HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; + HEADER_SEARCH_PATHS = ( + "$(mbgl_core_INCLUDE_DIRECTORIES)", + "$(polylabel_INCLUDE_DIRECTORIES)", + ); INFOPLIST_FILE = test/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; LIBRARY_SEARCH_PATHS = ( @@ -1866,7 +1875,10 @@ buildSettings = { CLANG_ENABLE_MODULES = YES; COMBINE_HIDPI_IMAGES = YES; - HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; + HEADER_SEARCH_PATHS = ( + "$(mbgl_core_INCLUDE_DIRECTORIES)", + "$(polylabel_INCLUDE_DIRECTORIES)", + ); INFOPLIST_FILE = test/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; OTHER_CFLAGS = "-fvisibility=hidden"; diff --git a/scripts/config.xcconfig.in b/scripts/config.xcconfig.in index eb6bc71b89..b70ff9d677 100644 --- a/scripts/config.xcconfig.in +++ b/scripts/config.xcconfig.in @@ -3,3 +3,4 @@ // mbgl-core mbgl_core_INCLUDE_DIRECTORIES = "@mbgl_core_INCLUDE_DIRECTORIES@" mbgl_core_LINK_LIBRARIES = "@mbgl_core_LINK_LIBRARIES@" +polylabel_INCLUDE_DIRECTORIES = "@MASON_PACKAGE_polylabel_INCLUDE_DIRS@" -- cgit v1.2.1 From c9de6cdb6c8b4a640c10940adbd76ed508900022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Sat, 20 May 2017 19:44:52 -0700 Subject: [ios, macos] More robust Streets localization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added Arabic, Portuguese, and Simplified Chinese to the list of languages with specialized fields in the Mapbox Streets source. Rely on NSBundle to select the most appropriate locale based on the user’s preferred languages. --- platform/ios/app/MBXViewController.m | 21 +++++++++++---------- platform/macos/app/MGLVectorSource+MBXAdditions.h | 2 +- platform/macos/app/MGLVectorSource+MBXAdditions.m | 18 +++++++++++------- platform/macos/app/MapDocument.m | 5 ++--- 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m index 209998adb9..d3927374a7 100644 --- a/platform/ios/app/MBXViewController.m +++ b/platform/ios/app/MBXViewController.m @@ -1397,19 +1397,20 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) { - (NSString *)bestLanguageForUser { - NSArray *supportedLanguages = @[ @"en", @"es", @"fr", @"de", @"ru", @"zh" ]; - NSArray *preferredLanguages = [NSLocale preferredLanguages]; - NSString *bestLanguage; - - for (NSString *language in preferredLanguages) { - NSString *thisLanguage = [[NSLocale localeWithLocaleIdentifier:language] objectForKey:NSLocaleLanguageCode]; - if ([supportedLanguages containsObject:thisLanguage]) { - bestLanguage = thisLanguage; - break; + // https://www.mapbox.com/vector-tiles/mapbox-streets-v7/#overview + NSArray *supportedLanguages = @[ @"ar", @"en", @"es", @"fr", @"de", @"pt", @"ru", @"zh", @"zh-Hans" ]; + NSArray *preferredLanguages = [NSBundle preferredLocalizationsFromArray:supportedLanguages forPreferences:[NSLocale preferredLanguages]]; + NSString *mostSpecificLanguage; + + for (NSString *language in preferredLanguages) + { + if (language.length > mostSpecificLanguage.length) + { + mostSpecificLanguage = language; } } - return bestLanguage ?: @"en"; + return mostSpecificLanguage ?: @"en"; } - (IBAction)startWorldTour diff --git a/platform/macos/app/MGLVectorSource+MBXAdditions.h b/platform/macos/app/MGLVectorSource+MBXAdditions.h index 312081ec51..1e25ee5a60 100644 --- a/platform/macos/app/MGLVectorSource+MBXAdditions.h +++ b/platform/macos/app/MGLVectorSource+MBXAdditions.h @@ -4,7 +4,7 @@ NS_ASSUME_NONNULL_BEGIN @interface MGLVectorSource (MBXAdditions) -+ (nullable NSString *)preferredMapboxStreetsLanguage; ++ (NSString *)preferredMapboxStreetsLanguage; - (NS_DICTIONARY_OF(NSString *, NSString *) *)localizedKeysByKeyForPreferredLanguage:(nullable NSString *)preferredLanguage; diff --git a/platform/macos/app/MGLVectorSource+MBXAdditions.m b/platform/macos/app/MGLVectorSource+MBXAdditions.m index 644b43a651..323bc74366 100644 --- a/platform/macos/app/MGLVectorSource+MBXAdditions.m +++ b/platform/macos/app/MGLVectorSource+MBXAdditions.m @@ -7,19 +7,23 @@ static dispatch_once_t onceToken; static NS_SET_OF(NSString *) *mapboxStreetsLanguages; dispatch_once(&onceToken, ^{ - mapboxStreetsLanguages = [NSSet setWithObjects:@"en", @"es", @"fr", @"de", @"ru", @"zh", nil]; + // https://www.mapbox.com/vector-tiles/mapbox-streets-v7/#overview + mapboxStreetsLanguages = [NSSet setWithObjects:@"ar", @"de", @"en", @"es", @"fr", @"pt", @"ru", @"zh", @"zh-Hans", nil]; }); return mapboxStreetsLanguages; } -+ (nullable NSString *)preferredMapboxStreetsLanguage { - for (NSString *language in [NSLocale preferredLanguages]) { - NSString *languageCode = [[NSLocale localeWithLocaleIdentifier:language] objectForKey:NSLocaleLanguageCode]; - if ([[MGLVectorSource mapboxStreetsLanguages] containsObject:languageCode]) { - return languageCode; ++ (NSString *)preferredMapboxStreetsLanguage { + NSArray *supportedLanguages = [MGLVectorSource mapboxStreetsLanguages].allObjects; + NSArray *preferredLanguages = [NSBundle preferredLocalizationsFromArray:supportedLanguages + forPreferences:[NSLocale preferredLanguages]]; + NSString *mostSpecificLanguage; + for (NSString *language in preferredLanguages) { + if (language.length > mostSpecificLanguage.length) { + mostSpecificLanguage = language; } } - return nil; + return mostSpecificLanguage ?: @"en"; } - (BOOL)isMapboxStreets { diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m index 59c1817f63..a30e762645 100644 --- a/platform/macos/app/MapDocument.m +++ b/platform/macos/app/MapDocument.m @@ -345,7 +345,7 @@ NS_ARRAY_OF(id ) *MBXFlattenedShapes(NS_ARRAY_OF(id ) *MBXFlattenedShapes(NS_ARRAY_OF(id Date: Tue, 23 May 2017 13:24:16 -0400 Subject: [ios] Fallback to Mapbox.bundle as the framework bundle (#9074) Fixes an issue where localizations could not be found when using static builds. Throws exception if our bundle can't be found. --- platform/darwin/src/NSBundle+MGLAdditions.h | 4 ---- platform/darwin/src/NSBundle+MGLAdditions.m | 28 ++++++++++++---------------- platform/ios/CHANGELOG.md | 1 + platform/ios/src/MGLAPIClient.m | 2 +- platform/ios/src/MGLMapView.mm | 3 +-- 5 files changed, 15 insertions(+), 23 deletions(-) diff --git a/platform/darwin/src/NSBundle+MGLAdditions.h b/platform/darwin/src/NSBundle+MGLAdditions.h index 1fc9e8b896..df70d23923 100644 --- a/platform/darwin/src/NSBundle+MGLAdditions.h +++ b/platform/darwin/src/NSBundle+MGLAdditions.h @@ -36,10 +36,6 @@ NS_ASSUME_NONNULL_BEGIN + (nullable NS_DICTIONARY_OF(NSString *, id) *)mgl_frameworkInfoDictionary; -/// The relative path to the directory containing the SDK’s resource files, or -/// `nil` if the files are located directly within the bundle’s root directory. -@property (readonly, copy, nullable) NSString *mgl_resourcesDirectory; - @end NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/NSBundle+MGLAdditions.m b/platform/darwin/src/NSBundle+MGLAdditions.m index 76d9cc0db7..ad122831ba 100644 --- a/platform/darwin/src/NSBundle+MGLAdditions.m +++ b/platform/darwin/src/NSBundle+MGLAdditions.m @@ -6,12 +6,19 @@ + (instancetype)mgl_frameworkBundle { NSBundle *bundle = [self bundleForClass:[MGLAccountManager class]]; - if (![bundle.infoDictionary[@"CFBundlePackageType"] isEqualToString:@"FMWK"] && !bundle.mgl_resourcesDirectory) { + + if (![bundle.infoDictionary[@"CFBundlePackageType"] isEqualToString:@"FMWK"]) { // For static frameworks, the bundle is the containing application - // bundle but the resources are still in the framework bundle. - bundle = [NSBundle bundleWithPath:[bundle.privateFrameworksPath - stringByAppendingPathComponent:@"Mapbox.framework"]]; + // bundle but the resources are in Mapbox.bundle. + NSString *bundlePath = [bundle pathForResource:@"Mapbox" ofType:@"bundle"]; + if (bundlePath) { + bundle = [self bundleWithPath:bundlePath]; + } else { + [NSException raise:@"MGLBundleNotFoundException" format: + @"The Mapbox framework bundle could not be found. If using the Mapbox iOS SDK as a static framework, make sure that Mapbox.bundle is copied into the root of the app bundle."]; + } } + return bundle; } @@ -21,18 +28,7 @@ + (nullable NS_DICTIONARY_OF(NSString *, id) *)mgl_frameworkInfoDictionary { NSBundle *bundle = self.mgl_frameworkBundle; - if (bundle.mgl_resourcesDirectory) { - NSString *infoPlistPath = [bundle pathForResource:@"Info" - ofType:@"plist" - inDirectory:bundle.mgl_resourcesDirectory]; - return [NSDictionary dictionaryWithContentsOfFile:infoPlistPath]; - } else { - return bundle.infoDictionary; - } -} - -- (NSString *)mgl_resourcesDirectory { - return [self pathForResource:@"Mapbox" ofType:@"bundle"] ? @"Mapbox.bundle" : nil; + return bundle.infoDictionary; } @end diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 15e3c7a081..b5a0e7dd7d 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -38,6 +38,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * The error passed into `-[MGLMapViewDelegate mapViewDidFailLoadingMap:withError:]` now includes a more specific description and failure reason. ([#8418](https://github.com/mapbox/mapbox-gl-native/pull/8418)) * Fixed an issue rendering polylines that contain duplicate vertices. ([#8808](https://github.com/mapbox/mapbox-gl-native/pull/8808)) * Fixed a bug which caused the compass and other ornaments to underlap navigation and tab bars. ([#7716](https://github.com/mapbox/mapbox-gl-native/pull/7716)) +* Fixed an issue in the static framework where localizations would never load. ([#9074](https://github.com/mapbox/mapbox-gl-native/pull/9074)) ## 3.5.4 - May 9, 2017 diff --git a/platform/ios/src/MGLAPIClient.m b/platform/ios/src/MGLAPIClient.m index 22ee5c55f5..124d436197 100644 --- a/platform/ios/src/MGLAPIClient.m +++ b/platform/ios/src/MGLAPIClient.m @@ -117,7 +117,7 @@ static NSString * const MGLAPIClientHTTPMethodPost = @"POST"; - (void)loadCertificate:(NSData **)certificate withResource:(NSString *)resource { NSBundle *frameworkBundle = [NSBundle mgl_frameworkBundle]; - NSString *cerPath = [frameworkBundle pathForResource:resource ofType:@"der" inDirectory:frameworkBundle.mgl_resourcesDirectory]; + NSString *cerPath = [frameworkBundle pathForResource:resource ofType:@"der"]; if (cerPath != nil) { *certificate = [NSData dataWithContentsOfFile:cerPath]; } diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 720c1d506a..9a27cf24c6 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -5293,8 +5293,7 @@ public: NSString *extension = imageName.pathExtension.length ? imageName.pathExtension : @"png"; NSBundle *bundle = [NSBundle mgl_frameworkBundle]; NSString *path = [bundle pathForResource:imageName.stringByDeletingPathExtension - ofType:extension - inDirectory:bundle.mgl_resourcesDirectory]; + ofType:extension]; if ( ! path) { [NSException raise:@"Resource not found" format: -- cgit v1.2.1 From d90c1722c9718e2532d406c13b17edf988070e2e Mon Sep 17 00:00:00 2001 From: Jason Wray Date: Fri, 19 May 2017 13:08:21 -0400 Subject: [ios] Move image resources to an asset catalog & switch to PDFs --- platform/ios/ios.xcodeproj/project.pbxproj | 60 +++------------------ platform/ios/originals/compass.sketch | Bin 0 -> 4881 bytes platform/ios/resources/Compass.png | Bin 1139 -> 0 bytes platform/ios/resources/Compass@2x.png | Bin 1892 -> 0 bytes platform/ios/resources/Compass@3x.png | Bin 3398 -> 0 bytes .../Images.xcassets/Compass.imageset/Contents.json | 12 +++++ .../Images.xcassets/Compass.imageset/compass.pdf | Bin 0 -> 4574 bytes .../ios/resources/Images.xcassets/Contents.json | 6 +++ .../default_marker.imageset/Contents.json | 12 +++++ .../default_marker.imageset/default_marker.pdf | Bin 0 -> 2601 bytes .../Images.xcassets/mapbox.imageset/Contents.json | 12 +++++ .../Images.xcassets/mapbox.imageset/mapbox.pdf | Bin 0 -> 8823 bytes platform/ios/resources/default_marker.png | Bin 1010 -> 0 bytes platform/ios/resources/default_marker@2x.png | Bin 1995 -> 0 bytes platform/ios/resources/default_marker@3x.png | Bin 2998 -> 0 bytes platform/ios/resources/mapbox.png | Bin 2347 -> 0 bytes platform/ios/resources/mapbox@2x.png | Bin 5290 -> 0 bytes platform/ios/resources/mapbox@3x.png | Bin 8245 -> 0 bytes platform/ios/src/MGLMapView.mm | 26 ++++----- 19 files changed, 61 insertions(+), 67 deletions(-) create mode 100644 platform/ios/originals/compass.sketch delete mode 100644 platform/ios/resources/Compass.png delete mode 100644 platform/ios/resources/Compass@2x.png delete mode 100644 platform/ios/resources/Compass@3x.png create mode 100644 platform/ios/resources/Images.xcassets/Compass.imageset/Contents.json create mode 100644 platform/ios/resources/Images.xcassets/Compass.imageset/compass.pdf create mode 100644 platform/ios/resources/Images.xcassets/Contents.json create mode 100644 platform/ios/resources/Images.xcassets/default_marker.imageset/Contents.json create mode 100644 platform/ios/resources/Images.xcassets/default_marker.imageset/default_marker.pdf create mode 100644 platform/ios/resources/Images.xcassets/mapbox.imageset/Contents.json create mode 100644 platform/ios/resources/Images.xcassets/mapbox.imageset/mapbox.pdf delete mode 100644 platform/ios/resources/default_marker.png delete mode 100644 platform/ios/resources/default_marker@2x.png delete mode 100644 platform/ios/resources/default_marker@3x.png delete mode 100644 platform/ios/resources/mapbox.png delete mode 100644 platform/ios/resources/mapbox@2x.png delete mode 100644 platform/ios/resources/mapbox@3x.png diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index ef57eac140..6ff148a18e 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -200,6 +200,8 @@ 7E016D861D9E890300A29A21 /* MGLPolygon+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E016D831D9E890300A29A21 /* MGLPolygon+MGLAdditions.m */; }; 7E016D871D9E890300A29A21 /* MGLPolygon+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E016D831D9E890300A29A21 /* MGLPolygon+MGLAdditions.m */; }; 920A3E5D1E6F995200C16EFC /* MGLSourceQueryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 920A3E5C1E6F995200C16EFC /* MGLSourceQueryTests.m */; }; + 960D0C361ECF5AAF008E151F /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 960D0C351ECF5AAF008E151F /* Images.xcassets */; }; + 960D0C371ECF5AAF008E151F /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 960D0C351ECF5AAF008E151F /* Images.xcassets */; }; 9620BB381E69FE1700705A1D /* MGLSDKUpdateChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 9620BB361E69FE1700705A1D /* MGLSDKUpdateChecker.h */; }; 9620BB391E69FE1700705A1D /* MGLSDKUpdateChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 9620BB361E69FE1700705A1D /* MGLSDKUpdateChecker.h */; }; 9620BB3A1E69FE1700705A1D /* MGLSDKUpdateChecker.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9620BB371E69FE1700705A1D /* MGLSDKUpdateChecker.mm */; }; @@ -333,15 +335,6 @@ DA88485C1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.h in Headers */ = {isa = PBXBuildFile; fileRef = DA88484D1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.h */; }; DA88485D1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88484E1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.m */; }; DA8848601CBAFC2E00AB86E3 /* Mapbox.h in Headers */ = {isa = PBXBuildFile; fileRef = DA88485E1CBAFC2E00AB86E3 /* Mapbox.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DA88486D1CBAFCC100AB86E3 /* Compass.png in Resources */ = {isa = PBXBuildFile; fileRef = DA8848631CBAFCC100AB86E3 /* Compass.png */; }; - DA88486E1CBAFCC100AB86E3 /* Compass@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA8848641CBAFCC100AB86E3 /* Compass@2x.png */; }; - DA88486F1CBAFCC100AB86E3 /* Compass@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA8848651CBAFCC100AB86E3 /* Compass@3x.png */; }; - DA8848701CBAFCC100AB86E3 /* default_marker.png in Resources */ = {isa = PBXBuildFile; fileRef = DA8848661CBAFCC100AB86E3 /* default_marker.png */; }; - DA8848711CBAFCC100AB86E3 /* default_marker@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA8848671CBAFCC100AB86E3 /* default_marker@2x.png */; }; - DA8848721CBAFCC100AB86E3 /* default_marker@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA8848681CBAFCC100AB86E3 /* default_marker@3x.png */; }; - DA8848731CBAFCC100AB86E3 /* mapbox.png in Resources */ = {isa = PBXBuildFile; fileRef = DA8848691CBAFCC100AB86E3 /* mapbox.png */; }; - DA8848741CBAFCC100AB86E3 /* mapbox@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA88486A1CBAFCC100AB86E3 /* mapbox@2x.png */; }; - DA8848751CBAFCC100AB86E3 /* mapbox@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA88486B1CBAFCC100AB86E3 /* mapbox@3x.png */; }; DA8848841CBB033F00AB86E3 /* FABAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848801CBB033F00AB86E3 /* FABAttributes.h */; }; DA8848851CBB033F00AB86E3 /* FABKitProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848811CBB033F00AB86E3 /* FABKitProtocol.h */; }; DA8848861CBB033F00AB86E3 /* Fabric+FABKits.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848821CBB033F00AB86E3 /* Fabric+FABKits.h */; }; @@ -355,15 +348,6 @@ DA8933DB1CCD31D400E68420 /* Foundation.strings in Resources */ = {isa = PBXBuildFile; fileRef = DA8933BA1CCD2CA100E68420 /* Foundation.strings */; }; DA8933DC1CCD31D400E68420 /* Foundation.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DA8933BD1CCD2CAD00E68420 /* Foundation.stringsdict */; }; DA8933E01CCD31DF00E68420 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DA89339F1CCC951200E68420 /* Localizable.strings */; }; - DA8933E11CCD31DF00E68420 /* Compass.png in Resources */ = {isa = PBXBuildFile; fileRef = DA8848631CBAFCC100AB86E3 /* Compass.png */; }; - DA8933E21CCD31DF00E68420 /* Compass@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA8848641CBAFCC100AB86E3 /* Compass@2x.png */; }; - DA8933E31CCD31DF00E68420 /* Compass@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA8848651CBAFCC100AB86E3 /* Compass@3x.png */; }; - DA8933E41CCD31DF00E68420 /* default_marker.png in Resources */ = {isa = PBXBuildFile; fileRef = DA8848661CBAFCC100AB86E3 /* default_marker.png */; }; - DA8933E51CCD31DF00E68420 /* default_marker@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA8848671CBAFCC100AB86E3 /* default_marker@2x.png */; }; - DA8933E61CCD31DF00E68420 /* default_marker@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA8848681CBAFCC100AB86E3 /* default_marker@3x.png */; }; - DA8933E71CCD31DF00E68420 /* mapbox.png in Resources */ = {isa = PBXBuildFile; fileRef = DA8848691CBAFCC100AB86E3 /* mapbox.png */; }; - DA8933E81CCD31DF00E68420 /* mapbox@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA88486A1CBAFCC100AB86E3 /* mapbox@2x.png */; }; - DA8933E91CCD31DF00E68420 /* mapbox@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA88486B1CBAFCC100AB86E3 /* mapbox@3x.png */; }; DA8933F01CCD387900E68420 /* strip-frameworks.sh in Resources */ = {isa = PBXBuildFile; fileRef = DA8933EF1CCD387900E68420 /* strip-frameworks.sh */; }; DA8963371CC549A100684375 /* glyphs in Resources */ = {isa = PBXBuildFile; fileRef = DA8963331CC549A100684375 /* glyphs */; }; DA8963381CC549A100684375 /* sprites in Resources */ = {isa = PBXBuildFile; fileRef = DA8963341CC549A100684375 /* sprites */; }; @@ -679,6 +663,7 @@ 7E016D821D9E890300A29A21 /* MGLPolygon+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLPolygon+MGLAdditions.h"; sourceTree = ""; }; 7E016D831D9E890300A29A21 /* MGLPolygon+MGLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MGLPolygon+MGLAdditions.m"; sourceTree = ""; }; 920A3E5C1E6F995200C16EFC /* MGLSourceQueryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLSourceQueryTests.m; path = ../../darwin/test/MGLSourceQueryTests.m; sourceTree = ""; }; + 960D0C351ECF5AAF008E151F /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 9620BB361E69FE1700705A1D /* MGLSDKUpdateChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLSDKUpdateChecker.h; sourceTree = ""; }; 9620BB371E69FE1700705A1D /* MGLSDKUpdateChecker.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = MGLSDKUpdateChecker.mm; sourceTree = ""; }; 9660916B1E5BBFD700A9A03B /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; @@ -847,15 +832,6 @@ DA88484D1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLFaux3DUserLocationAnnotationView.h; sourceTree = ""; }; DA88484E1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLFaux3DUserLocationAnnotationView.m; sourceTree = ""; }; DA88485E1CBAFC2E00AB86E3 /* Mapbox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Mapbox.h; path = src/Mapbox.h; sourceTree = SOURCE_ROOT; }; - DA8848631CBAFCC100AB86E3 /* Compass.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Compass.png; sourceTree = ""; }; - DA8848641CBAFCC100AB86E3 /* Compass@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Compass@2x.png"; sourceTree = ""; }; - DA8848651CBAFCC100AB86E3 /* Compass@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Compass@3x.png"; sourceTree = ""; }; - DA8848661CBAFCC100AB86E3 /* default_marker.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = default_marker.png; sourceTree = ""; }; - DA8848671CBAFCC100AB86E3 /* default_marker@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "default_marker@2x.png"; sourceTree = ""; }; - DA8848681CBAFCC100AB86E3 /* default_marker@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "default_marker@3x.png"; sourceTree = ""; }; - DA8848691CBAFCC100AB86E3 /* mapbox.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = mapbox.png; sourceTree = ""; }; - DA88486A1CBAFCC100AB86E3 /* mapbox@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mapbox@2x.png"; sourceTree = ""; }; - DA88486B1CBAFCC100AB86E3 /* mapbox@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mapbox@3x.png"; sourceTree = ""; }; DA8848801CBB033F00AB86E3 /* FABAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FABAttributes.h; sourceTree = ""; }; DA8848811CBB033F00AB86E3 /* FABKitProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FABKitProtocol.h; sourceTree = ""; }; DA8848821CBB033F00AB86E3 /* Fabric+FABKits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Fabric+FABKits.h"; sourceTree = ""; }; @@ -1363,17 +1339,9 @@ DA8848621CBAFCC100AB86E3 /* Kit Resources */ = { isa = PBXGroup; children = ( + 960D0C351ECF5AAF008E151F /* Images.xcassets */, DA89339F1CCC951200E68420 /* Localizable.strings */, DAC49C5F1CD02BC9009E1AA3 /* Localizable.stringsdict */, - DA8848631CBAFCC100AB86E3 /* Compass.png */, - DA8848641CBAFCC100AB86E3 /* Compass@2x.png */, - DA8848651CBAFCC100AB86E3 /* Compass@3x.png */, - DA8848661CBAFCC100AB86E3 /* default_marker.png */, - DA8848671CBAFCC100AB86E3 /* default_marker@2x.png */, - DA8848681CBAFCC100AB86E3 /* default_marker@3x.png */, - DA8848691CBAFCC100AB86E3 /* mapbox.png */, - DA88486A1CBAFCC100AB86E3 /* mapbox@2x.png */, - DA88486B1CBAFCC100AB86E3 /* mapbox@3x.png */, DA8933EF1CCD387900E68420 /* strip-frameworks.sh */, 40599F001DEE1B2400182B5D /* api_mapbox_staging.der */, 40599F011DEE1B2400182B5D /* api_mapbox_com-digicert.der */, @@ -2092,18 +2060,10 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - DA8848731CBAFCC100AB86E3 /* mapbox.png in Resources */, DA8933BC1CCD2CA100E68420 /* Foundation.strings in Resources */, - DA8848741CBAFCC100AB86E3 /* mapbox@2x.png in Resources */, DA8933A31CCC95B000E68420 /* Localizable.strings in Resources */, - DA88486D1CBAFCC100AB86E3 /* Compass.png in Resources */, - DA8848721CBAFCC100AB86E3 /* default_marker@3x.png in Resources */, - DA88486F1CBAFCC100AB86E3 /* Compass@3x.png in Resources */, - DA88486E1CBAFCC100AB86E3 /* Compass@2x.png in Resources */, - DA8848701CBAFCC100AB86E3 /* default_marker.png in Resources */, - DA8848711CBAFCC100AB86E3 /* default_marker@2x.png in Resources */, + 960D0C361ECF5AAF008E151F /* Images.xcassets in Resources */, DA8933F01CCD387900E68420 /* strip-frameworks.sh in Resources */, - DA8848751CBAFCC100AB86E3 /* mapbox@3x.png in Resources */, DAC49C5C1CD02BC9009E1AA3 /* Localizable.stringsdict in Resources */, DA8933BF1CCD2CAD00E68420 /* Foundation.stringsdict in Resources */, 408982E91DEE208200754016 /* api_mapbox_staging.der in Resources */, @@ -2117,16 +2077,8 @@ buildActionMask = 2147483647; files = ( DA8933E01CCD31DF00E68420 /* Localizable.strings in Resources */, - DA8933E11CCD31DF00E68420 /* Compass.png in Resources */, - DA8933E21CCD31DF00E68420 /* Compass@2x.png in Resources */, - DA8933E31CCD31DF00E68420 /* Compass@3x.png in Resources */, - DA8933E41CCD31DF00E68420 /* default_marker.png in Resources */, - DA8933E51CCD31DF00E68420 /* default_marker@2x.png in Resources */, - DA8933E61CCD31DF00E68420 /* default_marker@3x.png in Resources */, - DA8933E71CCD31DF00E68420 /* mapbox.png in Resources */, - DA8933E81CCD31DF00E68420 /* mapbox@2x.png in Resources */, - DA8933E91CCD31DF00E68420 /* mapbox@3x.png in Resources */, DA8933DB1CCD31D400E68420 /* Foundation.strings in Resources */, + 960D0C371ECF5AAF008E151F /* Images.xcassets in Resources */, DA8933DC1CCD31D400E68420 /* Foundation.stringsdict in Resources */, DAC49C5D1CD02BC9009E1AA3 /* Localizable.stringsdict in Resources */, 40599F0C1DEE1B7600182B5D /* api_mapbox_staging.der in Resources */, diff --git a/platform/ios/originals/compass.sketch b/platform/ios/originals/compass.sketch new file mode 100644 index 0000000000..f5b848cd96 Binary files /dev/null and b/platform/ios/originals/compass.sketch differ diff --git a/platform/ios/resources/Compass.png b/platform/ios/resources/Compass.png deleted file mode 100644 index 08bed0591b..0000000000 Binary files a/platform/ios/resources/Compass.png and /dev/null differ diff --git a/platform/ios/resources/Compass@2x.png b/platform/ios/resources/Compass@2x.png deleted file mode 100644 index 8473a2d1ec..0000000000 Binary files a/platform/ios/resources/Compass@2x.png and /dev/null differ diff --git a/platform/ios/resources/Compass@3x.png b/platform/ios/resources/Compass@3x.png deleted file mode 100644 index 9cf66ca483..0000000000 Binary files a/platform/ios/resources/Compass@3x.png and /dev/null differ diff --git a/platform/ios/resources/Images.xcassets/Compass.imageset/Contents.json b/platform/ios/resources/Images.xcassets/Compass.imageset/Contents.json new file mode 100644 index 0000000000..6065a93b4e --- /dev/null +++ b/platform/ios/resources/Images.xcassets/Compass.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "compass.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/platform/ios/resources/Images.xcassets/Compass.imageset/compass.pdf b/platform/ios/resources/Images.xcassets/Compass.imageset/compass.pdf new file mode 100644 index 0000000000..2048f96089 Binary files /dev/null and b/platform/ios/resources/Images.xcassets/Compass.imageset/compass.pdf differ diff --git a/platform/ios/resources/Images.xcassets/Contents.json b/platform/ios/resources/Images.xcassets/Contents.json new file mode 100644 index 0000000000..da4a164c91 --- /dev/null +++ b/platform/ios/resources/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/platform/ios/resources/Images.xcassets/default_marker.imageset/Contents.json b/platform/ios/resources/Images.xcassets/default_marker.imageset/Contents.json new file mode 100644 index 0000000000..9bef658a11 --- /dev/null +++ b/platform/ios/resources/Images.xcassets/default_marker.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "default_marker.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/platform/ios/resources/Images.xcassets/default_marker.imageset/default_marker.pdf b/platform/ios/resources/Images.xcassets/default_marker.imageset/default_marker.pdf new file mode 100644 index 0000000000..4e2e332301 Binary files /dev/null and b/platform/ios/resources/Images.xcassets/default_marker.imageset/default_marker.pdf differ diff --git a/platform/ios/resources/Images.xcassets/mapbox.imageset/Contents.json b/platform/ios/resources/Images.xcassets/mapbox.imageset/Contents.json new file mode 100644 index 0000000000..b49c53da84 --- /dev/null +++ b/platform/ios/resources/Images.xcassets/mapbox.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "mapbox.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/platform/ios/resources/Images.xcassets/mapbox.imageset/mapbox.pdf b/platform/ios/resources/Images.xcassets/mapbox.imageset/mapbox.pdf new file mode 100644 index 0000000000..45111c31a6 Binary files /dev/null and b/platform/ios/resources/Images.xcassets/mapbox.imageset/mapbox.pdf differ diff --git a/platform/ios/resources/default_marker.png b/platform/ios/resources/default_marker.png deleted file mode 100644 index b112096c18..0000000000 Binary files a/platform/ios/resources/default_marker.png and /dev/null differ diff --git a/platform/ios/resources/default_marker@2x.png b/platform/ios/resources/default_marker@2x.png deleted file mode 100644 index d05c82bfe2..0000000000 Binary files a/platform/ios/resources/default_marker@2x.png and /dev/null differ diff --git a/platform/ios/resources/default_marker@3x.png b/platform/ios/resources/default_marker@3x.png deleted file mode 100644 index 703b172c15..0000000000 Binary files a/platform/ios/resources/default_marker@3x.png and /dev/null differ diff --git a/platform/ios/resources/mapbox.png b/platform/ios/resources/mapbox.png deleted file mode 100644 index 00bc897a58..0000000000 Binary files a/platform/ios/resources/mapbox.png and /dev/null differ diff --git a/platform/ios/resources/mapbox@2x.png b/platform/ios/resources/mapbox@2x.png deleted file mode 100644 index 206ed5883e..0000000000 Binary files a/platform/ios/resources/mapbox@2x.png and /dev/null differ diff --git a/platform/ios/resources/mapbox@3x.png b/platform/ios/resources/mapbox@3x.png deleted file mode 100644 index efd631b587..0000000000 Binary files a/platform/ios/resources/mapbox@3x.png and /dev/null differ diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 9a27cf24c6..ed989459f5 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -467,7 +467,7 @@ public: // setup logo bug // - UIImage *logo = [MGLMapView resourceImageNamed:@"mapbox.png"]; + UIImage *logo = [MGLMapView resourceImageNamed:@"mapbox"]; _logoView = [[UIImageView alloc] initWithImage:logo]; _logoView.accessibilityTraits = UIAccessibilityTraitStaticText; _logoView.accessibilityLabel = NSLocalizedStringWithDefaultValue(@"LOGO_A11Y_LABEL", nil, nil, @"Mapbox", @"Accessibility label"); @@ -616,11 +616,11 @@ public: - (UIImage *)compassImage { - UIImage *scaleImage = [MGLMapView resourceImageNamed:@"Compass.png"]; + UIImage *scaleImage = [MGLMapView resourceImageNamed:@"Compass"]; UIGraphicsBeginImageContextWithOptions(scaleImage.size, NO, [UIScreen mainScreen].scale); [scaleImage drawInRect:{ CGPointZero, scaleImage.size }]; - CGFloat northSize = 9; + CGFloat northSize = 11; UIFont *northFont; if ([UIFont respondsToSelector:@selector(systemFontOfSize:weight:)]) { @@ -635,7 +635,7 @@ public: NSForegroundColorAttributeName: [UIColor whiteColor], }]; CGRect stringRect = CGRectMake((scaleImage.size.width - north.size.width) / 2, - scaleImage.size.height * 0.45, + scaleImage.size.height * 0.435, north.size.width, north.size.height); [north drawInRect:stringRect]; @@ -874,8 +874,8 @@ public: // logo bug self.logoView.frame = { - self.contentInset.left+5, - CGRectGetHeight(self.bounds)-5-self.contentInset.bottom-CGRectGetHeight(self.logoView.bounds), + self.contentInset.left+8, + CGRectGetHeight(self.bounds)-8-self.contentInset.bottom-CGRectGetHeight(self.logoView.bounds), CGRectGetWidth(self.logoView.bounds), CGRectGetHeight(self.logoView.bounds) }; @@ -5290,17 +5290,17 @@ public: + (UIImage *)resourceImageNamed:(NSString *)imageName { - NSString *extension = imageName.pathExtension.length ? imageName.pathExtension : @"png"; - NSBundle *bundle = [NSBundle mgl_frameworkBundle]; - NSString *path = [bundle pathForResource:imageName.stringByDeletingPathExtension - ofType:extension]; - if ( ! path) + UIImage *image = [UIImage imageNamed:imageName + inBundle:[NSBundle mgl_frameworkBundle] + compatibleWithTraitCollection:nil]; + + if ( ! image) { - [NSException raise:@"Resource not found" format: + [NSException raise:@"MGLResourceNotFoundException" format: @"The resource named “%@” could not be found in the Mapbox framework bundle.", imageName]; } - return [UIImage imageWithContentsOfFile:path]; + return image; } - (BOOL)isFullyLoaded -- cgit v1.2.1 From bf000c7d63991d8a38012be0b3e84d29cde17fd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Tue, 23 May 2017 11:40:43 -0700 Subject: [ios, macos] Updated changelogs Reorganized the changelogs with a new packaging section. Added blurbs about #9062, #8713, #9060, and #9031. --- platform/ios/CHANGELOG.md | 19 +++++++++++++------ platform/macos/CHANGELOG.md | 10 ++++++++-- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index b5a0e7dd7d..9caec9c0d7 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -4,6 +4,12 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT ## 3.6.0 +### Packaging + +* Xcode 8.0 or higher is now recommended for using this SDK. ([#8775](https://github.com/mapbox/mapbox-gl-native/pull/8775)) +* Fixed an issue in the static framework where localizations would never load. ([#9074](https://github.com/mapbox/mapbox-gl-native/pull/9074)) +* Updated MGLMapView’s logo view to display [the new Mapbox logo](https://www.mapbox.com/blog/new-mapbox-logo/). ([#8771](https://github.com/mapbox/mapbox-gl-native/pull/8771), [#8773](https://github.com/mapbox/mapbox-gl-native/pull/8773)) + ### Styles * Added support for 3D extrusion of buildings and other polygonal features via the `MGLFillExtrusionStyleLayer` class and the `fill-extrusion` layer type in style JSON. ([#8431](https://github.com/mapbox/mapbox-gl-native/pull/8431)) @@ -15,30 +21,31 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Fixed an issue causing a composite function’s highest zoom level stop to be misinterpreted. ([#8613](https://github.com/mapbox/mapbox-gl-native/pull/8613), [#8790](https://github.com/mapbox/mapbox-gl-native/pull/8790)) * Fixed an issue where re-adding a layer that had been previously removed from a style would reset its paint properties. Moved initializers for `MGLTileSource`, `MGLStyleLayer`, and `MGLForegroundStyleLayer` to their concrete subclasses; because these classes were already intended for initialization only via concrete subclasses, this should have no developer impact. ([#8626](https://github.com/mapbox/mapbox-gl-native/pull/8626)) * Feature querying results now account for any changes to a feature’s size caused by a source or composite style function. ([#8665](https://github.com/mapbox/mapbox-gl-native/pull/8665)) +* Letter spacing is now disabled in Arabic text so that ligatures are drawn correctly. ([#9062](https://github.com/mapbox/mapbox-gl-native/pull/9062)) ### Annotations * Added a new initializer to `MGLAnnotationView` so that it is possible to create a new instance with an associated annotation object. ([#9029](https://github.com/mapbox/mapbox-gl-native/pull/9029)) * Fixed an issue causing a view-backed annotation to disappear immediately instead of animating when the annotation’s `coordinate` property is set to a value outside the current viewport. ([#8565](https://github.com/mapbox/mapbox-gl-native/pull/8565)) * Fixed an issue in which `MGLMapView` overrode the tint colors of its annotation views. ([#8789](https://github.com/mapbox/mapbox-gl-native/pull/8789)) -* Fixed an issue causing annotation views to persist in the map's annotation container view even after their associated annotations were removed. ([#9025](https://github.com/mapbox/mapbox-gl-native/pull/9025)) +* Fixed an issue causing annotation views to persist in the map’s annotation container view even after their associated annotations were removed. ([#9025](https://github.com/mapbox/mapbox-gl-native/pull/9025)) +* The `MGLPolyline.coordinate` and `MGLPolygon.coordinate` properties now return the midpoint and centroid, respectively, instead of the first coordinate. ([#8713](https://github.com/mapbox/mapbox-gl-native/pull/8713)) ### User interaction * Added a scale bar to `MGLMapView` that indicates the scale of the map. ([#7631](https://github.com/mapbox/mapbox-gl-native/pull/7631)) * Fixed an issue where gesture recognizers associated with map view interactivity were not disabled when their related interactions were disabled. ([#8304](https://github.com/mapbox/mapbox-gl-native/pull/8304)) * Fixed an issue preventing the Mapbox Telemetry confirmation dialog from appearing when opened from within a map view in a modal view controller. ([#9027](https://github.com/mapbox/mapbox-gl-native/pull/9027)) +* Corrected the size of MGLMapView’s compass. ([#9060](https://github.com/mapbox/mapbox-gl-native/pull/9060)) ### Other changes -* Xcode 8.0 or higher is now recommended for using this SDK. ([#8775](https://github.com/mapbox/mapbox-gl-native/pull/8775)) -* Fixed a crash when calling `MGLMultiPolygon.coordinate` [#8713](https://github.com/mapbox/mapbox-gl-native/pull/8713) -* Updated MGLMapView’s logo view to display [the new Mapbox logo](https://www.mapbox.com/blog/new-mapbox-logo/). ([#8771](https://github.com/mapbox/mapbox-gl-native/pull/8771), [#8773](https://github.com/mapbox/mapbox-gl-native/pull/8773)) +* Fixed a crash that occurred when accessing the `MGLMultiPolygon.coordinate` property. ([#8713](https://github.com/mapbox/mapbox-gl-native/pull/8713)) * Fixed a crash or console spew when MGLMapView is initialized with a frame smaller than 64 points wide by 64 points tall. ([#8562](https://github.com/mapbox/mapbox-gl-native/pull/8562)) +* Fixed an issue that caused the compass and scale bar to underlap navigation and tab bars. ([#7716](https://github.com/mapbox/mapbox-gl-native/pull/7716)) * The error passed into `-[MGLMapViewDelegate mapViewDidFailLoadingMap:withError:]` now includes a more specific description and failure reason. ([#8418](https://github.com/mapbox/mapbox-gl-native/pull/8418)) +* Improved CPU and battery performance while animating a tilted map’s camera in an area with many labels. ([#9031](https://github.com/mapbox/mapbox-gl-native/pull/9031)) * Fixed an issue rendering polylines that contain duplicate vertices. ([#8808](https://github.com/mapbox/mapbox-gl-native/pull/8808)) -* Fixed a bug which caused the compass and other ornaments to underlap navigation and tab bars. ([#7716](https://github.com/mapbox/mapbox-gl-native/pull/7716)) -* Fixed an issue in the static framework where localizations would never load. ([#9074](https://github.com/mapbox/mapbox-gl-native/pull/9074)) ## 3.5.4 - May 9, 2017 diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index a1515e9d7a..ca08811c0a 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -2,6 +2,11 @@ ## 3.6.0 +### Packaging + +* Xcode 8.0 or higher is now recommended for using this SDK. ([#8775](https://github.com/mapbox/mapbox-gl-native/pull/8775)) +* Updated MGLMapView’s logo view to display [the new Mapbox logo](https://www.mapbox.com/blog/new-mapbox-logo/). ([#8771](https://github.com/mapbox/mapbox-gl-native/pull/8771), [#8773](https://github.com/mapbox/mapbox-gl-native/pull/8773)) + ### Styles * Added support for 3D extrusion of buildings and other polygonal features via the `MGLFillExtrusionStyleLayer` class and the `fill-extrusion` layer type in style JSON. ([#8431](https://github.com/mapbox/mapbox-gl-native/pull/8431)) @@ -13,15 +18,16 @@ * Fixed an issue causing a composite function’s highest zoom level stop to be misinterpreted. ([#8613](https://github.com/mapbox/mapbox-gl-native/pull/8613), [#8790](https://github.com/mapbox/mapbox-gl-native/pull/8790)) * Fixed an issue where re-adding a layer that had been previously removed from a style would reset its paint properties. Moved initializers for `MGLTileSource`, `MGLStyleLayer`, and `MGLForegroundStyleLayer` to their concrete subclasses; because these classes were already intended for initialization only via concrete subclasses, this should have no developer impact. ([#8626](https://github.com/mapbox/mapbox-gl-native/pull/8626)) * Feature querying results now account for any changes to a feature’s size caused by a source or composite style function. ([#8665](https://github.com/mapbox/mapbox-gl-native/pull/8665)) +* Letter spacing is now disabled in Arabic text so that ligatures are drawn correctly. ([#9062](https://github.com/mapbox/mapbox-gl-native/pull/9062)) ### Other changes -* Xcode 8.0 or higher is now recommended for using this SDK. ([#8775](https://github.com/mapbox/mapbox-gl-native/pull/8775)) * Fixed a crash when calling `MGLMultiPolygon.coordinate` [#8713](https://github.com/mapbox/mapbox-gl-native/pull/8713) -* Updated MGLMapView’s logo view to display [the new Mapbox logo](https://www.mapbox.com/blog/new-mapbox-logo/). ([#8771](https://github.com/mapbox/mapbox-gl-native/pull/8771), [#8773](https://github.com/mapbox/mapbox-gl-native/pull/8773)) * Fixed an issue causing attribution button text to appear blue instead of black. ([#8701](https://github.com/mapbox/mapbox-gl-native/pull/8701)) * Fixed a crash or console spew when MGLMapView is initialized with a frame smaller than 64 points wide by 64 points tall. ([#8562](https://github.com/mapbox/mapbox-gl-native/pull/8562)) * The error passed into `-[MGLMapViewDelegate mapViewDidFailLoadingMap:withError:]` now includes a more specific description and failure reason. ([#8418](https://github.com/mapbox/mapbox-gl-native/pull/8418)) +* The `MGLPolyline.coordinate` and `MGLPolygon.coordinate` properties now return the midpoint and centroid, respectively, instead of the first coordinate. ([#8713](https://github.com/mapbox/mapbox-gl-native/pull/8713)) +* Improved CPU and battery performance while animating a tilted map’s camera in an area with many labels. ([#9031](https://github.com/mapbox/mapbox-gl-native/pull/9031)) * Fixed an issue rendering polylines that contain duplicate vertices. ([#8808](https://github.com/mapbox/mapbox-gl-native/pull/8808)) ## 0.4.1 - April 8, 2017 -- cgit v1.2.1 From 091d3d1d7ba519500a04907eac8fe2567ea454e2 Mon Sep 17 00:00:00 2001 From: Fabian Guerra Date: Tue, 23 May 2017 16:52:28 -0400 Subject: [ios] Update pods spec for iOS v3.6.0-beta.1 --- platform/ios/Mapbox-iOS-SDK-symbols.podspec | 2 +- platform/ios/Mapbox-iOS-SDK.podspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/ios/Mapbox-iOS-SDK-symbols.podspec b/platform/ios/Mapbox-iOS-SDK-symbols.podspec index f8b20777fa..c94b349b8c 100644 --- a/platform/ios/Mapbox-iOS-SDK-symbols.podspec +++ b/platform/ios/Mapbox-iOS-SDK-symbols.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |m| - version = '3.6.0-alpha.1' + version = '3.6.0-beta.1' m.name = 'Mapbox-iOS-SDK-symbols' m.version = "#{version}-symbols" diff --git a/platform/ios/Mapbox-iOS-SDK.podspec b/platform/ios/Mapbox-iOS-SDK.podspec index 15658e6241..0d464de400 100644 --- a/platform/ios/Mapbox-iOS-SDK.podspec +++ b/platform/ios/Mapbox-iOS-SDK.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |m| - version = '3.6.0-alpha.1' + version = '3.6.0-beta.1' m.name = 'Mapbox-iOS-SDK' m.version = version -- cgit v1.2.1 From 8c73cb1a4631211ef805ca585c74701f40699c75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Tue, 23 May 2017 13:21:34 -0700 Subject: =?UTF-8?q?[macos]=20Enable=20View=20=E2=80=A3=20Traffic=20Night?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable the View ‣ Traffic Night menu item and check it when that style is active. --- platform/macos/app/MapDocument.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m index a30e762645..59844d363e 100644 --- a/platform/macos/app/MapDocument.m +++ b/platform/macos/app/MapDocument.m @@ -807,6 +807,9 @@ NS_ARRAY_OF(id ) *MBXFlattenedShapes(NS_ARRAY_OF(id Date: Wed, 24 May 2017 14:47:31 +0200 Subject: [android] - stop location updates when toggle MyLocationView state (#9099) --- .../src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java index aecf3cc655..338d29c87c 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java @@ -440,6 +440,7 @@ public class MyLocationView extends View { } else { // Disable location and user dot location = null; + locationSource.removeLocationUpdates(); locationSource.removeLocationEngineListener(userLocationListener); locationSource.deactivate(); } -- cgit v1.2.1 From 8199315e9d554a002e950508d0b6e51f22f79d1c Mon Sep 17 00:00:00 2001 From: Tobrun Date: Wed, 24 May 2017 20:39:42 +0200 Subject: [android] - LatLngBounds bearing default value (#9102) --- platform/android/src/map/camera_position.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/android/src/map/camera_position.cpp b/platform/android/src/map/camera_position.cpp index 27b19f7ad6..d6f2cb83e8 100644 --- a/platform/android/src/map/camera_position.cpp +++ b/platform/android/src/map/camera_position.cpp @@ -13,7 +13,7 @@ jni::Object CameraPosition::New(jni::JNIEnv &env, mbgl::CameraOp // convert bearing, measured in radians counterclockwise from true north. // Wrapped to [−π rad, π rad). Android binding from 0 to 360 degrees - double bearing_degrees = -options.angle.value_or(-M_PI) * util::RAD2DEG; + double bearing_degrees = -options.angle.value_or(0) * util::RAD2DEG; while (bearing_degrees > 360) { bearing_degrees -= 360; } -- cgit v1.2.1 From e1431f9085153f7afb33ee169289ff46d38fe209 Mon Sep 17 00:00:00 2001 From: Fabian Guerra Date: Wed, 24 May 2017 12:20:58 -0400 Subject: [ios, macos] Fix MGLLight.achor to accept style functions --- platform/darwin/src/MGLLight.h | 4 ++-- platform/darwin/src/MGLLight.mm | 8 ++------ platform/darwin/test/MGLLightTest.mm | 12 +++++++++--- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/platform/darwin/src/MGLLight.h b/platform/darwin/src/MGLLight.h index d9a22d60fa..ef9811bd33 100644 --- a/platform/darwin/src/MGLLight.h +++ b/platform/darwin/src/MGLLight.h @@ -60,7 +60,7 @@ MGL_EXPORT href="https://www.mapbox.com/mapbox-gl-js/style-spec/#light-anchor">anchor light property in the Mapbox Style Specification. */ -@property (nonatomic) MGLLightAnchor anchor; +@property (nonatomic) MGLStyleValue *anchor; /** Values describing animated transitions to `anchor` property. @@ -75,7 +75,7 @@ MGL_EXPORT href="https://www.mapbox.com/mapbox-gl-js/style-spec/#light-position">position light property in the Mapbox Style Specification. */ -@property (nonatomic) MGLStyleValue * position; +@property (nonatomic) MGLStyleValue *position; /** Values describing animated transitions to `position` property. diff --git a/platform/darwin/src/MGLLight.mm b/platform/darwin/src/MGLLight.mm index 02d55e76ed..262fad3b07 100644 --- a/platform/darwin/src/MGLLight.mm +++ b/platform/darwin/src/MGLLight.mm @@ -48,9 +48,7 @@ NS_INLINE mbgl::style::TransitionOptions MGLOptionsFromTransition(MGLTransition anchorStyleValue = MGLStyleValueTransformer().toEnumStyleValue(anchor); } - NSAssert([anchorStyleValue isKindOfClass:[MGLConstantStyleValue class]], @"Anchor isn’t a constant."); - NSValue *anchorValue = ((MGLConstantStyleValue *)anchorStyleValue).rawValue; - _anchor = [anchorValue MGLLightAnchorValue]; + _anchor = anchorStyleValue; _anchorTransition = MGLTransitionFromOptions(mbglLight->getAnchorTransition()); @@ -89,11 +87,9 @@ NS_INLINE mbgl::style::TransitionOptions MGLOptionsFromTransition(MGLTransition { mbgl::style::Light mbglLight; - MGLStyleValue *anchorType = [MGLStyleValue valueWithRawValue:[NSValue valueWithMGLLightAnchor:self.anchor]]; - auto anchor = MGLStyleValueTransformer().toEnumPropertyValue(anchorType); + auto anchor = MGLStyleValueTransformer().toEnumPropertyValue(self.anchor); mbglLight.setAnchor(anchor); - mbglLight.setAnchorTransition(MGLOptionsFromTransition(self.anchorTransition)); auto position = MGLStyleValueTransformer().toInterpolatablePropertyValue(self.position); diff --git a/platform/darwin/test/MGLLightTest.mm b/platform/darwin/test/MGLLightTest.mm index 4639b13cde..2c3d1c7bd1 100644 --- a/platform/darwin/test/MGLLightTest.mm +++ b/platform/darwin/test/MGLLightTest.mm @@ -25,7 +25,10 @@ { mbgl::style::Light light; MGLLight *mglLight = [[MGLLight alloc] initWithMBGLLight:&light]; - XCTAssertEqual(mglLight.anchor, MGLLightAnchorViewport); + + NSAssert([mglLight.anchor isKindOfClass:[MGLConstantStyleValue class]], @"mglLight.anchor isn’t a MGLConstantStyleValue."); + NSValue *anchorValue = ((MGLConstantStyleValue *)mglLight.anchor).rawValue; + XCTAssertEqual(anchorValue.MGLLightAnchorValue, MGLLightAnchorViewport); XCTAssertEqual(mglLight.anchorTransition.delay, defaultTransition.delay); XCTAssertEqual(mglLight.anchorTransition.duration, defaultTransition.duration); @@ -36,10 +39,13 @@ XCTAssert(anchorTransition.delay && MGLTimeIntervalFromDuration(*anchorTransition.delay) == defaultTransition.delay); XCTAssert(anchorTransition.duration && MGLTimeIntervalFromDuration(*anchorTransition.duration) == defaultTransition.duration); - mglLight.anchor = MGLLightAnchorMap; + MGLStyleValue *anchorStyleValue = [MGLStyleValue valueWithRawValue:[NSValue valueWithMGLLightAnchor:MGLLightAnchorMap]]; + mglLight.anchor = anchorStyleValue; mglLight.anchorTransition = transition; + NSAssert([mglLight.anchor isKindOfClass:[MGLConstantStyleValue class]], @"mglLight.anchor isn’t a MGLConstantStyleValue."); + anchorValue = ((MGLConstantStyleValue *)mglLight.anchor).rawValue; - XCTAssertEqual(mglLight.anchor, MGLLightAnchorMap); + XCTAssertEqual(anchorValue.MGLLightAnchorValue, MGLLightAnchorMap); XCTAssertEqual(mglLight.anchorTransition.delay, transition.delay); XCTAssertEqual(mglLight.anchorTransition.duration, transition.duration); -- cgit v1.2.1 From fce7747da099519d8e29eff4befc5c205048492a Mon Sep 17 00:00:00 2001 From: Jesse Bounds Date: Wed, 24 May 2017 21:08:19 -0700 Subject: [ios] Fix annotation initializers for subclasses of MGLAnnotationView (#9104) Use a common init function in both of the provided initializers so that subclasses of `MGLAnnotationView` written in Swift don't need to override `init(annotation, reuseIdentifier)` --- platform/ios/ios.xcodeproj/project.pbxproj | 4 ++++ platform/ios/src/MGLAnnotationView.mm | 23 ++++++++++++++-------- .../test/MGLAnnotationViewIntegrationTests.swift | 23 ++++++++++++++++++++++ platform/ios/test/MGLAnnotationViewTests.m | 21 +++++++++++++++++++- 4 files changed, 62 insertions(+), 9 deletions(-) create mode 100644 platform/ios/test/MGLAnnotationViewIntegrationTests.swift diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index 6ff148a18e..b6d422d0fc 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -172,6 +172,7 @@ 408AA8571DAEDA1700022900 /* NSDictionary+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 408AA8551DAEDA0800022900 /* NSDictionary+MGLAdditions.h */; }; 408AA8581DAEDA1E00022900 /* NSDictionary+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 408AA8561DAEDA0800022900 /* NSDictionary+MGLAdditions.mm */; }; 408AA8591DAEDA1E00022900 /* NSDictionary+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 408AA8561DAEDA0800022900 /* NSDictionary+MGLAdditions.mm */; }; + 409D0A0D1ED614CE00C95D0C /* MGLAnnotationViewIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 409D0A0C1ED614CE00C95D0C /* MGLAnnotationViewIntegrationTests.swift */; }; 409F43FD1E9E781C0048729D /* MGLMapViewDelegateIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 409F43FC1E9E781C0048729D /* MGLMapViewDelegateIntegrationTests.swift */; }; 40CF6DBB1DAC3C6600A4D18B /* MGLShape_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 40CF6DBA1DAC3C1800A4D18B /* MGLShape_Private.h */; }; 40CFA6511D7875BB008103BD /* MGLShapeSourceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 40CFA6501D787579008103BD /* MGLShapeSourceTests.mm */; }; @@ -639,6 +640,7 @@ 4085AF081D933DEA00F11B22 /* MGLTileSetTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLTileSetTests.mm; path = ../../darwin/test/MGLTileSetTests.mm; sourceTree = ""; }; 408AA8551DAEDA0800022900 /* NSDictionary+MGLAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+MGLAdditions.h"; sourceTree = ""; }; 408AA8561DAEDA0800022900 /* NSDictionary+MGLAdditions.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSDictionary+MGLAdditions.mm"; sourceTree = ""; }; + 409D0A0C1ED614CE00C95D0C /* MGLAnnotationViewIntegrationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MGLAnnotationViewIntegrationTests.swift; sourceTree = ""; }; 409F43FC1E9E781C0048729D /* MGLMapViewDelegateIntegrationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MGLMapViewDelegateIntegrationTests.swift; sourceTree = ""; }; 40CF6DBA1DAC3C1800A4D18B /* MGLShape_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLShape_Private.h; sourceTree = ""; }; 40CFA6501D787579008103BD /* MGLShapeSourceTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLShapeSourceTests.mm; path = ../../darwin/test/MGLShapeSourceTests.mm; sourceTree = ""; }; @@ -1119,6 +1121,7 @@ isa = PBXGroup; children = ( 409F43FC1E9E781C0048729D /* MGLMapViewDelegateIntegrationTests.swift */, + 409D0A0C1ED614CE00C95D0C /* MGLAnnotationViewIntegrationTests.swift */, ); name = "Swift Integration"; sourceTree = ""; @@ -2148,6 +2151,7 @@ 1F95931D1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm in Sources */, DD58A4C61D822BD000E1F038 /* MGLExpressionTests.mm in Sources */, 3575798B1D502B0C000B822E /* MGLBackgroundStyleLayerTests.mm in Sources */, + 409D0A0D1ED614CE00C95D0C /* MGLAnnotationViewIntegrationTests.swift in Sources */, DA2E88621CC0382C00F24E7B /* MGLOfflinePackTests.m in Sources */, 55E2AD131E5B125400E8C587 /* MGLOfflineStorageTests.mm in Sources */, 920A3E5D1E6F995200C16EFC /* MGLSourceQueryTests.m in Sources */, diff --git a/platform/ios/src/MGLAnnotationView.mm b/platform/ios/src/MGLAnnotationView.mm index 9e1212b4fb..78e38f10cb 100644 --- a/platform/ios/src/MGLAnnotationView.mm +++ b/platform/ios/src/MGLAnnotationView.mm @@ -24,22 +24,29 @@ } - (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier { - return [self initWithAnnotation:nil reuseIdentifier:reuseIdentifier]; + self = [super initWithFrame:CGRectZero]; + if (self) { + [self commonInitWithAnnotation:nil reuseIdentifier:reuseIdentifier]; + } + return self; } - (instancetype)initWithAnnotation:(nullable id)annotation reuseIdentifier:(nullable NSString *)reuseIdentifier { self = [super initWithFrame:CGRectZero]; - if (self) - { - _lastAppliedScaleTransform = CATransform3DIdentity; - _annotation = annotation; - _reuseIdentifier = [reuseIdentifier copy]; - _scalesWithViewingDistance = YES; - _enabled = YES; + if (self) { + [self commonInitWithAnnotation:annotation reuseIdentifier:reuseIdentifier]; } return self; } +- (void)commonInitWithAnnotation:(nullable id)annotation reuseIdentifier:(nullable NSString *)reuseIdentifier { + _lastAppliedScaleTransform = CATransform3DIdentity; + _annotation = annotation; + _reuseIdentifier = [reuseIdentifier copy]; + _scalesWithViewingDistance = YES; + _enabled = YES; +} + - (instancetype)initWithCoder:(NSCoder *)decoder { if (self = [super initWithCoder:decoder]) { _reuseIdentifier = [decoder decodeObjectOfClass:[NSString class] forKey:@"reuseIdentifier"]; diff --git a/platform/ios/test/MGLAnnotationViewIntegrationTests.swift b/platform/ios/test/MGLAnnotationViewIntegrationTests.swift new file mode 100644 index 0000000000..82a57a4009 --- /dev/null +++ b/platform/ios/test/MGLAnnotationViewIntegrationTests.swift @@ -0,0 +1,23 @@ +import XCTest +import Mapbox + +class CustomAnnotationView: MGLAnnotationView { + + override init(reuseIdentifier: String?) { + super.init(reuseIdentifier: reuseIdentifier) + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + +} + +class MGLAnnotationViewIntegrationTests: XCTestCase { + + func testCreatingCustomAnnotationView() { + let customAnnotationView = CustomAnnotationView(reuseIdentifier: "resuse-id") + XCTAssertNotNil(customAnnotationView) + } + +} diff --git a/platform/ios/test/MGLAnnotationViewTests.m b/platform/ios/test/MGLAnnotationViewTests.m index 88ca755476..fc4f35a9e1 100644 --- a/platform/ios/test/MGLAnnotationViewTests.m +++ b/platform/ios/test/MGLAnnotationViewTests.m @@ -3,11 +3,24 @@ static NSString * const MGLTestAnnotationReuseIdentifer = @"MGLTestAnnotationReuseIdentifer"; +@interface MGLCustomAnnotationView : MGLAnnotationView + +@end + +@implementation MGLCustomAnnotationView + +- (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier { + return [super initWithReuseIdentifier:@"reuse-id"]; +} + +@end + @interface MGLAnnotationView (Test) + @property (nonatomic) MGLMapView *mapView; @property (nonatomic, readwrite) MGLAnnotationViewDragState dragState; - - (void)setDragState:(MGLAnnotationViewDragState)dragState; + @end @interface MGLMapView (Test) @@ -79,6 +92,12 @@ static NSString * const MGLTestAnnotationReuseIdentifer = @"MGLTestAnnotationReu XCTAssertNil(_annotationView.annotation, @"annotation property should be nil"); } +- (void)testCustomAnnotationView +{ + MGLCustomAnnotationView *customAnnotationView = [[MGLCustomAnnotationView alloc] initWithReuseIdentifier:@"reuse-id"]; + XCTAssertNotNil(customAnnotationView); +} + - (MGLAnnotationView *)mapView:(MGLMapView *)mapView viewForAnnotation:(id)annotation { MGLAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:MGLTestAnnotationReuseIdentifer]; -- cgit v1.2.1 From 35f548a07d11a62fda91d0352650d25ee51b1381 Mon Sep 17 00:00:00 2001 From: Jordan Kiley Date: Thu, 25 May 2017 18:09:45 -0700 Subject: [ios] Moved `MGLLight` in jazzy table of contents (#9111) --- platform/ios/jazzy.yml | 1 + platform/macos/jazzy.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/platform/ios/jazzy.yml b/platform/ios/jazzy.yml index 638abaaf6c..31380faa2c 100644 --- a/platform/ios/jazzy.yml +++ b/platform/ios/jazzy.yml @@ -60,6 +60,7 @@ custom_categories: children: - MGLStyle - MGLStyleValue + - MGLLight - name: Style Primitives children: - MGLFeature diff --git a/platform/macos/jazzy.yml b/platform/macos/jazzy.yml index 53f260b242..fcd4bfd301 100644 --- a/platform/macos/jazzy.yml +++ b/platform/macos/jazzy.yml @@ -46,6 +46,7 @@ custom_categories: children: - MGLStyle - MGLStyleValue + - MGLLight - name: Content Primitives children: - MGLFeature -- cgit v1.2.1 From c392c678ab4ea560cefca59d14b215e2d4c79ecb Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 26 May 2017 10:32:11 +0200 Subject: [android] - logo placement for creating a Mapview programatically (#9094) * [android] - Correct logo placement for creating a Mapview programatically, fixup non default placements * Fixed NIGHTY_TWO_DP typo to NINETY_TWO_DP --- .../mapbox/mapboxsdk/maps/MapboxMapOptions.java | 4 ++-- .../java/com/mapbox/mapboxsdk/maps/UiSettings.java | 28 +++++++++++++++------- .../src/main/res/values/dimens.xml | 2 +- .../main/res/layout/activity_press_for_marker.xml | 2 +- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java index 68603ab1a3..98f94ddb39 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java @@ -36,7 +36,7 @@ import java.util.Arrays; public class MapboxMapOptions implements Parcelable { private static final float FOUR_DP = 4f; - private static final float EIGHTY_NINE_DP = 92f; + private static final float NINETY_TWO_DP = 92f; private CameraPosition cameraPosition; @@ -241,7 +241,7 @@ public class MapboxMapOptions implements Parcelable { R.styleable.mapbox_MapView_mapbox_uiAttributionGravity, Gravity.BOTTOM)); mapboxMapOptions.attributionMargins(new int[] { (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiAttributionMarginLeft, - EIGHTY_NINE_DP * pxlRatio)), + NINETY_TWO_DP * pxlRatio)), (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiAttributionMarginTop, FOUR_DP * pxlRatio)), (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiAttributionMarginRight, 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 1bcf8a70b9..accecf232b 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 @@ -193,12 +193,16 @@ public final class UiSettings { private void initialiseLogo(MapboxMapOptions options, Resources resources) { setLogoEnabled(options.getLogoEnabled()); setLogoGravity(options.getLogoGravity()); - int[] logoMargins = options.getLogoMargins(); + setLogoMargins(resources, options.getLogoMargins()); + } + + private void setLogoMargins(Resources resources, int[]logoMargins) { if (logoMargins != null) { setLogoMargins(logoMargins[0], logoMargins[1], logoMargins[2], logoMargins[3]); } else { - int twoDp = (int) resources.getDimension(R.dimen.mapbox_two_dp); - setLogoMargins(twoDp, twoDp, twoDp, twoDp); + // user did not specify margins when programmatically creating a map + int fourDp = (int) resources.getDimension(R.dimen.mapbox_four_dp); + setLogoMargins(fourDp, fourDp, fourDp, fourDp); } } @@ -223,15 +227,23 @@ public final class UiSettings { private void initialiseAttribution(Context context, MapboxMapOptions options) { setAttributionEnabled(options.getAttributionEnabled()); setAttributionGravity(options.getAttributionGravity()); - int[] attributionMargins = options.getAttributionMargins(); + setAttributionMargins(context, options.getAttributionMargins()); + int attributionTintColor = options.getAttributionTintColor(); + setAttributionTintColor(attributionTintColor != -1 + ? attributionTintColor : ColorUtils.getPrimaryColor(context)); + } + + private void setAttributionMargins(Context context, int[] attributionMargins) { if (attributionMargins != null) { setAttributionMargins(attributionMargins[0], attributionMargins[1], attributionMargins[2], attributionMargins[3]); + } else { + // user did not specify margins when programmatically creating a map + Resources resources = context.getResources(); + int margin = (int) resources.getDimension(R.dimen.mapbox_four_dp); + int leftMargin = (int) resources.getDimension(R.dimen.mapbox_ninety_two_dp); + setAttributionMargins(leftMargin, margin, margin, margin); } - - int attributionTintColor = options.getAttributionTintColor(); - setAttributionTintColor(attributionTintColor != -1 - ? attributionTintColor : ColorUtils.getPrimaryColor(context)); } private void saveAttribution(Bundle outState) { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml index ce20cb9a8b..8edbd47c29 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml +++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml @@ -13,6 +13,6 @@ 8dp 10dp 16dp - 95dp + 92dp 18dp diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_press_for_marker.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_press_for_marker.xml index 9932803907..c2098b0f5b 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_press_for_marker.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_press_for_marker.xml @@ -16,6 +16,6 @@ app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets" app:mapbox_uiAttributionGravity="top|end" app:mapbox_uiLogoGravity="top|end" - app:mapbox_uiLogoMarginRight="10dp"/> + app:mapbox_uiLogoMarginRight="28dp"/> -- cgit v1.2.1 From 5716bd3aecc777813161292e104ac9ceba3f230a Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 26 May 2017 16:04:09 +0200 Subject: [android] - add binding support for Light (#9013) --- .../MapboxGLAndroidSDK/gradle-checkstyle.gradle | 1 + .../java/com/mapbox/mapboxsdk/maps/MapboxMap.java | 15 ++ .../com/mapbox/mapboxsdk/maps/NativeMapView.java | 10 ++ .../mapbox/mapboxsdk/style/layers/Property.java | 21 +++ .../com/mapbox/mapboxsdk/style/light/Light.java | 181 +++++++++++++++++++++ .../com/mapbox/mapboxsdk/style/light/Position.java | 81 +++++++++ .../mapbox/mapboxsdk/style/light/light.java.ejs | 121 ++++++++++++++ .../mapbox/mapboxsdk/testapp/style/LightTest.java | 162 ++++++++++++++++++ .../mapbox/mapboxsdk/testapp/style/light.junit.ejs | 128 +++++++++++++++ .../src/main/AndroidManifest.xml | 4 +- .../style/BuildingFillExtrusionActivity.java | 88 ++++++++-- .../style/FillExtrusionStyleTestActivity.java | 78 +++++++++ .../src/main/res/drawable/ic_paint.xml | 9 + .../main/res/layout/activity_building_layer.xml | 30 +++- .../main/res/layout/activity_extrusion_test.xml | 18 ++ .../src/main/res/menu/menu_building.xml | 12 ++ platform/android/config.cmake | 4 + platform/android/scripts/generate-style-code.js | 93 ++++++++++- platform/android/src/jni.cpp | 3 + platform/android/src/native_map_view.cpp | 11 ++ platform/android/src/native_map_view.hpp | 3 + platform/android/src/style/conversion/position.hpp | 37 +++++ platform/android/src/style/conversion/types.hpp | 7 + .../src/style/conversion/types_string_values.hpp | 14 ++ platform/android/src/style/light.cpp | 146 +++++++++++++++++ platform/android/src/style/light.cpp.ejs | 123 ++++++++++++++ platform/android/src/style/light.hpp | 57 +++++++ platform/android/src/style/light.hpp.ejs | 59 +++++++ platform/android/src/style/position.cpp | 34 ++++ platform/android/src/style/position.hpp | 29 ++++ 30 files changed, 1557 insertions(+), 22 deletions(-) create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Light.java create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Position.java create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/light.java.ejs create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LightTest.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/light.junit.ejs create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/FillExtrusionStyleTestActivity.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_paint.xml create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_extrusion_test.xml create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_building.xml create mode 100644 platform/android/src/style/conversion/position.hpp create mode 100644 platform/android/src/style/light.cpp create mode 100644 platform/android/src/style/light.cpp.ejs create mode 100644 platform/android/src/style/light.hpp create mode 100644 platform/android/src/style/light.hpp.ejs create mode 100644 platform/android/src/style/position.cpp create mode 100644 platform/android/src/style/position.hpp diff --git a/platform/android/MapboxGLAndroidSDK/gradle-checkstyle.gradle b/platform/android/MapboxGLAndroidSDK/gradle-checkstyle.gradle index 05037c6be7..e0bc076d3d 100644 --- a/platform/android/MapboxGLAndroidSDK/gradle-checkstyle.gradle +++ b/platform/android/MapboxGLAndroidSDK/gradle-checkstyle.gradle @@ -15,6 +15,7 @@ task checkstyle(type: Checkstyle) { exclude '**/style/layers/Property.java' exclude '**/style/layers/PropertyFactory.java' exclude '**/style/layers/*Layer.java' + exclude '**/style/light/Light.java' classpath = files() ignoreFailures = false } 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 96603355f1..0bfa74d1c0 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 @@ -41,6 +41,7 @@ import com.mapbox.mapboxsdk.location.LocationSource; import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings; import com.mapbox.mapboxsdk.style.layers.Filter; import com.mapbox.mapboxsdk.style.layers.Layer; +import com.mapbox.mapboxsdk.style.light.Light; import com.mapbox.mapboxsdk.style.sources.Source; import com.mapbox.services.android.telemetry.location.LocationEngine; import com.mapbox.services.commons.geojson.Feature; @@ -567,6 +568,20 @@ public final class MapboxMap { return projection; } + // + // + // + + /** + * Get the global light source used to change lighting conditions on extruded fill layers. + * + * @return the global light source + */ + @Nullable + public Light getLight() { + return nativeMapView.getLight(); + } + // // Camera API // 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 cf8faa9012..008a1971cc 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 @@ -26,6 +26,7 @@ import com.mapbox.mapboxsdk.storage.FileSource; import com.mapbox.mapboxsdk.style.layers.CannotAddLayerException; import com.mapbox.mapboxsdk.style.layers.Filter; import com.mapbox.mapboxsdk.style.layers.Layer; +import com.mapbox.mapboxsdk.style.light.Light; import com.mapbox.mapboxsdk.style.sources.CannotAddSourceException; import com.mapbox.mapboxsdk.style.sources.Source; import com.mapbox.services.commons.geojson.Feature; @@ -885,6 +886,13 @@ final class NativeMapView { fileSource.setApiBaseUrl(baseUrl); } + public Light getLight() { + if (isDestroyedOn("getLight")) { + return null; + } + return nativeGetLight(); + } + public float getPixelRatio() { return pixelRatio; } @@ -1120,6 +1128,8 @@ final class NativeMapView { String[] layerIds, Object[] filter); + private native Light nativeGetLight(); + int getWidth() { if (isDestroyedOn("")) { return 0; 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 48e0ec5de3..5e345268f9 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 @@ -467,6 +467,27 @@ public final class Property { @Retention(RetentionPolicy.SOURCE) public @interface FILL_EXTRUSION_TRANSLATE_ANCHOR {} + // ANCHOR: Whether extruded geometries are lit relative to the map or viewport. + + /** + * The position of the light source is aligned to the rotation of the map. + */ + public static final String ANCHOR_MAP = "map"; + /** + * The position of the light source is aligned to the rotation of the viewport. + */ + public static final String ANCHOR_VIEWPORT = "viewport"; + + /** + * Whether extruded geometries are lit relative to the map or viewport. + */ + @StringDef({ + ANCHOR_MAP, + ANCHOR_VIEWPORT, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ANCHOR {} + private Property() { } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Light.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Light.java new file mode 100644 index 0000000000..b66a50b8a4 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Light.java @@ -0,0 +1,181 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +package com.mapbox.mapboxsdk.style.light; + +import android.support.annotation.ColorInt; +import android.support.annotation.NonNull; +import android.support.annotation.UiThread; + +import com.mapbox.mapboxsdk.style.layers.Property; +import com.mapbox.mapboxsdk.style.layers.PropertyFactory; +import com.mapbox.mapboxsdk.style.layers.TransitionOptions; + +/** + * The global light source. + * + * @see The online documentation + */ +@UiThread +public class Light { + + private long nativePtr; + + /** + * Creates a Light. + * + * @param nativePtr pointer used by core + */ + public Light(long nativePtr) { + this.nativePtr = nativePtr; + } + + /** + * Set the Anchor property. Whether extruded geometries are lit relative to the map or viewport. + * + * @param anchor as String + */ + public void setAnchor(@Property.ANCHOR String anchor) { + nativeSetAnchor(anchor); + } + + /** + * Get the Anchor property. Whether extruded geometries are lit relative to the map or viewport. + * + * @return anchor as String + */ + @Property.ANCHOR public String getAnchor() { + return nativeGetAnchor(); + } + + /** + * Set the Position property. Position of the light source relative to lit (extruded) geometries, in [r radial coordinate, a azimuthal angle, p polar angle] where r indicates the distance from the center of the base of an object to its light, a indicates the position of the light relative to 0° (0° when `light.anchor` is set to `viewport` corresponds to the top of the viewport, or 0° when `light.anchor` is set to `map` corresponds to due north, and degrees proceed clockwise), and p indicates the height of the light (from 0°, directly above, to 180°, directly below). + * + * @param position of the light + */ + public void setPosition(@NonNull Position position) { + nativeSetPosition(position); + } + + /** + * Get the Position property. Position of the light source relative to lit (extruded) geometries, in [r radial coordinate, a azimuthal angle, p polar angle] where r indicates the distance from the center of the base of an object to its light, a indicates the position of the light relative to 0° (0° when `light.anchor` is set to `viewport` corresponds to the top of the viewport, or 0° when `light.anchor` is set to `map` corresponds to due north, and degrees proceed clockwise), and p indicates the height of the light (from 0°, directly above, to 180°, directly below). + * + * @return position as Position + */ + public Position getPosition() { + return nativeGetPosition(); + } + + /** + * Get the Position property transition options. + * + * @return transition options for position + */ + public TransitionOptions getPositionTransition() { + return nativeGetPositionTransition(); + } + + /** + * Set the Position property transition options. + * + * @param options transition options for position + */ + public void setPositionTransition(TransitionOptions options) { + nativeSetPositionTransition(options.getDuration(), options.getDelay()); + } + + /** + * Set the Color property. Color tint for lighting extruded geometries. + * + * @param color as int + */ + public void setColor(@ColorInt int color) { + nativeSetColor(PropertyFactory.colorToRgbaString(color)); + } + + /** + * Set the Color property. Color tint for lighting extruded geometries. + * + * @param color as String + */ + public void setColor(String color) { + nativeSetColor(color); + } + + /** + * Get the Color property. Color tint for lighting extruded geometries. + * + * @return color as String + */ + public String getColor() { + return nativeGetColor(); + } + + /** + * Get the Color property transition options. + * + * @return transition options for color + */ + public TransitionOptions getColorTransition() { + return nativeGetColorTransition(); + } + + /** + * Set the Color property transition options. + * + * @param options transition options for color + */ + public void setColorTransition(TransitionOptions options) { + nativeSetColorTransition(options.getDuration(), options.getDelay()); + } + + /** + * Set the Intensity property. Intensity of lighting (on a scale from 0 to 1). Higher numbers will present as more extreme contrast. + * + * @param intensity as Float + */ + public void setIntensity(float intensity) { + nativeSetIntensity(intensity); + } + + /** + * Get the Intensity property. Intensity of lighting (on a scale from 0 to 1). Higher numbers will present as more extreme contrast. + * + * @return intensity as Float + */ + public float getIntensity() { + return nativeGetIntensity(); + } + + /** + * Get the Intensity property transition options. + * + * @return transition options for intensity + */ + public TransitionOptions getIntensityTransition() { + return nativeGetIntensityTransition(); + } + + /** + * Set the Intensity property transition options. + * + * @param options transition options for intensity + */ + public void setIntensityTransition(TransitionOptions options) { + nativeSetIntensityTransition(options.getDuration(), options.getDelay()); + } + + private native void nativeSetAnchor(String anchor); + private native String nativeGetAnchor(); + private native void nativeSetPosition(Position position); + private native Position nativeGetPosition(); + private native TransitionOptions nativeGetPositionTransition(); + private native void nativeSetPositionTransition(long duration, long delay); + private native void nativeSetColor(String color); + private native String nativeGetColor(); + private native TransitionOptions nativeGetColorTransition(); + private native void nativeSetColorTransition(long duration, long delay); + private native void nativeSetIntensity(float intensity); + private native float nativeGetIntensity(); + private native TransitionOptions nativeGetIntensityTransition(); + private native void nativeSetIntensityTransition(long duration, long delay); +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Position.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Position.java new file mode 100644 index 0000000000..215db03ad2 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Position.java @@ -0,0 +1,81 @@ +package com.mapbox.mapboxsdk.style.light; + +/** + * Position of the light source relative to lit (extruded) geometries. + *

+ * The position is constructed out of a radial coordinate, an azimuthal angle and a polar angle. + * where the radial coordinate indicates the distance from the center of the base of an object to its light, the + * azimuthal angle indicates the position of the light relative to 0° (0° when + * {@link com.mapbox.mapboxsdk.style.layers.Property.ANCHOR} is set to viewport corresponds to the top of the + * viewport, or 0° when {@link com.mapbox.mapboxsdk.style.layers.Property.ANCHOR} is set to map corresponds to due + * north, and degrees proceed clockwise), and polar indicates the height of the light + * (from 0°, directly above, to 180°, directly below). + */ +public class Position { + + private float radialCoordinate; + private float azimuthalAngle; + private float polarAngle; + + /** + * Creates a Position from a radial coordinate, an azimuthal angle & a polar angle. + * + * @param radialCoordinate the distance from the center of the base of an object to its light + * @param azimuthalAngle the position of the light relative to 0° + * @param polarAngle the height of the light + */ + public Position(float radialCoordinate, float azimuthalAngle, float polarAngle) { + this.radialCoordinate = radialCoordinate; + this.azimuthalAngle = azimuthalAngle; + this.polarAngle = polarAngle; + } + + /** + * Returns a Position from a radial coordinate, an azimuthal angle & a polar angle + * + * @param radialCoordinate the radial coordinate + * @param azimuthalAngle the azimuthal angle + * @param polarAngle the polar angle + * @return the created Position object + */ + public static Position fromPosition(float radialCoordinate, float azimuthalAngle, float polarAngle) { + return new Position(radialCoordinate, azimuthalAngle, polarAngle); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Position position = (Position) o; + + if (Float.compare(position.radialCoordinate, radialCoordinate) != 0) { + return false; + } + if (Float.compare(position.azimuthalAngle, azimuthalAngle) != 0) { + return false; + } + return Float.compare(position.polarAngle, polarAngle) == 0; + } + + @Override + public int hashCode() { + int result = (radialCoordinate != +0.0f ? Float.floatToIntBits(radialCoordinate) : 0); + result = 31 * result + (azimuthalAngle != +0.0f ? Float.floatToIntBits(azimuthalAngle) : 0); + result = 31 * result + (polarAngle != +0.0f ? Float.floatToIntBits(polarAngle) : 0); + return result; + } + + @Override + public String toString() { + return "Position{" + + "radialCoordinate=" + radialCoordinate + + ", azimuthalAngle=" + azimuthalAngle + + ", polarAngle=" + polarAngle + + '}'; + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/light.java.ejs b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/light.java.ejs new file mode 100644 index 0000000000..067efe1092 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/light.java.ejs @@ -0,0 +1,121 @@ +<% + const properties = locals.properties; + const doc = locals.doc; +-%> +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +package com.mapbox.mapboxsdk.style.light; + +import android.support.annotation.ColorInt; +import android.support.annotation.NonNull; +import android.support.annotation.UiThread; + +import com.mapbox.mapboxsdk.style.layers.Property; +import com.mapbox.mapboxsdk.style.layers.PropertyFactory; +import com.mapbox.mapboxsdk.style.layers.TransitionOptions; + +/** + * The global light source. + * + * @see The online documentation + */ +@UiThread +public class Light { + + private long nativePtr; + + /** + * Creates a Light. + * + * @param nativePtr pointer used by core + */ + public Light(long nativePtr) { + this.nativePtr = nativePtr; + } +<% for (const property of properties) { -%> +<% if (property.name == "position") {-%> + + /** + * Set the <%- camelize(property.name) %> property. <%- property.doc %> + * + * @param position of the light + */ + public void set<%- camelize(property.name) %>(@NonNull Position position) { + nativeSet<%- camelize(property.name) %>(position); + } + + /** + * Get the <%- camelize(property.name) %> property. <%- property.doc %> + * + * @return <%- property.name %> as Position + */ + public Position get<%- camelize(property.name) %>() { + return nativeGet<%- camelize(property.name) %>(); + } +<% } else { -%> +<% if (property.name == "color") {-%> + + /** + * Set the <%- camelize(property.name) %> property. <%- property.doc %> + * + * @param <%- property.name %> as int + */ + public void set<%- camelize(property.name) %>(@ColorInt int <%- property.name %>) { + nativeSet<%- camelize(property.name) %>(PropertyFactory.colorToRgbaString(<%- property.name %>)); + } +<% } -%> + + /** + * Set the <%- camelize(property.name) %> property. <%- property.doc %> + * + * @param <%- property.name %> as <%- propertyType(property) %> + */ + public void set<%- camelize(property.name) %>(<%- propertyTypeAnnotation(property) %><%- iff(() => propertyTypeAnnotation(property), " ") %><%- propertyJavaType(property) %> <%- property.name %>) { + nativeSet<%- camelize(property.name) %>(<%- property.name %>); + } + + /** + * Get the <%- camelize(property.name) %> property. <%- property.doc %> + * + * @return <%- property.name %> as <%- propertyType(property) %> + */ + <%- propertyTypeAnnotation(property) %> public <%- propertyJavaType(property) %> get<%- camelize(property.name) %>() { + return nativeGet<%- camelize(property.name) %>(); + } +<% } -%> +<% if (property.transition) { -%> + + /** + * Get the <%- camelize(property.name) %> property transition options. + * + * @return transition options for <%- property.name %> + */ + public TransitionOptions get<%- camelize(property.name) %>Transition() { + return nativeGet<%- camelize(property.name) %>Transition(); + } + + /** + * Set the <%- camelize(property.name) %> property transition options. + * + * @param options transition options for <%- property.name %> + */ + public void set<%- camelize(property.name) %>Transition(TransitionOptions options) { + nativeSet<%- camelize(property.name) %>Transition(options.getDuration(), options.getDelay()); + } +<% } -%> +<% } -%> + +<% for (const property of properties) { -%> +<% if (property.name == "position") {-%> + private native void nativeSet<%- camelize(property.name) %>(Position position); + private native Position nativeGet<%- camelize(property.name) %>(); +<% } else { -%> + private native void nativeSet<%- camelize(property.name) %>(<%- propertyJavaType(property) -%> <%- property.name %>); + private native <%- propertyJavaType(property) -%> nativeGet<%- camelize(property.name) %>(); +<% } -%> +<% if (property.transition) { -%> + private native TransitionOptions nativeGet<%- camelize(property.name) %>Transition(); + private native void nativeSet<%- camelize(property.name) %>Transition(long duration, long delay); +<% } -%> +<% } -%> +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LightTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LightTest.java new file mode 100644 index 0000000000..36833fb4ee --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LightTest.java @@ -0,0 +1,162 @@ +package com.mapbox.mapboxsdk.testapp.style; + +import android.graphics.Color; +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.light.Light; +import com.mapbox.mapboxsdk.style.functions.Function; +import com.mapbox.mapboxsdk.style.functions.stops.IdentityStops; +import com.mapbox.mapboxsdk.style.layers.FillExtrusionLayer; +import com.mapbox.mapboxsdk.style.layers.TransitionOptions; +import com.mapbox.mapboxsdk.style.light.Position; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; +import com.mapbox.mapboxsdk.testapp.activity.style.FillExtrusionStyleTestActivity; + +import timber.log.Timber; + +import org.hamcrest.Matcher; +import org.junit.Test; +import org.junit.runner.RunWith; + +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; +import static com.mapbox.mapboxsdk.style.layers.Filter.eq; +import static com.mapbox.mapboxsdk.style.layers.Property.ANCHOR_MAP; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionBase; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionColor; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionHeight; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionOpacity; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; + +@RunWith(AndroidJUnit4.class) +public class LightTest extends BaseActivityTest { + + private Light light; + + @Test + public void testAnchor() { + validateTestSetup(); + setupLayer(); + Timber.i("anchor"); + assertNotNull(light); + // Set and Get + light.setAnchor(ANCHOR_MAP); + assertEquals("Anchor should match", ANCHOR_MAP, light.getAnchor()); + } + + @Test + public void testPositionTransition() { + validateTestSetup(); + setupLayer(); + Timber.i("positionTransitionOptions"); + assertNotNull(light); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + light.setPositionTransition(options); + assertEquals("Transition options should match", options, light.getPositionTransition()); + } + + @Test + public void testPosition() { + validateTestSetup(); + setupLayer(); + Timber.i("position"); + assertNotNull(light); + + // Set and Get + Position position = new Position(1,2,3); + light.setPosition(position); + assertEquals("Position should match", position, light.getPosition()); + } + + @Test + public void testColorTransition() { + validateTestSetup(); + setupLayer(); + Timber.i("colorTransitionOptions"); + assertNotNull(light); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + light.setColorTransition(options); + assertEquals("Transition options should match", options, light.getColorTransition()); + } + + @Test + public void testColor() { + validateTestSetup(); + setupLayer(); + Timber.i("color"); + assertNotNull(light); + // Set and Get + light.setColor("rgba(0, 0, 0, 1)"); + assertEquals("Color should match", "rgba(0, 0, 0, 1)".replaceAll("\\s+",""), light.getColor()); + } + + @Test + public void testIntensityTransition() { + validateTestSetup(); + setupLayer(); + Timber.i("intensityTransitionOptions"); + assertNotNull(light); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + light.setIntensityTransition(options); + assertEquals("Transition options should match", options, light.getIntensityTransition()); + } + + @Test + public void testIntensity() { + validateTestSetup(); + setupLayer(); + Timber.i("intensity"); + assertNotNull(light); + // Set and Get + light.setIntensity(0.3f); + assertEquals("Intensity should match", 0.3f, light.getIntensity()); + } + + private void setupLayer() { + onView(withId(R.id.mapView)).perform(new ViewAction() { + @Override + public Matcher getConstraints() { + return isDisplayed(); + } + + @Override + public String getDescription() { + return getClass().getSimpleName(); + } + + @Override + public void perform(UiController uiController, View view) { + light = mapboxMap.getLight(); + FillExtrusionLayer fillExtrusionLayer = new FillExtrusionLayer("3d-buildings", "composite"); + fillExtrusionLayer.setSourceLayer("building"); + fillExtrusionLayer.setFilter(eq("extrude", "true")); + fillExtrusionLayer.setMinZoom(15); + fillExtrusionLayer.setProperties( + fillExtrusionColor(Color.LTGRAY), + fillExtrusionHeight(Function.property("height", new IdentityStops())), + fillExtrusionBase(Function.property("min_height", new IdentityStops())), + fillExtrusionOpacity(0.6f) + ); + mapboxMap.addLayer(fillExtrusionLayer); + } + }); + } + + @Override + protected Class getActivityClass() { + return FillExtrusionStyleTestActivity.class; + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/light.junit.ejs b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/light.junit.ejs new file mode 100644 index 0000000000..cb3ba58100 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/light.junit.ejs @@ -0,0 +1,128 @@ +<% + const properties = locals.properties; +-%> +package com.mapbox.mapboxsdk.testapp.style; + +import android.graphics.Color; +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.light.Light; +import com.mapbox.mapboxsdk.style.functions.Function; +import com.mapbox.mapboxsdk.style.functions.stops.IdentityStops; +import com.mapbox.mapboxsdk.style.layers.FillExtrusionLayer; +import com.mapbox.mapboxsdk.style.layers.TransitionOptions; +import com.mapbox.mapboxsdk.style.light.Position; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; +import com.mapbox.mapboxsdk.testapp.activity.style.FillExtrusionStyleTestActivity; + +import timber.log.Timber; + +import org.hamcrest.Matcher; +import org.junit.Test; +import org.junit.runner.RunWith; + +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; +import static com.mapbox.mapboxsdk.style.layers.Filter.eq; +import static com.mapbox.mapboxsdk.style.layers.Property.ANCHOR_MAP; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionBase; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionColor; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionHeight; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionOpacity; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; + +@RunWith(AndroidJUnit4.class) +public class LightTest extends BaseActivityTest { + + private Light light; +<% for (const property of properties) { -%> +<% if (property.transition) { -%> + + @Test + public void test<%- camelize(property.name) %>Transition() { + validateTestSetup(); + setupLayer(); + Timber.i("<%- property.name %>TransitionOptions"); + assertNotNull(light); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + light.set<%- camelize(property.name) %>Transition(options); + assertEquals("Transition options should match", options, light.get<%- camelize(property.name) %>Transition()); + } +<% } -%> +<% if (property.name == "position") { -%> + + @Test + public void test<%- camelize(property.name) %>() { + validateTestSetup(); + setupLayer(); + Timber.i("<%- property.name %>"); + assertNotNull(light); + + // Set and Get + Position position = new Position(1,2,3); + light.set<%- camelize(property.name) %>(position); + assertEquals("Position should match", position, light.get<%- camelize(property.name) %>()); + } +<% } else { -%> + + @Test + public void test<%- camelize(property.name) %>() { + validateTestSetup(); + setupLayer(); + Timber.i("<%- property.name %>"); + assertNotNull(light); + // Set and Get + light.set<%- camelize(property.name) %>(<%- defaultValueJava(property) %>); +<% if (property.name == 'color') { -%> + assertEquals("<%- camelize(property.name) %> should match", <%- defaultValueJava(property) %>.replaceAll("\\s+",""), light.get<%- camelize(property.name) %>()); +<% } else { -%> + assertEquals("<%- camelize(property.name) %> should match", <%- defaultValueJava(property) %>, light.get<%- camelize(property.name) %>()); +<% } -%> + } +<% } -%> +<% } -%> + + private void setupLayer() { + onView(withId(R.id.mapView)).perform(new ViewAction() { + @Override + public Matcher getConstraints() { + return isDisplayed(); + } + + @Override + public String getDescription() { + return getClass().getSimpleName(); + } + + @Override + public void perform(UiController uiController, View view) { + light = mapboxMap.getLight(); + FillExtrusionLayer fillExtrusionLayer = new FillExtrusionLayer("3d-buildings", "composite"); + fillExtrusionLayer.setSourceLayer("building"); + fillExtrusionLayer.setFilter(eq("extrude", "true")); + fillExtrusionLayer.setMinZoom(15); + fillExtrusionLayer.setProperties( + fillExtrusionColor(Color.LTGRAY), + fillExtrusionHeight(Function.property("height", new IdentityStops())), + fillExtrusionBase(Function.property("min_height", new IdentityStops())), + fillExtrusionOpacity(0.6f) + ); + mapboxMap.addLayer(fillExtrusionLayer); + } + }); + } + + @Override + protected Class getActivityClass() { + return FillExtrusionStyleTestActivity.class; + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml index 9ede763533..1a70e4548a 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml @@ -661,7 +661,9 @@ - + ())), - fillExtrusionBase(Function.property("min_height", new IdentityStops())), - fillExtrusionOpacity(0.6f) - ); - map.addLayer(fillExtrusionLayer); + mapboxMap = map; + setupBuildings(); + setupLight(); } }); } + private void setupBuildings() { + FillExtrusionLayer fillExtrusionLayer = new FillExtrusionLayer("3d-buildings", "composite"); + fillExtrusionLayer.setSourceLayer("building"); + fillExtrusionLayer.setFilter(eq("extrude", "true")); + fillExtrusionLayer.setMinZoom(15); + fillExtrusionLayer.setProperties( + fillExtrusionColor(Color.LTGRAY), + fillExtrusionHeight(Function.property("height", new IdentityStops())), + fillExtrusionBase(Function.property("min_height", new IdentityStops())), + fillExtrusionOpacity(0.9f) + ); + mapboxMap.addLayer(fillExtrusionLayer); + } + + private void setupLight() { + light = mapboxMap.getLight(); + + findViewById(R.id.fabLightPosition).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + isInitPosition = !isInitPosition; + if (isInitPosition) { + light.setPosition(new Position(1.5f, 90, 80)); + } else { + light.setPosition(new Position(1.15f, 210, 30)); + } + } + }); + + findViewById(R.id.fabLightColor).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + isRedColor = !isRedColor; + light.setColor(PropertyFactory.colorToRgbaString(isRedColor ? Color.RED : Color.BLUE)); + } + }); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_building, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (light != null) { + int id = item.getItemId(); + if (id == R.id.menu_action_anchor) { + isMapAnchorLight = !isMapAnchorLight; + light.setAnchor(isMapAnchorLight ? Property.ANCHOR_MAP : Property.ANCHOR_VIEWPORT); + } else if (id == R.id.menu_action_intensity) { + isLowIntensityLight = !isLowIntensityLight; + light.setIntensity(isLowIntensityLight ? 0.35f : 1.0f); + } + } + return super.onOptionsItemSelected(item); + } + @Override protected void onStart() { super.onStart(); @@ -91,5 +156,4 @@ public class BuildingFillExtrusionActivity extends AppCompatActivity { super.onDestroy(); mapView.onDestroy(); } - } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/FillExtrusionStyleTestActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/FillExtrusionStyleTestActivity.java new file mode 100644 index 0000000000..1ff0b0e8e1 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/FillExtrusionStyleTestActivity.java @@ -0,0 +1,78 @@ +package com.mapbox.mapboxsdk.testapp.activity.style; + + +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.testapp.R; + +public class FillExtrusionStyleTestActivity extends AppCompatActivity { + + public MapView mapView; + private MapboxMap mapboxMap; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_extrusion_test); + + // Initialize map as normal + mapView = (MapView) findViewById(R.id.mapView); + mapView.onCreate(savedInstanceState); + mapView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(MapboxMap mapboxMap) { + FillExtrusionStyleTestActivity.this.mapboxMap = mapboxMap; + } + }); + } + + public MapboxMap getMapboxMap() { + return mapboxMap; + } + + @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 + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + mapView.onSaveInstanceState(outState); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapView.onDestroy(); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapView.onLowMemory(); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_paint.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_paint.xml new file mode 100644 index 0000000000..f9e55e1480 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_paint.xml @@ -0,0 +1,9 @@ + + + diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_building_layer.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_building_layer.xml index d9a10871b5..fa37c485d7 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_building_layer.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_building_layer.xml @@ -1,9 +1,8 @@ - + android:layout_height="match_parent"> + app:mapbox_styleUrl="@string/mapbox_style_dark"/> - + + + + + diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_extrusion_test.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_extrusion_test.xml new file mode 100644 index 0000000000..d9a10871b5 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_extrusion_test.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_building.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_building.xml new file mode 100644 index 0000000000..92d1dd5380 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_building.xml @@ -0,0 +1,12 @@ + +

+ + + diff --git a/platform/android/config.cmake b/platform/android/config.cmake index c111744ed0..84591d644b 100644 --- a/platform/android/config.cmake +++ b/platform/android/config.cmake @@ -168,6 +168,10 @@ add_library(mbgl-android STATIC platform/android/src/style/functions/identity_stops.hpp platform/android/src/style/functions/interval_stops.cpp platform/android/src/style/functions/interval_stops.hpp + platform/android/src/style/position.cpp + platform/android/src/style/position.hpp + platform/android/src/style/light.cpp + platform/android/src/style/light.hpp # FileSource holder platform/android/src/file_source.cpp diff --git a/platform/android/scripts/generate-style-code.js b/platform/android/scripts/generate-style-code.js index 5d8fc4cc6d..bb04e3ba2a 100644 --- a/platform/android/scripts/generate-style-code.js +++ b/platform/android/scripts/generate-style-code.js @@ -8,6 +8,13 @@ const _ = require('lodash'); require('../../../scripts/style-code'); // Specification parsing // +const lightProperties = Object.keys(spec[`light`]).reduce((memo, name) => { + var property = spec[`light`][name]; + property.name = name; + property['light-property'] = true; + memo.push(property); + return memo; +}, []); // Collect layer types from spec var layers = Object.keys(spec.layer.type.values).map((type) => { @@ -37,7 +44,7 @@ var layers = Object.keys(spec.layer.type.values).map((type) => { // Process all layer properties const layoutProperties = _(layers).map('layoutProperties').flatten().value(); const paintProperties = _(layers).map('paintProperties').flatten().value(); -const allProperties = _(layoutProperties).union(paintProperties).value(); +const allProperties = _(layoutProperties).union(paintProperties).union(lightProperties).value(); const enumProperties = _(allProperties).filter({'type': 'enum'}).value(); global.propertyType = function propertyType(property) { @@ -59,12 +66,31 @@ global.propertyType = function propertyType(property) { } } +global.propertyJavaType = function propertyType(property) { + switch (property.type) { + case 'boolean': + return 'boolean'; + case 'number': + return 'float'; + case 'string': + return 'String'; + case 'enum': + return 'String'; + case 'color': + return 'String'; + case 'array': + return `${propertyJavaType({type:property.value})}[]`; + default: + throw new Error(`unknown type for ${property.name}`); + } + } + global.propertyJNIType = function propertyJNIType(property) { switch (property.type) { case 'boolean': return 'jboolean'; - case 'jfloat': - return 'Float'; + case 'number': + return 'jfloat'; case 'String': return 'String'; case 'enum': @@ -93,6 +119,9 @@ global.propertyNativeType = function (property) { case 'string': return 'std::string'; case 'enum': + if(property['light-property']){ + return `Light${camelize(property.name)}Type`; + } return `${camelize(property.name)}Type`; case 'color': return `Color`; @@ -215,6 +244,53 @@ global.propertyValueDoc = function (property, value) { return doc; }; +global.isDataDriven = function (property) { + return property['property-function'] === true; +}; + +global.isLightProperty = function (property) { + return property['light-property'] === true; +}; + +global.propertyValueType = function (property) { + if (isDataDriven(property)) { + return `DataDrivenPropertyValue<${evaluatedType(property)}>`; + } else { + return `PropertyValue<${evaluatedType(property)}>`; + } +}; + +global.evaluatedType = function (property) { + if (/-translate-anchor$/.test(property.name)) { + return 'TranslateAnchorType'; + } + if (/-(rotation|pitch|illumination)-alignment$/.test(property.name)) { + return 'AlignmentType'; + } + if (/position/.test(property.name)) { + return 'Position'; + } + switch (property.type) { + case 'boolean': + return 'bool'; + case 'number': + return 'float'; + case 'string': + return 'std::string'; + case 'enum': + return (isLightProperty(property) ? 'Light' : '') + `${camelize(property.name)}Type`; + case 'color': + return `Color`; + case 'array': + if (property.length) { + return `std::array<${evaluatedType({type: property.value})}, ${property.length}>`; + } else { + return `std::vector<${evaluatedType({type: property.value})}>`; + } + default: throw new Error(`unknown type for ${property.name}`) + } +}; + global.supportsZoomFunction = function (property) { return property['zoom-function'] === true; }; @@ -225,6 +301,16 @@ global.supportsPropertyFunction = function (property) { // Template processing // +// Java + JNI Light (Peer model) +const lightHpp = ejs.compile(fs.readFileSync('platform/android/src/style/light.hpp.ejs', 'utf8'), {strict: true});; +const lightCpp = ejs.compile(fs.readFileSync('platform/android/src/style/light.cpp.ejs', 'utf8'), {strict: true});; +const lightJava = ejs.compile(fs.readFileSync('platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/light.java.ejs', 'utf8'), {strict: true}); +const lightJavaUnitTests = ejs.compile(fs.readFileSync('platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/light.junit.ejs', 'utf8'), {strict: true}); +writeIfModified(`platform/android/src/style/light.hpp`, lightHpp({properties: lightProperties})); +writeIfModified(`platform/android/src/style/light.cpp`, lightCpp({properties: lightProperties})); +writeIfModified(`platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Light.java`, lightJava({properties: lightProperties})); +writeIfModified(`platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LightTest.java`, lightJavaUnitTests({properties: lightProperties})); + // Java + JNI Layers (Peer model) const layerHpp = ejs.compile(fs.readFileSync('platform/android/src/style/layers/layer.hpp.ejs', 'utf8'), {strict: true}); const layerCpp = ejs.compile(fs.readFileSync('platform/android/src/style/layers/layer.cpp.ejs', 'utf8'), {strict: true}); @@ -238,7 +324,6 @@ for (const layer of layers) { writeIfModified(`platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/${camelize(layer.type)}LayerTest.java`, layerJavaUnitTests(layer)); } - // Java PropertyFactory const propertiesTemplate = ejs.compile(fs.readFileSync('platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs', 'utf8'), {strict: true}); writeIfModified( diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp index 53691acb39..6c490fad5c 100755 --- a/platform/android/src/jni.cpp +++ b/platform/android/src/jni.cpp @@ -45,6 +45,7 @@ #include "style/functions/stop.hpp" #include "style/layers/layers.hpp" #include "style/sources/sources.hpp" +#include "style/light.hpp" namespace mbgl { namespace android { @@ -153,6 +154,8 @@ void registerNatives(JavaVM *vm) { TransitionOptions::registerNative(env); registerNativeLayers(env); registerNativeSources(env); + Light::registerNative(env); + Position::registerNative(env); Stop::registerNative(env); CategoricalStops::registerNative(env); ExponentialStops::registerNative(env); diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index 1012a0e9d8..0a57d3e6b4 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -46,6 +46,7 @@ #include "java/util.hpp" #include "geometry/lat_lng_bounds.hpp" #include "map/camera_position.hpp" +#include "style/light.hpp" namespace mbgl { namespace android { @@ -819,6 +820,15 @@ jni::Array> NativeMapView::queryRenderedFeaturesFo return *convert>, std::vector>(env, map->queryRenderedFeatures(box, { layers, toFilter(env, jfilter) })); } +jni::Object NativeMapView::getLight(JNIEnv& env) { + mbgl::style::Light* light = map->getLight(); + if (light) { + return jni::Object(Light::createJavaLightPeer(env, *map, *light)); + } else { + return jni::Object(); + } +} + jni::Array> NativeMapView::getLayers(JNIEnv& env) { // Get the core layers @@ -1533,6 +1543,7 @@ void NativeMapView::registerNative(jni::JNIEnv& env) { METHOD(&NativeMapView::queryPointAnnotations, "nativeQueryPointAnnotations"), METHOD(&NativeMapView::queryRenderedFeaturesForPoint, "nativeQueryRenderedFeaturesForPoint"), METHOD(&NativeMapView::queryRenderedFeaturesForBox, "nativeQueryRenderedFeaturesForBox"), + METHOD(&NativeMapView::getLight, "nativeGetLight"), METHOD(&NativeMapView::getLayers, "nativeGetLayers"), METHOD(&NativeMapView::getLayer, "nativeGetLayer"), METHOD(&NativeMapView::addLayer, "nativeAddLayer"), diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp index e5fcb9badd..df43ad08b7 100755 --- a/platform/android/src/native_map_view.hpp +++ b/platform/android/src/native_map_view.hpp @@ -24,6 +24,7 @@ #include "style/sources/sources.hpp" #include "geometry/lat_lng_bounds.hpp" #include "map/camera_position.hpp" +#include "style/light.hpp" #include #include @@ -230,6 +231,8 @@ public: jni::jfloat, jni::Array, jni::Array> jfilter); + jni::Object getLight(JNIEnv&); + jni::Array> getLayers(JNIEnv&); jni::Object getLayer(JNIEnv&, jni::String); diff --git a/platform/android/src/style/conversion/position.hpp b/platform/android/src/style/conversion/position.hpp new file mode 100644 index 0000000000..f32a892c0c --- /dev/null +++ b/platform/android/src/style/conversion/position.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include "../../conversion/conversion.hpp" + +#include +#include +#include "../../jni/local_object.hpp" +#include "../position.hpp" + +namespace mbgl { +namespace android { +namespace conversion { + +template<> +struct Converter, mbgl::style::Position> { + Result> operator()(jni::JNIEnv &env, const mbgl::style::Position &value) const { + std::array cartPosition = value.getSpherical(); + return Position::fromPosition(env, cartPosition[0], cartPosition[1], cartPosition[2]); + } +}; + +template<> +struct Converter> { + Result operator()(jni::JNIEnv &env, const jni::Object &value) const { + float radialCoordinate = Position::getRadialCoordinate(env, value); + float azimuthalAngle = Position::getAzimuthalAngle(env, value); + float polarAngle = Position::getPolarAngle(env, value); + std::array cartPosition {{radialCoordinate, azimuthalAngle, polarAngle}}; + mbgl::style::Position position{}; + position.set(cartPosition); + return position; + } +}; + +} +} +} \ No newline at end of file diff --git a/platform/android/src/style/conversion/types.hpp b/platform/android/src/style/conversion/types.hpp index d9921e582e..a00f668c24 100644 --- a/platform/android/src/style/conversion/types.hpp +++ b/platform/android/src/style/conversion/types.hpp @@ -92,6 +92,13 @@ struct Converter { } }; +template <> +struct Converter { + Result operator()(jni::JNIEnv& env, const mbgl::style::LightAnchorType& value) const { + return convert(env, toString(value)); + } +}; + } // namespace conversion } // namespace android diff --git a/platform/android/src/style/conversion/types_string_values.hpp b/platform/android/src/style/conversion/types_string_values.hpp index e3108fdf5b..e96de3b01e 100644 --- a/platform/android/src/style/conversion/types_string_values.hpp +++ b/platform/android/src/style/conversion/types_string_values.hpp @@ -206,6 +206,20 @@ namespace conversion { } } + // anchor + inline std::string toString(mbgl::style::LightAnchorType value) { + switch (value) { + case mbgl::style::LightAnchorType::Map: + return "map"; + break; + case mbgl::style::LightAnchorType::Viewport: + return "viewport"; + break; + default: + throw std::runtime_error("Not implemented"); + } + } + } // namespace conversion } // namespace android diff --git a/platform/android/src/style/light.cpp b/platform/android/src/style/light.cpp new file mode 100644 index 0000000000..71f1cb076e --- /dev/null +++ b/platform/android/src/style/light.cpp @@ -0,0 +1,146 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +#include +#include "light.hpp" +#include "conversion/transition_options.hpp" +#include "conversion/position.hpp" + +namespace mbgl { +namespace android { + +Light::Light(mbgl::Map& coreMap, mbgl::style::Light& coreLight) + : light(coreLight) , map(&coreMap) { +} + +static Light* initializeLightPeer(mbgl::Map& map, mbgl::style::Light& coreLight) { + return new Light(map, coreLight); +} + +jni::jobject* Light::createJavaLightPeer(jni::JNIEnv& env, Map& map, mbgl::style::Light& coreLight) { + std::unique_ptr peerLight = std::unique_ptr(initializeLightPeer(map, coreLight)); + jni::jobject* result = peerLight->createJavaPeer(env); + peerLight.release(); + return result; +} + +jni::Class Light::javaClass; + +jni::jobject* Light::createJavaPeer(jni::JNIEnv& env) { + static auto constructor = Light::javaClass.template GetConstructor(env); + return Light::javaClass.New(env, constructor, reinterpret_cast(this)); +} + +void Light::setAnchor(jni::JNIEnv& env, jni::String property) { + std::string anchorStr = jni::Make(env, property); + if (anchorStr.compare("map") == 0) { + light.setAnchor(LightAnchorType::Map); + } else if (anchorStr.compare("viewport") == 0) { + light.setAnchor(LightAnchorType::Viewport); + } +} + +jni::String Light::getAnchor(jni::JNIEnv& env) { + auto anchorType = light.getAnchor(); + if (anchorType == LightAnchorType::Map) { + return jni::Make(env, "map"); + } else { + return jni::Make(env, "viewport"); + } +} + +void Light::setPosition(jni::JNIEnv& env, jni::Object jposition) { + using namespace mbgl::android::conversion; + auto position = *convert(env, jposition); + light.setPosition(position); +} + +jni::Object Light::getPosition(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + mbgl::style::Position position = light.getPosition().asConstant(); + return *convert>(env, position); +} + +jni::Object Light::getPositionTransition(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + mbgl::style::TransitionOptions options = light.getPositionTransition(); + return *convert>(env, options); +} + +void Light::setPositionTransition(jni::JNIEnv&, jlong duration, jlong delay) { + mbgl::style::TransitionOptions options; + options.duration.emplace(mbgl::Milliseconds(duration)); + options.delay.emplace(mbgl::Milliseconds(delay)); + light.setPositionTransition(options); +} + +void Light::setColor(jni::JNIEnv& env, jni::String property) { + auto color = Color::parse(jni::Make(env, property)); + if (color) { + light.setColor(color.value()); + } +} + +jni::String Light::getColor(jni::JNIEnv &env) { + auto color = light.getColor().asConstant(); + return jni::Make(env, color.stringify()); +} + +jni::Object Light::getColorTransition(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + mbgl::style::TransitionOptions options = light.getColorTransition(); + return *convert>(env, options); +} + +void Light::setColorTransition(jni::JNIEnv&, jlong duration, jlong delay) { + mbgl::style::TransitionOptions options; + options.duration.emplace(mbgl::Milliseconds(duration)); + options.delay.emplace(mbgl::Milliseconds(delay)); + light.setColorTransition(options); +} + +void Light::setIntensity(jni::JNIEnv&, jni::jfloat property) { + light.setIntensity(property); +} + +jni::jfloat Light::getIntensity(jni::JNIEnv&) { + return light.getIntensity().asConstant(); +} + +jni::Object Light::getIntensityTransition(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + mbgl::style::TransitionOptions options = light.getIntensityTransition(); + return *convert>(env, options); +} + +void Light::setIntensityTransition(jni::JNIEnv&, jlong duration, jlong delay) { + mbgl::style::TransitionOptions options; + options.duration.emplace(mbgl::Milliseconds(duration)); + options.delay.emplace(mbgl::Milliseconds(delay)); + light.setIntensityTransition(options); +} + +void Light::registerNative(jni::JNIEnv& env) { + // Lookup the class + Light::javaClass = *jni::Class::Find(env).NewGlobalRef(env).release(); + +#define METHOD(MethodPtr, name) jni::MakeNativePeerMethod(name) + // Register the peer + jni::RegisterNativePeer(env, Light::javaClass, "nativePtr", + METHOD(&Light::getAnchor, "nativeGetAnchor"), + METHOD(&Light::setAnchor, "nativeSetAnchor"), + METHOD(&Light::getPositionTransition, "nativeGetPositionTransition"), + METHOD(&Light::setPositionTransition, "nativeSetPositionTransition"), + METHOD(&Light::getPosition, "nativeGetPosition"), + METHOD(&Light::setPosition, "nativeSetPosition"), + METHOD(&Light::getColorTransition, "nativeGetColorTransition"), + METHOD(&Light::setColorTransition, "nativeSetColorTransition"), + METHOD(&Light::getColor, "nativeGetColor"), + METHOD(&Light::setColor, "nativeSetColor"), + METHOD(&Light::getIntensityTransition, "nativeGetIntensityTransition"), + METHOD(&Light::setIntensityTransition, "nativeSetIntensityTransition"), + METHOD(&Light::getIntensity, "nativeGetIntensity"), + METHOD(&Light::setIntensity, "nativeSetIntensity")); +} + +} // namespace android +} // namespace mb diff --git a/platform/android/src/style/light.cpp.ejs b/platform/android/src/style/light.cpp.ejs new file mode 100644 index 0000000000..17f0bba09d --- /dev/null +++ b/platform/android/src/style/light.cpp.ejs @@ -0,0 +1,123 @@ +<% + const properties = locals.properties; +-%> +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +#include +#include "light.hpp" +#include "conversion/transition_options.hpp" +#include "conversion/position.hpp" + +namespace mbgl { +namespace android { + +Light::Light(mbgl::Map& coreMap, mbgl::style::Light& coreLight) + : light(coreLight) , map(&coreMap) { +} + +static Light* initializeLightPeer(mbgl::Map& map, mbgl::style::Light& coreLight) { + return new Light(map, coreLight); +} + +jni::jobject* Light::createJavaLightPeer(jni::JNIEnv& env, Map& map, mbgl::style::Light& coreLight) { + std::unique_ptr peerLight = std::unique_ptr(initializeLightPeer(map, coreLight)); + jni::jobject* result = peerLight->createJavaPeer(env); + peerLight.release(); + return result; +} + +jni::Class Light::javaClass; + +jni::jobject* Light::createJavaPeer(jni::JNIEnv& env) { + static auto constructor = Light::javaClass.template GetConstructor(env); + return Light::javaClass.New(env, constructor, reinterpret_cast(this)); +} + +<% for (const property of properties) { -%> +<% if (property.name == "position") { -%> +void Light::set<%- camelize(property.name) %>(jni::JNIEnv& env, jni::Object<<%- camelize(property.name) %>> j<%- property.name %>) { + using namespace mbgl::android::conversion; + auto position = *convert>(env, jposition); + light.set<%- camelize(property.name) %>(<%- property.name %>); +} + +jni::Object Light::get<%- camelize(property.name) %>(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + mbgl::style::<%- camelize(property.name) %> <%- property.name %> = light.get<%- camelize(property.name) %>().asConstant(); + return *convert>>(env, <%- property.name %>); +} +<% } else { -%> +<% if(property.name == "color") {-%> +void Light::set<%- camelize(property.name) %>(jni::JNIEnv& env, jni::<%- propertyJNIType(property) %> property) { + auto color = Color::parse(jni::Make(env, property)); + if (color) { + light.set<%- camelize(property.name) %>(color.value()); + } +} + +jni::String Light::get<%- camelize(property.name) %>(jni::JNIEnv &env) { + auto color = light.get<%- camelize(property.name) %>().asConstant(); + return jni::Make(env, color.stringify()); +} +<% } else if(property.name == "anchor"){ -%> +void Light::set<%- camelize(property.name) %>(jni::JNIEnv& env, jni::<%- propertyJNIType(property) %> property) { + std::string anchorStr = jni::Make(env, property); + if (anchorStr.compare("map") == 0) { + light.setAnchor(LightAnchorType::Map); + } else if (anchorStr.compare("viewport") == 0) { + light.setAnchor(LightAnchorType::Viewport); + } +} + +jni::String Light::getAnchor(jni::JNIEnv& env) { + auto anchorType = light.getAnchor(); + if (anchorType == LightAnchorType::Map) { + return jni::Make(env, "map"); + } else { + return jni::Make(env, "viewport"); + } +} +<% } else { -%> +void Light::set<%- camelize(property.name) %>(jni::JNIEnv&, jni::<%- propertyJNIType(property) %> property) { + light.set<%- camelize(property.name) %>(property); +} + +jni::<%- propertyJNIType(property) %> Light::get<%- camelize(property.name) %>(jni::JNIEnv&) { + return light.get<%- camelize(property.name) %>().asConstant(); +} +<% } -%> +<% } -%> + +<% if (property.transition) { -%> +jni::Object Light::get<%- camelize(property.name) %>Transition(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + mbgl::style::TransitionOptions options = light.get<%- camelize(property.name) %>Transition(); + return *convert>(env, options); +} + +void Light::set<%- camelize(property.name) %>Transition(jni::JNIEnv&, jlong duration, jlong delay) { + mbgl::style::TransitionOptions options; + options.duration.emplace(mbgl::Milliseconds(duration)); + options.delay.emplace(mbgl::Milliseconds(delay)); + light.set<%- camelize(property.name) %>Transition(options); +} + +<% } -%> +<% } -%> +void Light::registerNative(jni::JNIEnv& env) { + // Lookup the class + Light::javaClass = *jni::Class::Find(env).NewGlobalRef(env).release(); + +#define METHOD(MethodPtr, name) jni::MakeNativePeerMethod(name) + // Register the peer + jni::RegisterNativePeer(env, Light::javaClass, "nativePtr",<% for(var i = 0; i < properties.length; i++) {%> +<% if (properties[i].transition) { -%> + METHOD(&Light::get<%- camelize(properties[i].name) %>Transition, "nativeGet<%- camelize(properties[i].name) %>Transition"), + METHOD(&Light::set<%- camelize(properties[i].name) %>Transition, "nativeSet<%- camelize(properties[i].name) %>Transition"), +<% } -%> + METHOD(&Light::get<%- camelize(properties[i].name) %>, "nativeGet<%- camelize(properties[i].name) %>"), + METHOD(&Light::set<%- camelize(properties[i].name) %>, "nativeSet<%- camelize(properties[i].name) %>")<% if(i != (properties.length -1)) {-%>,<% } -%><% } -%>); +} + +} // namespace android +} // namespace mb diff --git a/platform/android/src/style/light.hpp b/platform/android/src/style/light.hpp new file mode 100644 index 0000000000..2c314067be --- /dev/null +++ b/platform/android/src/style/light.hpp @@ -0,0 +1,57 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +#pragma once + +#include + +#include +#include +#include "transition_options.hpp" +#include "position.hpp" +#include +#include + +namespace mbgl { +namespace android { + +using namespace style; + +class Light : private mbgl::util::noncopyable { +public: + + static constexpr auto Name() { return "com/mapbox/mapboxsdk/style/light/Light"; }; + + static jni::Class javaClass; + + static void registerNative(jni::JNIEnv&); + + static jni::jobject* createJavaLightPeer(jni::JNIEnv&, mbgl::Map&, mbgl::style::Light&); + + Light(mbgl::Map&, mbgl::style::Light&); + + void setAnchor(jni::JNIEnv&, jni::String); + jni::String getAnchor(jni::JNIEnv&); + void setPosition(jni::JNIEnv&, jni::Object); + jni::Object getPosition(jni::JNIEnv&); + void setPositionTransition(jni::JNIEnv&, jlong duration, jlong delay); + jni::Object getPositionTransition(jni::JNIEnv&); + void setColor(jni::JNIEnv&, jni::String); + jni::String getColor(jni::JNIEnv&); + void setColorTransition(jni::JNIEnv&, jlong duration, jlong delay); + jni::Object getColorTransition(jni::JNIEnv&); + void setIntensity(jni::JNIEnv&, jni::jfloat); + jni::jfloat getIntensity(jni::JNIEnv&); + void setIntensityTransition(jni::JNIEnv&, jlong duration, jlong delay); + jni::Object getIntensityTransition(jni::JNIEnv&); + jni::jobject* createJavaPeer(jni::JNIEnv&); + +protected: + + // Raw reference to the light + mbgl::style::Light& light; + + // Map is set when the light is retrieved + mbgl::Map* map; +}; +} // namespace android +} // namespace mbgl \ No newline at end of file diff --git a/platform/android/src/style/light.hpp.ejs b/platform/android/src/style/light.hpp.ejs new file mode 100644 index 0000000000..18f961b9e0 --- /dev/null +++ b/platform/android/src/style/light.hpp.ejs @@ -0,0 +1,59 @@ +<% + const properties = locals.properties; +-%> +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +#pragma once + +#include + +#include +#include +#include "transition_options.hpp" +#include "position.hpp" +#include +#include + +namespace mbgl { +namespace android { + +using namespace style; + +class Light : private mbgl::util::noncopyable { +public: + + static constexpr auto Name() { return "com/mapbox/mapboxsdk/style/light/Light"; }; + + static jni::Class javaClass; + + static void registerNative(jni::JNIEnv&); + + static jni::jobject* createJavaLightPeer(jni::JNIEnv&, mbgl::Map&, mbgl::style::Light&); + + Light(mbgl::Map&, mbgl::style::Light&); + +<% for (const property of properties) { -%> +<% if (property.name=="position") {-%> + void set<%- camelize(property.name) %>(jni::JNIEnv&, jni::Object); + jni::Object<<%- camelize(property.name) %>> get<%- camelize(property.name) %>(jni::JNIEnv&); +<% } else { -%> + void set<%- camelize(property.name) %>(jni::JNIEnv&, jni::<%- propertyJNIType(property) %>); + jni::<%- propertyJNIType(property) %> get<%- camelize(property.name) %>(jni::JNIEnv&); +<% } -%> +<% if (property.transition) { -%> + void set<%- camelize(property.name) %>Transition(jni::JNIEnv&, jlong duration, jlong delay); + jni::Object get<%- camelize(property.name) %>Transition(jni::JNIEnv&); +<% } -%> +<% } -%> + jni::jobject* createJavaPeer(jni::JNIEnv&); + +protected: + + // Raw reference to the light + mbgl::style::Light& light; + + // Map is set when the light is retrieved + mbgl::Map* map; +}; +} // namespace android +} // namespace mbgl \ No newline at end of file diff --git a/platform/android/src/style/position.cpp b/platform/android/src/style/position.cpp new file mode 100644 index 0000000000..0bbcefcbcd --- /dev/null +++ b/platform/android/src/style/position.cpp @@ -0,0 +1,34 @@ +#include "position.hpp" + +namespace mbgl { +namespace android { + +jni::Object Position::fromPosition(jni::JNIEnv& env, jfloat radialCoordinate, jfloat azimuthalAngle, jfloat polarAngle) { + static auto method = Position::javaClass.GetStaticMethod (jfloat, jfloat, jfloat)>(env, "fromPosition"); + return Position::javaClass.Call(env, method, radialCoordinate, azimuthalAngle, polarAngle); +} + +void Position::registerNative(jni::JNIEnv& env) { + // Lookup the class + Position::javaClass = *jni::Class::Find(env).NewGlobalRef(env).release(); +} + +jni::Class Position::javaClass; + +float Position::getRadialCoordinate(jni::JNIEnv& env, jni::Object position){ + static auto field = Position::javaClass.GetField(env, "radialCoordinate"); + return position.Get(env, field); +} + +float Position::getAzimuthalAngle(jni::JNIEnv& env, jni::Object position){ + static auto field = Position::javaClass.GetField(env, "azimuthalAngle"); + return position.Get(env, field); +} + +float Position::getPolarAngle(jni::JNIEnv& env, jni::Object position){ + static auto field = Position::javaClass.GetField(env, "polarAngle"); + return position.Get(env, field); +} + +} // namespace andr[oid +} // namespace mbgl \ No newline at end of file diff --git a/platform/android/src/style/position.hpp b/platform/android/src/style/position.hpp new file mode 100644 index 0000000000..4aafa853db --- /dev/null +++ b/platform/android/src/style/position.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include + +#include + +namespace mbgl { +namespace android { + +class Position : private mbgl::util::noncopyable { +public: + + static constexpr auto Name() { return "com/mapbox/mapboxsdk/style/light/Position"; }; + + static jni::Object fromPosition(jni::JNIEnv&, jfloat, jfloat, jfloat); + + static jni::Class javaClass; + + static void registerNative(jni::JNIEnv&); + + static float getRadialCoordinate(jni::JNIEnv&, jni::Object); + static float getAzimuthalAngle(jni::JNIEnv&, jni::Object); + static float getPolarAngle(jni::JNIEnv&, jni::Object); + +}; + + +} // namespace android +} // namespace mbgl \ No newline at end of file -- cgit v1.2.1 From 82a3a7e74681dd0cdae810f28fae70122f306834 Mon Sep 17 00:00:00 2001 From: Pablo Guardiola Date: Fri, 26 May 2017 20:00:40 +0200 Subject: [android] Update Lost to final version 3.0.0 (#9112) * update lost to final version 3.0.0 * bump MAS version to 2.1.1 --- platform/android/dependencies.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/android/dependencies.gradle b/platform/android/dependencies.gradle index eb717ba600..5e80e344e4 100644 --- a/platform/android/dependencies.gradle +++ b/platform/android/dependencies.gradle @@ -7,7 +7,7 @@ ext { versionCode = 11 versionName = "5.0.0" - mapboxServicesVersion = "2.2.0-SNAPSHOT" + mapboxServicesVersion = "2.1.1" supportLibVersion = "25.3.1" wearableVersion = '2.0.0' espressoVersion = '2.2.2' @@ -21,7 +21,7 @@ ext { mapboxAndroidTelemetry : "com.mapbox.mapboxsdk:mapbox-android-telemetry:${mapboxServicesVersion}@aar", // mapzen lost - lost : 'com.mapzen.android:lost:2.3.0-SNAPSHOT', + lost : 'com.mapzen.android:lost:3.0.0', // unit test junit : 'junit:junit:4.12', -- cgit v1.2.1 From bc5b147df79425ec03f2fbe6f3a2566ee45b4800 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 26 May 2017 20:01:57 +0200 Subject: [android] - convert dp to pixels when getting meters per pixel at. (#9048) --- .../src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 008a1971cc..02eeb25f83 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 @@ -621,7 +621,7 @@ final class NativeMapView { if (isDestroyedOn("getMetersPerPixelAtLatitude")) { return 0; } - return nativeGetMetersPerPixelAtLatitude(lat, getZoom()); + return nativeGetMetersPerPixelAtLatitude(lat, getZoom()) / pixelRatio; } public ProjectedMeters projectedMetersForLatLng(LatLng latLng) { -- cgit v1.2.1 From 40a73b390b7e692e8415c98dba267ccefc909357 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 26 May 2017 22:08:54 +0200 Subject: Release Android v5.1.0-beta.3 (#9115) * [android] - Changelog update for Android release v5.1.0-beta.3 * update CI & version * reset release properties --- platform/android/CHANGELOG.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md index bc307e5061..e99276dd20 100644 --- a/platform/android/CHANGELOG.md +++ b/platform/android/CHANGELOG.md @@ -2,8 +2,20 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to do so please see the [`Contributing Guide`](https://github.com/mapbox/mapbox-gl-native/blob/master/CONTRIBUTING.md) first to get started. -## 5.1.0 - TBA +## 5.1.0-beta.3 - May 26, 2017 + +* Add binding support for Light [#9013](https://github.com/mapbox/mapbox-gl-native/pull/9013) * Update attribution with new Mapbox wordmark [#8774](https://github.com/mapbox/mapbox-gl-native/pull/8774) +* LatLngBounds bearing default value [#9102](https://github.com/mapbox/mapbox-gl-native/pull/9102) +* Stop location updates when toggling MyLocationView [#9099](https://github.com/mapbox/mapbox-gl-native/pull/9099) +* Horizontally rotated in snapshot [#9083](https://github.com/mapbox/mapbox-gl-native/pull/9083) +* Disable letter spacing for Arabic text [#9071](https://github.com/mapbox/mapbox-gl-native/pull/9071) +* Correct bearing conversion when animating the map [#9050](https://github.com/mapbox/mapbox-gl-native/pull/9050) +* Don't leak selected markers when removing [#9047](https://github.com/mapbox/mapbox-gl-native/pull/9047) +* Bump tools and support lib version [#9046](https://github.com/mapbox/mapbox-gl-native/pull/9046) +* MarkerView deselect events with OnMarkerViewClickListener [#9047](https://github.com/mapbox/mapbox-gl-native/pull/9047) +* LOST update to v3.0.0 [#9112](https://github.com/mapbox/mapbox-gl-native/pull/9112) +* Convert dp to pixels for meters per pixel at latitude [#9048](https://github.com/mapbox/mapbox-gl-native/pull/9048) ## 5.1.0-beta.2 - May 12, 2017 -- cgit v1.2.1 From fc495dec12a5136f7476aa9d5cb8d76c95024919 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Tue, 30 May 2017 16:56:19 +0200 Subject: [android] - harden orientation changes (#9128) --- .../com/mapbox/mapboxsdk/annotations/Icon.java | 67 +++++++--- .../mapbox/mapboxsdk/annotations/MarkerView.java | 4 + .../com/mapbox/mapboxsdk/maps/IconManager.java | 148 ++++++++++----------- .../com/mapbox/mapboxsdk/maps/NativeMapView.java | 4 - .../com/mapbox/mapboxsdk/annotations/IconTest.java | 2 + 5 files changed, 127 insertions(+), 98 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Icon.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Icon.java index b1a05ec436..2ee17c227d 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Icon.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Icon.java @@ -1,15 +1,18 @@ package com.mapbox.mapboxsdk.annotations; import android.graphics.Bitmap; +import android.util.DisplayMetrics; -import com.mapbox.mapboxsdk.maps.MapView; +import java.nio.ByteBuffer; /** - * Icon is the visual representation of a {@link Marker} on a {@link MapView}. + * Icon is the visual representation of a Marker on a MapView. * * @see Marker + * @see IconFactory */ public class Icon { + private Bitmap mBitmap; private String mId; @@ -19,29 +22,67 @@ public class Icon { } /** - * {@link String} identifier for this {@link Icon}. + * String identifier for this icon. * - * @return {@link String} identifier for this {@link Icon}. + * @return String identifier for this icon. */ public String getId() { return mId; } /** - * Get the {@link Bitmap} being used for this {@link Icon}. + * Get the bitmap being used for this icon. * - * @return The {@link Bitmap} being used for the {@link Icon}. + * @return The bitmap being used for the icon. */ public Bitmap getBitmap() { + if (mBitmap.getConfig() != Bitmap.Config.ARGB_8888) { + mBitmap = mBitmap.copy(Bitmap.Config.ARGB_8888, false); + } return mBitmap; } /** - * Compares this {@link Icon} object with another {@link Icon} and determines if they match. + * Get the icon bitmap scale. + *

+ * Requires the bitmap to be set before calling this method. + *

+ * + * @return the scale of the bitmap + */ + public float getScale() { + if (mBitmap == null) { + throw new IllegalStateException("Required to set a Icon before calling getScale"); + } + float density = mBitmap.getDensity(); + if (density == Bitmap.DENSITY_NONE) { + density = DisplayMetrics.DENSITY_DEFAULT; + } + return density / DisplayMetrics.DENSITY_DEFAULT; + } + + /** + * Get the icon bitmap bytes. + *

+ * Requires the bitmap to be set before calling this method. + *

* - * @param object Another {@link Icon} to compare with this object. - * @return True if the {@link Icon} being passed in matches this {@link Icon} object. Else, - * false. + * @return the bytes of the bitmap + */ + public byte[] toBytes() { + if (mBitmap == null) { + throw new IllegalStateException("Required to set a Icon before calling toBytes"); + } + ByteBuffer buffer = ByteBuffer.allocate(mBitmap.getRowBytes() * mBitmap.getHeight()); + mBitmap.copyPixelsToBuffer(buffer); + return buffer.array(); + } + + /** + * Compares this icon object with another icon and determines if they match. + * + * @param object Another iconi to compare with this object. + * @return True if the icon being passed in matches this icon object. Else, false. */ @Override public boolean equals(Object object) { @@ -53,11 +94,7 @@ public class Icon { } Icon icon = (Icon) object; - - if (!mBitmap.equals(icon.mBitmap)) { - return false; - } - return mId.equals(icon.mId); + return mBitmap.equals(icon.mBitmap) && mId.equals(icon.mId); } /** diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java index 30336d4ebd..56e8cc4ce2 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java @@ -3,6 +3,7 @@ package com.mapbox.mapboxsdk.annotations; import android.support.annotation.FloatRange; import android.support.annotation.Nullable; +import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapboxMap; @@ -361,6 +362,9 @@ public class MarkerView extends Marker { */ @Override public Icon getIcon() { + if (markerViewIcon == null) { + setIcon(IconFactory.getInstance(Mapbox.getApplicationContext()).defaultMarkerView()); + } return markerViewIcon; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java index c9d81a88bc..9f4171aee8 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java @@ -1,15 +1,14 @@ package com.mapbox.mapboxsdk.maps; import android.graphics.Bitmap; -import android.util.DisplayMetrics; +import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.annotations.Icon; import com.mapbox.mapboxsdk.annotations.IconFactory; import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.annotations.MarkerView; import com.mapbox.mapboxsdk.exceptions.IconBitmapChangedException; -import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; @@ -41,118 +40,109 @@ class IconManager { Icon loadIconForMarker(Marker marker) { Icon icon = marker.getIcon(); - - // calculating average before adding - int iconSize = icons.size() + 1; - - // TODO replace former if case with anchor implementation, - // current workaround for having extra pixels is diving height by 2 if (icon == null) { - icon = IconFactory.getInstance(nativeMapView.getContext()).defaultMarker(); - Bitmap bitmap = icon.getBitmap(); - averageIconHeight = averageIconHeight + (bitmap.getHeight() / 2 - averageIconHeight) / iconSize; - averageIconWidth = averageIconWidth + (bitmap.getWidth() - averageIconWidth) / iconSize; - marker.setIcon(icon); - } else { - Bitmap bitmap = icon.getBitmap(); - averageIconHeight = averageIconHeight + (bitmap.getHeight() - averageIconHeight) / iconSize; - averageIconWidth = averageIconWidth + (bitmap.getWidth() - averageIconWidth) / iconSize; - } - - if (!icons.contains(icon)) { - icons.add(icon); - loadIcon(icon); + // TODO replace with anchor implementation, we are faking an anchor by adding extra pixels and diving height by 2 + // TODO we can move this code afterwards to getIcon as with MarkerView.getIcon + icon = loadDefaultIconForMarker(marker); } else { - Icon oldIcon = icons.get(icons.indexOf(icon)); - if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) { - throw new IconBitmapChangedException(); - } + updateAverageIconSize(icon); } + addIcon(icon); return icon; } - Icon loadIconForMarkerView(MarkerView marker) { + void loadIconForMarkerView(MarkerView marker) { Icon icon = marker.getIcon(); - int iconSize = icons.size() + 1; - if (icon == null) { - icon = IconFactory.getInstance(nativeMapView.getContext()).defaultMarkerView(); - marker.setIcon(icon); - } Bitmap bitmap = icon.getBitmap(); - averageIconHeight = averageIconHeight + (bitmap.getHeight() - averageIconHeight) / iconSize; - averageIconWidth = averageIconWidth + (bitmap.getWidth() - averageIconWidth) / iconSize; - if (!icons.contains(icon)) { - icons.add(icon); - } else { - Icon oldIcon = icons.get(icons.indexOf(icon)); - if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) { - throw new IconBitmapChangedException(); - } - } - return icon; + updateAverageIconSize(bitmap); + addIcon(icon, false); } int getTopOffsetPixelsForIcon(Icon icon) { return (int) (nativeMapView.getTopOffsetPixelsForAnnotationSymbol(icon.getId()) * nativeMapView.getPixelRatio()); } - void loadIcon(Icon icon) { + int getAverageIconHeight() { + return averageIconHeight; + } + + int getAverageIconWidth() { + return averageIconWidth; + } + + private Icon loadDefaultIconForMarker(Marker marker) { + Icon icon = IconFactory.getInstance(Mapbox.getApplicationContext()).defaultMarker(); Bitmap bitmap = icon.getBitmap(); - String id = icon.getId(); - if (bitmap.getConfig() != Bitmap.Config.ARGB_8888) { - bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false); - } - ByteBuffer buffer = ByteBuffer.allocate(bitmap.getRowBytes() * bitmap.getHeight()); - bitmap.copyPixelsToBuffer(buffer); + updateAverageIconSize(bitmap.getWidth(), bitmap.getHeight() / 2); + marker.setIcon(icon); + return icon; + } + + private void addIcon(Icon icon) { + addIcon(icon, true); + } - float density = bitmap.getDensity(); - if (density == Bitmap.DENSITY_NONE) { - density = DisplayMetrics.DENSITY_DEFAULT; + private void addIcon(Icon icon, boolean addIconToMap) { + if (!icons.contains(icon)) { + icons.add(icon); + if (addIconToMap) { + loadIcon(icon); + } + } else { + validateIconChanged(icon); } - float scale = density / DisplayMetrics.DENSITY_DEFAULT; - nativeMapView.addAnnotationIcon( - id, + } + + private void updateAverageIconSize(Icon icon) { + updateAverageIconSize(icon.getBitmap()); + } + + private void updateAverageIconSize(Bitmap bitmap) { + updateAverageIconSize(bitmap.getWidth(), bitmap.getHeight()); + } + + private void updateAverageIconSize(int width, int height) { + int iconSize = icons.size() + 1; + averageIconHeight = averageIconHeight + (height - averageIconHeight) / iconSize; + averageIconWidth = averageIconWidth + (width - averageIconWidth) / iconSize; + } + + private void loadIcon(Icon icon) { + Bitmap bitmap = icon.getBitmap(); + nativeMapView.addAnnotationIcon(icon.getId(), bitmap.getWidth(), bitmap.getHeight(), - scale, buffer.array()); + icon.getScale(), + icon.toBytes()); } void reloadIcons() { - int count = icons.size(); - for (int i = 0; i < count; i++) { - Icon icon = icons.get(i); + for (Icon icon : icons) { loadIcon(icon); } } + private void validateIconChanged(Icon icon) { + Icon oldIcon = icons.get(icons.indexOf(icon)); + if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) { + throw new IconBitmapChangedException(); + } + } + void ensureIconLoaded(Marker marker, MapboxMap mapboxMap) { Icon icon = marker.getIcon(); if (icon == null) { - icon = IconFactory.getInstance(nativeMapView.getContext()).defaultMarker(); - marker.setIcon(icon); - } - if (!icons.contains(icon)) { - icons.add(icon); - loadIcon(icon); - } else { - Icon oldIcon = icons.get(icons.indexOf(icon)); - if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) { - throw new IconBitmapChangedException(); - } + icon = loadDefaultIconForMarker(marker); } + addIcon(icon); + setTopOffsetPixels(marker, mapboxMap, icon); + } + private void setTopOffsetPixels(Marker marker, MapboxMap mapboxMap, Icon icon) { // this seems to be a costly operation according to the profiler so I'm trying to save some calls Marker previousMarker = marker.getId() != -1 ? (Marker) mapboxMap.getAnnotation(marker.getId()) : null; if (previousMarker == null || previousMarker.getIcon() == null || previousMarker.getIcon() != marker.getIcon()) { marker.setTopOffsetPixels(getTopOffsetPixelsForIcon(icon)); } } - - int getAverageIconHeight() { - return averageIconHeight; - } - - int getAverageIconWidth() { - return averageIconWidth; - } } 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 02eeb25f83..63f2e653cc 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 @@ -897,10 +897,6 @@ final class NativeMapView { return pixelRatio; } - public Context getContext() { - return mapView.getContext(); - } - // // Callbacks // diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/IconTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/IconTest.java index 5f6f6b6c6d..1c259af2d0 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/IconTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/IconTest.java @@ -9,6 +9,7 @@ import org.mockito.MockitoAnnotations; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotSame; +import static org.mockito.Mockito.when; public class IconTest { @@ -18,6 +19,7 @@ public class IconTest { @Before public void beforeTest() { MockitoAnnotations.initMocks(this); + when(bitmap.getConfig()).thenReturn(Bitmap.Config.ARGB_8888); } @Test -- cgit v1.2.1 From 7b85bcccae5c7b8f3b82135362e16a799413fcc5 Mon Sep 17 00:00:00 2001 From: Jesse Bounds Date: Tue, 30 May 2017 10:51:07 -0700 Subject: [ios] Remove filter of single metric event --- platform/ios/src/MGLMapboxEvents.m | 7 ------- 1 file changed, 7 deletions(-) diff --git a/platform/ios/src/MGLMapboxEvents.m b/platform/ios/src/MGLMapboxEvents.m index 7b28ccf1a8..4f1413d300 100644 --- a/platform/ios/src/MGLMapboxEvents.m +++ b/platform/ios/src/MGLMapboxEvents.m @@ -317,13 +317,6 @@ const NSTimeInterval MGLFlushInterval = 180; return; } - if ([self.eventQueue count] <= 1) { - [self.eventQueue removeAllObjects]; - [[UIApplication sharedApplication] endBackgroundTask:_backgroundTaskIdentifier]; - _backgroundTaskIdentifier = UIBackgroundTaskInvalid; - return; - } - NSArray *events = [NSArray arrayWithArray:self.eventQueue]; [self.eventQueue removeAllObjects]; -- cgit v1.2.1 From 608fd66ab833937671a52d1366caf11a23f7c457 Mon Sep 17 00:00:00 2001 From: Fredrik Karlsson Date: Thu, 25 May 2017 21:42:28 +0200 Subject: [ios] remove layout guide observers --- platform/ios/src/MGLMapView.mm | 100 ++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 56 deletions(-) diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index ed989459f5..39a9281a7a 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -656,21 +656,57 @@ public: _isWaitingForRedundantReachableNotification = NO; } -- (void)dealloc +- (void)willMoveToWindow:(UIWindow *)newWindow { - [_reachability stopNotifier]; + [super willMoveToWindow:newWindow]; + + if (newWindow) { + [self addLayoutGuideObserversIfNeeded]; + } else { + [self removeLayoutGuideObserversIfNeeded]; + } +} - [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [_attributionButton removeObserver:self forKeyPath:@"hidden"]; +- (void)addLayoutGuideObserversIfNeeded +{ + UIViewController *viewController = self.viewControllerForLayoutGuides; + BOOL useLayoutGuides = viewController.view && viewController.automaticallyAdjustsScrollViewInsets; + + if (useLayoutGuides && viewController.topLayoutGuide && !_isObservingTopLayoutGuide) { + [(NSObject *)viewController.topLayoutGuide addObserver:self forKeyPath:@"bounds" options:0 context:(void *)&MGLLayoutGuidesUpdatedContext]; + _isObservingTopLayoutGuide = YES; + } + + if (useLayoutGuides && viewController.bottomLayoutGuide && !_isObservingBottomLayoutGuide) { + [(NSObject *)viewController.bottomLayoutGuide addObserver:self forKeyPath:@"bounds" options:0 context:(void *)&MGLLayoutGuidesUpdatedContext]; + _isObservingBottomLayoutGuide = YES; + } +} +- (void)removeLayoutGuideObserversIfNeeded +{ + UIViewController *viewController = self.viewControllerForLayoutGuides; + if (_isObservingTopLayoutGuide) { - [(NSObject *)self.viewControllerForLayoutGuides.topLayoutGuide removeObserver:self forKeyPath:@"bounds" context:(void *)&MGLLayoutGuidesUpdatedContext]; + [(NSObject *)viewController.topLayoutGuide removeObserver:self forKeyPath:@"bounds" context:(void *)&MGLLayoutGuidesUpdatedContext]; + _isObservingTopLayoutGuide = NO; } if (_isObservingBottomLayoutGuide) { - [(NSObject *)self.viewControllerForLayoutGuides.bottomLayoutGuide removeObserver:self forKeyPath:@"bounds" context:(void *)&MGLLayoutGuidesUpdatedContext]; + [(NSObject *)viewController.bottomLayoutGuide removeObserver:self forKeyPath:@"bounds" context:(void *)&MGLLayoutGuidesUpdatedContext]; + _isObservingBottomLayoutGuide = NO; } +} + +- (void)dealloc +{ + [_reachability stopNotifier]; + + [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [_attributionButton removeObserver:self forKeyPath:@"hidden"]; + + [self removeLayoutGuideObserversIfNeeded]; // Removing the annotations unregisters any outstanding KVO observers. NSArray *annotations = self.annotations; @@ -787,25 +823,7 @@ public: // is set to YES, -[MGLMapView adjustContentInset] takes top and bottom layout // guides into account. To get notified about changes to the layout guides, // we need to observe their bounds and re-layout accordingly. - - UIViewController *viewController = self.viewControllerForLayoutGuides; - BOOL useLayoutGuides = viewController.view && viewController.automaticallyAdjustsScrollViewInsets; - - if (useLayoutGuides && viewController.topLayoutGuide && !_isObservingTopLayoutGuide) { - [(NSObject *)viewController.topLayoutGuide addObserver:self forKeyPath:@"bounds" options:0 context:(void *)&MGLLayoutGuidesUpdatedContext]; - _isObservingTopLayoutGuide = YES; - } else if (!useLayoutGuides && _isObservingTopLayoutGuide) { - [(NSObject *)viewController.topLayoutGuide removeObserver:self forKeyPath:@"bounds" context:(void *)&MGLLayoutGuidesUpdatedContext]; - _isObservingTopLayoutGuide = NO; - } - - if (useLayoutGuides && viewController.bottomLayoutGuide && !_isObservingBottomLayoutGuide) { - [(NSObject *)viewController.bottomLayoutGuide addObserver:self forKeyPath:@"bounds" options:0 context:(void *)&MGLLayoutGuidesUpdatedContext]; - _isObservingBottomLayoutGuide = YES; - } else if (!useLayoutGuides && _isObservingBottomLayoutGuide) { - [(NSObject *)viewController.bottomLayoutGuide removeObserver:self forKeyPath:@"bounds" context:(void *)&MGLLayoutGuidesUpdatedContext]; - _isObservingBottomLayoutGuide = NO; - } + [self addLayoutGuideObserversIfNeeded]; } - (BOOL)isOpaque @@ -839,8 +857,6 @@ public: [self adjustContentInset]; - [self observeLayoutGuidesIfNeeded]; - [self layoutOrnaments]; if (!_isTargetingInterfaceBuilder) { @@ -928,34 +944,6 @@ public: self.contentInset = contentInset; } -- (void)observeLayoutGuidesIfNeeded -{ - UIViewController *viewController = self.viewControllerForLayoutGuides; - BOOL useLayoutGuides = viewController.view && viewController.automaticallyAdjustsScrollViewInsets; - - if (!_isObservingTopLayoutGuide && useLayoutGuides && viewController.topLayoutGuide) - { - [(NSObject *)viewController.topLayoutGuide addObserver:self forKeyPath:@"bounds" options:0 context:MGLLayoutGuidesUpdatedContext]; - _isObservingTopLayoutGuide = YES; - } - else if (!useLayoutGuides && _isObservingTopLayoutGuide) - { - [(NSObject *)viewController.topLayoutGuide removeObserver:self forKeyPath:@"bounds" context:MGLLayoutGuidesUpdatedContext]; - _isObservingTopLayoutGuide = NO; - } - - if (!_isObservingBottomLayoutGuide && useLayoutGuides && viewController.bottomLayoutGuide) - { - [(NSObject *)viewController.bottomLayoutGuide addObserver:self forKeyPath:@"bounds" options:0 context:MGLLayoutGuidesUpdatedContext]; - _isObservingBottomLayoutGuide = YES; - } - else if (!useLayoutGuides && _isObservingBottomLayoutGuide) - { - [(NSObject *)viewController.bottomLayoutGuide removeObserver:self forKeyPath:@"bounds" context:MGLLayoutGuidesUpdatedContext]; - _isObservingBottomLayoutGuide = NO; - } -} - - (void)setContentInset:(UIEdgeInsets)contentInset { [self setContentInset:contentInset animated:NO]; -- cgit v1.2.1 From a39116a552bbb7b77f2946b5931944c7065d818e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Tue, 30 May 2017 15:14:00 -0700 Subject: =?UTF-8?q?Migrate=20to=20GL=20JS=E2=80=93powered=20feedback=20for?= =?UTF-8?q?m=20(#9078)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [ios, macos] Updated feedback URL * [ios, macos] Add referrer, heading, pitch to feedback URL * [ios, macos] Updated changelogs for feedback changes * [ios] Vary referrer by platform --- platform/darwin/src/MGLAttributionInfo.mm | 31 +++++++++++++++++++++--- platform/darwin/src/MGLAttributionInfo_Private.h | 18 ++++++++++++++ platform/darwin/src/MGLOfflineStorage.mm | 14 +++-------- platform/darwin/src/NSBundle+MGLAdditions.h | 2 ++ platform/darwin/src/NSBundle+MGLAdditions.m | 9 +++++++ platform/darwin/test/MGLAttributionInfoTests.m | 12 ++++++++- platform/ios/CHANGELOG.md | 1 + platform/ios/src/MGLMapView.mm | 10 +++++--- platform/macos/CHANGELOG.md | 1 + platform/macos/src/MGLMapView.mm | 15 ++++++++---- 10 files changed, 89 insertions(+), 24 deletions(-) diff --git a/platform/darwin/src/MGLAttributionInfo.mm b/platform/darwin/src/MGLAttributionInfo.mm index 7583244491..770aeb25e7 100644 --- a/platform/darwin/src/MGLAttributionInfo.mm +++ b/platform/darwin/src/MGLAttributionInfo.mm @@ -6,8 +6,10 @@ #import #endif +#import "MGLAccountManager.h" #import "MGLMapCamera.h" #import "NSArray+MGLAdditions.h" +#import "NSBundle+MGLAdditions.h" #import "NSString+MGLAdditions.h" #include @@ -126,13 +128,34 @@ } - (nullable NSURL *)feedbackURLAtCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:(double)zoomLevel { + return [self feedbackURLForStyleURL:nil atCenterCoordinate:centerCoordinate zoomLevel:zoomLevel direction:0 pitch:0]; +} + +- (nullable NSURL *)feedbackURLForStyleURL:(nullable NSURL *)styleURL atCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:(double)zoomLevel direction:(CLLocationDirection)direction pitch:(CGFloat)pitch { if (!self.feedbackLink) { return nil; } - - NSURLComponents *components = [NSURLComponents componentsWithURL:self.URL resolvingAgainstBaseURL:NO]; - components.fragment = [NSString stringWithFormat:@"/%.5f/%.5f/%i", - centerCoordinate.longitude, centerCoordinate.latitude, (int)round(zoomLevel + 1)]; + + NSURLComponents *components = [NSURLComponents componentsWithString:@"https://www.mapbox.com/feedback/"]; + components.fragment = [NSString stringWithFormat:@"/%.5f/%.5f/%.2f/%.1f/%i", + centerCoordinate.longitude, centerCoordinate.latitude, zoomLevel, + direction, (int)round(pitch)]; + + NSURLQueryItem *referrerQueryItem = [NSURLQueryItem queryItemWithName:@"referrer" + value:[NSBundle mgl_applicationBundleIdentifier]]; + NSMutableArray *queryItems = [NSMutableArray arrayWithObject:referrerQueryItem]; + if ([styleURL.scheme isEqualToString:@"mapbox"] && [styleURL.host isEqualToString:@"styles"]) { + NSArray *stylePathComponents = styleURL.pathComponents; + if (stylePathComponents.count >= 3) { + [queryItems addObjectsFromArray:@[ + [NSURLQueryItem queryItemWithName:@"owner" value:stylePathComponents[1]], + [NSURLQueryItem queryItemWithName:@"id" value:stylePathComponents[2]], + [NSURLQueryItem queryItemWithName:@"access_token" value:[MGLAccountManager accessToken]], + ]]; + } + } + components.queryItems = queryItems; + return components.URL; } diff --git a/platform/darwin/src/MGLAttributionInfo_Private.h b/platform/darwin/src/MGLAttributionInfo_Private.h index 08bc6bfc4d..c639752ac3 100644 --- a/platform/darwin/src/MGLAttributionInfo_Private.h +++ b/platform/darwin/src/MGLAttributionInfo_Private.h @@ -20,6 +20,24 @@ NS_ASSUME_NONNULL_BEGIN + (NSAttributedString *)attributedStringForAttributionInfos:(NS_ARRAY_OF(MGLAttributionInfo *) *)attributionInfos; +/** + Returns a copy of the `URL` property modified to account for the given style + URL, center coordinate, and zoom level. + + @param styleURL The map’s style URL. + @param centerCoordinate The map’s center coordinate. + @param zoomLevel The map’s zoom level. See the `MGLMapView.zoomLevel` property + for more information. + @param direction The heading of the map, measured in degrees clockwise from + true north. + @param pitch Pitch toward the horizon measured in degrees, with 0 degrees + resulting in a two-dimensional map. + @return A modified URL containing a fragment that points to the specified + viewport. If the `feedbackLink` property is set to `NO`, this method returns + `nil`. + */ +- (nullable NSURL *)feedbackURLForStyleURL:(nullable NSURL *)styleURL atCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:(double)zoomLevel direction:(CLLocationDirection)direction pitch:(CGFloat)pitch; + @end @interface NSMutableArray (MGLAttributionInfoAdditions) diff --git a/platform/darwin/src/MGLOfflineStorage.mm b/platform/darwin/src/MGLOfflineStorage.mm index 195ef3c36a..81774ad3cb 100644 --- a/platform/darwin/src/MGLOfflineStorage.mm +++ b/platform/darwin/src/MGLOfflineStorage.mm @@ -7,6 +7,7 @@ #import "MGLOfflinePack_Private.h" #import "MGLOfflineRegion_Private.h" #import "MGLTilePyramidOfflineRegion.h" +#import "NSBundle+MGLAdditions.h" #import "NSValue+MGLAdditions.h" #include @@ -132,7 +133,7 @@ NSString * const MGLOfflinePackMaximumCountUserInfoKey = MGLOfflinePackUserInfoK appropriateForURL:nil create:YES error:nil]; - NSString *bundleIdentifier = [self bundleIdentifier]; + NSString *bundleIdentifier = [NSBundle mgl_applicationBundleIdentifier]; if (!bundleIdentifier) { // There’s no main bundle identifier when running in a unit test bundle. bundleIdentifier = [NSBundle bundleForClass:self].bundleIdentifier; @@ -166,7 +167,7 @@ NSString * const MGLOfflinePackMaximumCountUserInfoKey = MGLOfflinePackUserInfoK NSString *legacyCachePath = [legacyPaths.firstObject stringByAppendingPathComponent:MGLOfflineStorageFileName3_2_0_beta_1]; #elif TARGET_OS_MAC // ~/Library/Caches/tld.app.bundle.id/offline.db - NSString *bundleIdentifier = [self bundleIdentifier]; + NSString *bundleIdentifier = [NSBundle mgl_applicationBundleIdentifier]; NSURL *legacyCacheDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory inDomain:NSUserDomainMask appropriateForURL:nil @@ -219,15 +220,6 @@ NSString * const MGLOfflinePackMaximumCountUserInfoKey = MGLOfflinePackUserInfoK return self; } -+ (NSString *)bundleIdentifier { - NSString *bundleIdentifier = [NSBundle mainBundle].bundleIdentifier; - if (!bundleIdentifier) { - // There’s no main bundle identifier when running in a unit test bundle. - bundleIdentifier = [NSBundle bundleForClass:self].bundleIdentifier; - } - return bundleIdentifier; -} - - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; [[MGLNetworkConfiguration sharedManager] removeObserver:self forKeyPath:@"apiBaseURL"]; diff --git a/platform/darwin/src/NSBundle+MGLAdditions.h b/platform/darwin/src/NSBundle+MGLAdditions.h index df70d23923..ad5e9d5369 100644 --- a/platform/darwin/src/NSBundle+MGLAdditions.h +++ b/platform/darwin/src/NSBundle+MGLAdditions.h @@ -36,6 +36,8 @@ NS_ASSUME_NONNULL_BEGIN + (nullable NS_DICTIONARY_OF(NSString *, id) *)mgl_frameworkInfoDictionary; ++ (nullable NSString *)mgl_applicationBundleIdentifier; + @end NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/NSBundle+MGLAdditions.m b/platform/darwin/src/NSBundle+MGLAdditions.m index ad122831ba..f383a50300 100644 --- a/platform/darwin/src/NSBundle+MGLAdditions.m +++ b/platform/darwin/src/NSBundle+MGLAdditions.m @@ -31,4 +31,13 @@ return bundle.infoDictionary; } ++ (nullable NSString *)mgl_applicationBundleIdentifier { + NSString *bundleIdentifier = [NSBundle mainBundle].bundleIdentifier; + if (!bundleIdentifier) { + // There’s no main bundle identifier when running in a unit test bundle. + bundleIdentifier = [NSBundle bundleForClass:[MGLAccountManager class]].bundleIdentifier; + } + return bundleIdentifier; +} + @end diff --git a/platform/darwin/test/MGLAttributionInfoTests.m b/platform/darwin/test/MGLAttributionInfoTests.m index e258671c09..ed4927d44b 100644 --- a/platform/darwin/test/MGLAttributionInfoTests.m +++ b/platform/darwin/test/MGLAttributionInfoTests.m @@ -46,8 +46,18 @@ XCTAssertEqualObjects(infos[3].title.string, @"Improve this map"); XCTAssertEqualObjects(infos[3].URL, [NSURL URLWithString:@"https://www.mapbox.com/map-feedback/"]); XCTAssertTrue(infos[3].feedbackLink); + NSURL *styleURL = [MGLStyle satelliteStreetsStyleURLWithVersion:99]; +#if TARGET_OS_IPHONE + XCTAssertEqualObjects([infos[3] feedbackURLAtCenterCoordinate:mapbox zoomLevel:14], + [NSURL URLWithString:@"https://www.mapbox.com/feedback/?referrer=com.mapbox.sdk.ios#/77.63680/12.98108/14.00/0.0/0"]); + XCTAssertEqualObjects([infos[3] feedbackURLForStyleURL:styleURL atCenterCoordinate:mapbox zoomLevel:3.14159 direction:90.9 pitch:12.5], + [NSURL URLWithString:@"https://www.mapbox.com/feedback/?referrer=com.mapbox.sdk.ios&owner=mapbox&id=satellite-streets-v99&access_token#/77.63680/12.98108/3.14/90.9/13"]); +#else XCTAssertEqualObjects([infos[3] feedbackURLAtCenterCoordinate:mapbox zoomLevel:14], - [NSURL URLWithString:@"https://www.mapbox.com/map-feedback/#/77.63680/12.98108/15"]); + [NSURL URLWithString:@"https://www.mapbox.com/feedback/?referrer=com.mapbox.MapboxGL#/77.63680/12.98108/14.00/0.0/0"]); + XCTAssertEqualObjects([infos[3] feedbackURLForStyleURL:styleURL atCenterCoordinate:mapbox zoomLevel:3.14159 direction:90.9 pitch:12.5], + [NSURL URLWithString:@"https://www.mapbox.com/feedback/?referrer=com.mapbox.MapboxGL&owner=mapbox&id=satellite-streets-v99&access_token#/77.63680/12.98108/3.14/90.9/13"]); +#endif } - (void)testStyle { diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 9caec9c0d7..7228a94649 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -37,6 +37,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Fixed an issue where gesture recognizers associated with map view interactivity were not disabled when their related interactions were disabled. ([#8304](https://github.com/mapbox/mapbox-gl-native/pull/8304)) * Fixed an issue preventing the Mapbox Telemetry confirmation dialog from appearing when opened from within a map view in a modal view controller. ([#9027](https://github.com/mapbox/mapbox-gl-native/pull/9027)) * Corrected the size of MGLMapView’s compass. ([#9060](https://github.com/mapbox/mapbox-gl-native/pull/9060)) +* The Improve This Map button in the attribution action sheet now leads to a feedback tool that matches MGLMapView’s rotation and pitch. `-[MGLAttributionInfo feedbackURLAtCenterCoordinate:zoomLevel:]` no longer respects the feedback URL specified in TileJSON. ([#9078](https://github.com/mapbox/mapbox-gl-native/pull/9078)) ### Other changes diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 39a9281a7a..9d4c295d62 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -64,7 +64,7 @@ #import "MGLCompactCalloutView.h" #import "MGLAnnotationContainerView.h" #import "MGLAnnotationContainerView_Private.h" -#import "MGLAttributionInfo.h" +#import "MGLAttributionInfo_Private.h" #include #include @@ -1895,8 +1895,12 @@ public: { if (info.feedbackLink) { - url = [info feedbackURLAtCenterCoordinate:self.centerCoordinate - zoomLevel:self.zoomLevel]; + MGLMapCamera *camera = self.camera; + url = [info feedbackURLForStyleURL:self.styleURL + atCenterCoordinate:camera.centerCoordinate + zoomLevel:self.zoomLevel + direction:camera.heading + pitch:camera.pitch]; } [[UIApplication sharedApplication] openURL:url]; } diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index ca08811c0a..fc4e88b08f 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -25,6 +25,7 @@ * Fixed a crash when calling `MGLMultiPolygon.coordinate` [#8713](https://github.com/mapbox/mapbox-gl-native/pull/8713) * Fixed an issue causing attribution button text to appear blue instead of black. ([#8701](https://github.com/mapbox/mapbox-gl-native/pull/8701)) * Fixed a crash or console spew when MGLMapView is initialized with a frame smaller than 64 points wide by 64 points tall. ([#8562](https://github.com/mapbox/mapbox-gl-native/pull/8562)) +* The Improve This Map button in the attribution action sheet now leads to a feedback tool that matches MGLMapView’s rotation and pitch. `-[MGLAttributionInfo feedbackURLAtCenterCoordinate:zoomLevel:]` no longer respects the feedback URL specified in TileJSON. ([#9078](https://github.com/mapbox/mapbox-gl-native/pull/9078)) * The error passed into `-[MGLMapViewDelegate mapViewDidFailLoadingMap:withError:]` now includes a more specific description and failure reason. ([#8418](https://github.com/mapbox/mapbox-gl-native/pull/8418)) * The `MGLPolyline.coordinate` and `MGLPolygon.coordinate` properties now return the midpoint and centroid, respectively, instead of the first coordinate. ([#8713](https://github.com/mapbox/mapbox-gl-native/pull/8713)) * Improved CPU and battery performance while animating a tilted map’s camera in an area with many labels. ([#9031](https://github.com/mapbox/mapbox-gl-native/pull/9031)) diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index a36766b745..3e91a6c5a5 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -1,17 +1,18 @@ #import "MGLMapView_Private.h" -#import "MGLAnnotationImage_Private.h" + #import "MGLAttributionButton.h" -#import "MGLAttributionInfo.h" #import "MGLCompassCell.h" #import "MGLOpenGLLayer.h" #import "MGLStyle.h" +#import "MGLAnnotationImage_Private.h" +#import "MGLAttributionInfo_Private.h" #import "MGLFeature_Private.h" +#import "MGLFoundation_Private.h" #import "MGLGeometry_Private.h" #import "MGLMultiPoint_Private.h" #import "MGLOfflineStorage_Private.h" #import "MGLStyle_Private.h" -#import "MGLFoundation_Private.h" #import "MGLAccountManager.h" #import "MGLMapCamera.h" @@ -1735,11 +1736,15 @@ public: } - (IBAction)giveFeedback:(id)sender { - CLLocationCoordinate2D centerCoordinate = self.centerCoordinate; + MGLMapCamera *camera = self.camera; double zoomLevel = self.zoomLevel; NSMutableArray *urls = [NSMutableArray array]; for (MGLAttributionInfo *info in [self.style attributionInfosWithFontSize:0 linkColor:nil]) { - NSURL *url = [info feedbackURLAtCenterCoordinate:centerCoordinate zoomLevel:zoomLevel]; + NSURL *url = [info feedbackURLForStyleURL:self.styleURL + atCenterCoordinate:camera.centerCoordinate + zoomLevel:zoomLevel + direction:camera.heading + pitch:camera.pitch]; if (url) { [urls addObject:url]; } -- cgit v1.2.1 From 83df8a8621287e548ee771599c9c98b61b9971a3 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Wed, 31 May 2017 09:46:12 +0200 Subject: [android] - javadoc update for 5.1.0 release (#9138) * [android] - javadoc update for 5.1.0 release * oxford comma * Grammar/spelling tweaks * grammar tweak * grammar tweak * Grammar tweaks * Grammar tweaks --- .../src/main/java/com/mapbox/mapboxsdk/Mapbox.java | 33 ++++++++---- .../mapbox/mapboxsdk/camera/CameraPosition.java | 4 +- .../mapboxsdk/camera/CameraUpdateFactory.java | 2 +- .../mapboxsdk/constants/MyBearingTracking.java | 4 +- .../mapboxsdk/constants/MyLocationTracking.java | 4 +- .../java/com/mapbox/mapboxsdk/constants/Style.java | 2 +- .../mapbox/mapboxsdk/location/LocationSource.java | 53 +++++++++++++++++-- .../mapboxsdk/maps/FocalPointChangeListener.java | 3 ++ .../java/com/mapbox/mapboxsdk/maps/MapboxMap.java | 6 +-- .../mapbox/mapboxsdk/offline/OfflineManager.java | 4 +- .../mapbox/mapboxsdk/offline/OfflineRegion.java | 2 +- .../com/mapbox/mapboxsdk/storage/Resource.java | 6 +++ .../style/functions/CompositeFunction.java | 2 +- .../com/mapbox/mapboxsdk/style/layers/Filter.java | 2 +- .../mapboxsdk/style/layers/TransitionOptions.java | 28 ++++++++++ .../mapbox/mapboxsdk/style/light/package-info.java | 4 ++ .../com/mapbox/mapboxsdk/utils/AnimatorUtils.java | 59 ++++++++++++++++++++++ .../com/mapbox/mapboxsdk/utils/ColorUtils.java | 3 ++ 18 files changed, 188 insertions(+), 33 deletions(-) create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/package-info.java diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java index 8098ee4d86..f75d7ed90d 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java @@ -1,5 +1,6 @@ package com.mapbox.mapboxsdk; +import android.app.Application; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; @@ -15,6 +16,14 @@ import com.mapbox.services.android.telemetry.MapboxTelemetry; import com.mapbox.services.android.telemetry.location.LocationEngine; import com.mapbox.services.android.telemetry.location.LocationEnginePriority; +/** + * The entry point of the Mapbox Android SDK. + *

+ * Obtain a reference by calling {@link #getInstance(Context, String)}. Usually this class is configured in + * {@link Application#onCreate()} and is responsible for the active access token, application context, and + * connectivity state. + *

+ */ public final class Mapbox { private static Mapbox INSTANCE; @@ -25,7 +34,7 @@ public final class Mapbox { /** * Get an instance of Mapbox. *

- * This class manages the active access token, application context and connectivity state. + * This class manages the active access token, application context, and connectivity state. *

* * @param context Android context which holds or is an application context @@ -52,9 +61,9 @@ public final class Mapbox { } /** - * Access Token for this application. + * Access token for this application. * - * @return Mapbox Access Token + * @return Mapbox access token */ public static String getAccessToken() { validateMapbox(); @@ -72,12 +81,14 @@ public final class Mapbox { } /** - * Runtime validation of Access Token. + * Runtime validation of access token. * * @throws MapboxConfigurationException exception thrown when not using a valid accessToken */ private static void validateAccessToken() throws MapboxConfigurationException { - String accessToken = INSTANCE.accessToken; + String + + = INSTANCE.accessToken; if (TextUtils.isEmpty(accessToken) || (!accessToken.toLowerCase(MapboxConstants.MAPBOX_LOCALE).startsWith("pk.") && !accessToken.toLowerCase(MapboxConstants.MAPBOX_LOCALE).startsWith("sk."))) { throw new MapboxConfigurationException(); @@ -92,11 +103,11 @@ public final class Mapbox { } /** - * Manually sets the connectivity state of the app. This is useful for apps that control their + * Manually sets the connectivity state of the app. This is useful for apps which control their * own connectivity state and want to bypass any checks to the ConnectivityManager. * * @param connected flag to determine the connectivity state, true for connected, false for - * disconnected, null for ConnectivityManager to determine. + * disconnected, and null for ConnectivityManager to determine. */ public static synchronized void setConnected(Boolean connected) { // Connectivity state overridden by app @@ -104,10 +115,10 @@ public final class Mapbox { } /** - * Determines whether we have an Internet connection available. Please do not rely on this - * method in your apps, this method is used internally by the SDK. + * Determines whether we have an internet connection available. Please do not rely on this + * method in your apps. This method is used internally by the SDK. * - * @return true if there is an Internet connection, false otherwise + * @return true if there is an internet connection, false otherwise */ public static synchronized Boolean isConnected() { if (INSTANCE.connected != null) { @@ -119,4 +130,4 @@ public final class Mapbox { NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); return (activeNetwork != null && activeNetwork.isConnected()); } -} \ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java index 5e958ff565..66c261f1d0 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java @@ -156,7 +156,7 @@ public final class CameraPosition implements Parcelable { } /** - * Builder for composing {@link CameraPosition} objects. + * Builder for composing CameraPosition objects. */ public static final class Builder { @@ -190,7 +190,7 @@ public final class CameraPosition implements Parcelable { /** * Create Builder with an existing CameraPosition data. * - * @param typedArray TypedArray containgin attribute values + * @param typedArray TypedArray containing attribute values */ public Builder(TypedArray typedArray) { super(); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java index 64b86054a0..8e1411e273 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java @@ -15,7 +15,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** - * Factory for creating {@link CameraUpdate} objects. + * Factory for creating CameraUpdate objects. */ public final class CameraUpdateFactory { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java index f53c65d055..88c3bef673 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java @@ -16,7 +16,7 @@ import java.lang.annotation.RetentionPolicy; public class MyBearingTracking { /** - * Indicates the parameter accepts one of the values from {@link MyBearingTracking}. + * Indicates that the parameter accepts one of the values from MyBearingTracking. */ @IntDef( {NONE, COMPASS, GPS, /**COMBINED**/}) @Retention(RetentionPolicy.SOURCE) @@ -38,6 +38,4 @@ public class MyBearingTracking { */ public static final int GPS = 0x00000008; - // public static final int COMBINED = 0x00000012; - } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java index 39f653596f..a1744d701f 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java @@ -17,7 +17,7 @@ import java.lang.annotation.RetentionPolicy; public class MyLocationTracking { /** - * Indicates the parameter accepts one of the values from {@link MyLocationTracking}. + * Indicates the parameter accepts one of the values from MyLocationTracking. */ @IntDef( {TRACKING_NONE, TRACKING_FOLLOW}) @Retention(RetentionPolicy.SOURCE) @@ -30,7 +30,7 @@ public class MyLocationTracking { public static final int TRACKING_NONE = 0x00000000; /** - * Tracking the location of the user, {@link MapView} will reposition to center of {@link MyLocationView} + * Tracking the location of the user. {@link MapView} will reposition to center of {@link MyLocationView} */ public static final int TRACKING_FOLLOW = 0x00000004; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java index 77d0929df3..31e6313509 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java @@ -19,7 +19,7 @@ public class Style { /** - * Indicates the parameter accepts one of the values from {@link Style}. Using one of these + * Indicates the parameter accepts one of the values from Style. Using one of these * constants means your map style will always use the latest version and may change as we * improve the style */ diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java index c4bdb4a17d..4e934fa3cc 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java @@ -2,7 +2,7 @@ package com.mapbox.mapboxsdk.location; import android.content.Context; import android.location.Location; -import android.util.Log; +import android.support.annotation.NonNull; import com.mapbox.services.android.telemetry.location.LocationEngine; import com.mapbox.services.android.telemetry.location.LocationEngineListener; @@ -15,6 +15,8 @@ import com.mapzen.android.lost.api.LostApiClient; import java.lang.ref.WeakReference; +import timber.log.Timber; + /** * Manages locational updates. Contains methods to register and unregister location listeners. *
    @@ -33,8 +35,6 @@ import java.lang.ref.WeakReference; public class LocationSource extends LocationEngine implements LostApiClient.ConnectionCallbacks, LocationListener { - private static final String LOG_TAG = LocationSource.class.getSimpleName(); - private static LocationEngine instance; private WeakReference context; @@ -48,7 +48,13 @@ public class LocationSource extends LocationEngine implements .build(); } - public static synchronized LocationEngine getLocationEngine(Context context) { + /** + * Get the LocationEngine instance. + * + * @param context a Context from which the application context is derived + * @return the LocationEngine instance + */ + public static synchronized LocationEngine getLocationEngine(@NonNull Context context) { if (instance == null) { instance = new LocationSource(context.getApplicationContext()); } @@ -56,6 +62,10 @@ public class LocationSource extends LocationEngine implements return instance; } + /** + * Activate the location engine which will connect whichever location provider you are using. You'll need to call + * this before requesting user location updates using {@link LocationEngine#requestLocationUpdates()}. + */ @Override public void activate() { if (lostApiClient != null && !lostApiClient.isConnected()) { @@ -63,6 +73,11 @@ public class LocationSource extends LocationEngine implements } } + /** + * Disconnect the location engine which is useful when you no longer need location updates or requesting the users + * {@link LocationEngine#getLastLocation()}. Before deactivating, you'll need to stop request user location updates + * using {@link LocationEngine#removeLocationUpdates()}. + */ @Override public void deactivate() { if (lostApiClient != null && lostApiClient.isConnected()) { @@ -70,11 +85,20 @@ public class LocationSource extends LocationEngine implements } } + /** + * Check if your location provider has been activated/connected. This is mainly used internally but is also useful in + * the rare case when you'd like to know if your location engine is connected or not. + * + * @return boolean true if the location engine has been activated/connected, else false. + */ @Override public boolean isConnected() { return lostApiClient.isConnected(); } + /** + * Invoked when the location provider has connected. + */ @Override public void onConnected() { for (LocationEngineListener listener : locationListeners) { @@ -82,11 +106,19 @@ public class LocationSource extends LocationEngine implements } } + /** + * Invoked when the location provider connection has been suspended. + */ @Override public void onConnectionSuspended() { - Log.d(LOG_TAG, "Connection suspended."); + Timber.d("Connection suspended."); } + /** + * Returns the Last known location is the location provider is connected and location permissions are granted. + * + * @return the last known location + */ @Override public Location getLastLocation() { if (lostApiClient.isConnected() && PermissionsManager.areLocationPermissionsGranted(context.get())) { @@ -97,6 +129,9 @@ public class LocationSource extends LocationEngine implements return null; } + /** + * Request location updates to the location provider. + */ @Override public void requestLocationUpdates() { // Common params @@ -122,6 +157,9 @@ public class LocationSource extends LocationEngine implements } } + /** + * Dismiss ongoing location update to the location provider. + */ @Override public void removeLocationUpdates() { if (lostApiClient.isConnected()) { @@ -129,6 +167,11 @@ public class LocationSource extends LocationEngine implements } } + /** + * Invoked when the Location has changed. + * + * @param location the new location + */ @Override public void onLocationChanged(Location location) { for (LocationEngineListener listener : locationListeners) { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/FocalPointChangeListener.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/FocalPointChangeListener.java index 006122a4e2..aec9a848b7 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/FocalPointChangeListener.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/FocalPointChangeListener.java @@ -2,6 +2,9 @@ package com.mapbox.mapboxsdk.maps; import android.graphics.PointF; +/** + * Interface definition of a callback that is invoked when the focal point will change. + */ public interface FocalPointChangeListener { void onFocalPointChanged(PointF pointF); 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 0bfa74d1c0..0ba6c10831 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 @@ -1972,9 +1972,9 @@ public final class MapboxMap { /** * Interface definition for a callback to be invoked when the camera changes position. * - * @deprecated Replaced by MapboxMap.OnCameraMoveStartedListener, MapboxMap.OnCameraMoveListener and - * MapboxMap.OnCameraIdleListener. The order in which the deprecated onCameraChange method will be called in relation - * to the methods in the new camera change listeners is undefined. + * @deprecated Replaced by {@link MapboxMap.OnCameraMoveStartedListener}, {@link MapboxMap.OnCameraMoveListener} and + * {@link MapboxMap.OnCameraIdleListener}. The order in which the deprecated onCameraChange method will be called in + * relation to the methods in the new camera change listeners is undefined. */ @Deprecated public interface OnCameraChangeListener { 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 225278b17d..95cb7d66c4 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 @@ -46,7 +46,7 @@ public class OfflineManager { /** * This callback receives an asynchronous response containing a list of all - * {@link OfflineRegion} in the database, or an error message otherwise. + * OfflineRegion in the database or an error message otherwise. */ public interface ListOfflineRegionsCallback { /** @@ -66,7 +66,7 @@ public class OfflineManager { /** * This callback receives an asynchronous response containing the newly created - * {@link OfflineRegion} in the database, or an error message otherwise. + * OfflineRegion in the database or an error message otherwise. */ public interface CreateOfflineRegionCallback { /** diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java index 44bb2a05ee..baa815491f 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java @@ -98,7 +98,7 @@ public class OfflineRegion { } /** - * This callback receives an asynchronous response containing the {@link OfflineRegionStatus} + * This callback receives an asynchronous response containing the OfflineRegionStatus * of the offline region, or a {@link String} error message otherwise. */ public interface OfflineRegionStatusCallback { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/Resource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/Resource.java index af98a46a9b..eae83e8c1f 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/Resource.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/Resource.java @@ -5,9 +5,15 @@ import android.support.annotation.IntDef; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +/** + * Resource provides access to resource types. + */ public final class Resource { // Note: Keep this in sync with include/mbgl/storage/resource.hpp + /** + * Resource type variants. + */ @IntDef( {UNKNOWN, STYLE, SOURCE, TILE, GLYPHS, SPRITE_IMAGE, SPRITE_JSON}) @Retention(RetentionPolicy.SOURCE) public @interface Kind { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/CompositeFunction.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/CompositeFunction.java index 8ded7ecd34..15e4474105 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/CompositeFunction.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/CompositeFunction.java @@ -13,7 +13,7 @@ import com.mapbox.mapboxsdk.style.layers.PropertyValue; import java.util.Map; /** - * Composite functions combine {@link android.graphics.Camera} and {@link SourceFunction}s. + * Composite functions combine Camera and SourceFunctions. *

    * Composite functions allow the appearance of a map feature to change with both its * properties and zoom. Each stop is an array with two elements, the first is an object diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Filter.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Filter.java index 643a126388..4dbb461e4c 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Filter.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Filter.java @@ -11,7 +11,7 @@ import java.util.Collections; public class Filter { /** - * Base {@link Filter} statement. Subclassed to provide concrete statements. + * Base Filter statement. Subclassed to provide concrete statements. */ public abstract static class Statement { protected final String operator; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/TransitionOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/TransitionOptions.java index a46c11b35c..6e6e4ca613 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/TransitionOptions.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/TransitionOptions.java @@ -1,23 +1,51 @@ package com.mapbox.mapboxsdk.style.layers; +/** + * Resembles transition property from the style specification. + * + * @see Transition documentation + */ public class TransitionOptions { private long duration; private long delay; + /** + * Create a transition property based on duration and a delay. + * + * @param duration the duration of the transition + * @param delay the delay to start the transition + */ public TransitionOptions(long duration, long delay) { this.duration = duration; this.delay = delay; } + /** + * Create a transition property based on duration and a delay. + * + * @param duration the duration of the transition + * @param delay the delay to start the transition + * @return a new transition property object + */ public static TransitionOptions fromTransitionOptions(long duration, long delay) { return new TransitionOptions(duration, delay); } + /** + * Get the transition duration. + * + * @return the transition duration + */ public long getDuration() { return duration; } + /** + * Get the transition delay. + * + * @return the transition delay + */ public long getDelay() { return delay; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/package-info.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/package-info.java new file mode 100644 index 0000000000..a613bf9587 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/package-info.java @@ -0,0 +1,4 @@ +/** + * Contains the Mapbox Maps Android Style Light API classes. + */ +package com.mapbox.mapboxsdk.style.light; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/AnimatorUtils.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/AnimatorUtils.java index 7694604d9f..34c52c829b 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/AnimatorUtils.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/AnimatorUtils.java @@ -10,13 +10,31 @@ import android.support.annotation.Nullable; import android.support.v4.view.animation.FastOutSlowInInterpolator; import android.view.View; +/** + * Animator utility class. + */ public class AnimatorUtils { + /** + * Animate a view from an animator resource. + * + * @param view the view to be animated + * @param animatorRes the animator resource to be loaded + * @param listener the animator end listener + */ public static void animate(@NonNull final View view, @AnimatorRes int animatorRes, @Nullable OnAnimationEndListener listener) { animate(view, animatorRes, -1, listener); } + /** + * Animate a view from an animator resource. + * + * @param view the view to be animated + * @param animatorRes the animator resource to be loaded + * @param duration the duration of the animator + * @param listener the animator end listener + */ public static void animate(final View view, @AnimatorRes int animatorRes, int duration, @Nullable final OnAnimationEndListener listener) { if (view == null) { @@ -43,14 +61,33 @@ public class AnimatorUtils { animator.start(); } + /** + * Animate a view from an animator resource. + * + * @param view the view to be animated + * @param animatorRes the animator resource to be loaded + */ public static void animate(@NonNull final View view, @AnimatorRes int animatorRes) { animate(view, animatorRes, -1); } + /** + * Animate a view from an animator resource. + * + * @param view the view to be animated + * @param animatorRes the animator resource to be loaded + * @param duration the duration of the animator + */ public static void animate(@NonNull final View view, @AnimatorRes int animatorRes, int duration) { animate(view, animatorRes, duration, null); } + /** + * Animate a view rotation property to a value. + * + * @param view the view to be rotated + * @param rotation the value to animate to + */ public static void rotate(@NonNull final View view, float rotation) { view.setLayerType(View.LAYER_TYPE_HARDWARE, null); ObjectAnimator rotateAnimator = ObjectAnimator.ofFloat(view, View.ROTATION, view.getRotation(), rotation); @@ -64,6 +101,12 @@ public class AnimatorUtils { rotateAnimator.start(); } + /** + * Animate a view rotation property by a value. + * + * @param view the view to be rotated + * @param rotationBy the value to animate by + */ public static void rotateBy(@NonNull final View view, float rotationBy) { view.setLayerType(View.LAYER_TYPE_HARDWARE, null); view.animate().rotationBy(rotationBy).setInterpolator(new FastOutSlowInInterpolator()).setListener( @@ -76,6 +119,13 @@ public class AnimatorUtils { }); } + /** + * Animate a view alpha property to a value. + * + * @param convertView the view to be animated + * @param alpha the value to animate to + * @param listener the animator end listener + */ public static void alpha(@NonNull final View convertView, float alpha, @Nullable final OnAnimationEndListener listener) { convertView.setLayerType(View.LAYER_TYPE_HARDWARE, null); @@ -99,10 +149,19 @@ public class AnimatorUtils { rotateAnimator.start(); } + /** + * Animate a view alpha property to a value. + * + * @param convertView the view to be animated + * @param alpha the value to animate to + */ public static void alpha(@NonNull final View convertView, float alpha) { alpha(convertView, alpha, null); } + /** + * An interface definition that is invoked when an animation ends. + */ public interface OnAnimationEndListener { void onAnimationEnd(); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ColorUtils.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ColorUtils.java index 2da2472d69..24c76243d9 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ColorUtils.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ColorUtils.java @@ -17,6 +17,9 @@ import com.mapbox.mapboxsdk.exceptions.ConversionException; import java.util.regex.Matcher; import java.util.regex.Pattern; +/** + * Color utility class. + */ public class ColorUtils { /** -- cgit v1.2.1 From b6a4f1212cbf7454134a1e3f367d2e47db305a15 Mon Sep 17 00:00:00 2001 From: Pablo Guardiola Date: Wed, 31 May 2017 12:59:01 +0200 Subject: [android] fix missing access token variable issue (#9151) --- .../MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java index f75d7ed90d..81134e9497 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java @@ -86,9 +86,7 @@ public final class Mapbox { * @throws MapboxConfigurationException exception thrown when not using a valid accessToken */ private static void validateAccessToken() throws MapboxConfigurationException { - String - - = INSTANCE.accessToken; + String accessToken = INSTANCE.accessToken; if (TextUtils.isEmpty(accessToken) || (!accessToken.toLowerCase(MapboxConstants.MAPBOX_LOCALE).startsWith("pk.") && !accessToken.toLowerCase(MapboxConstants.MAPBOX_LOCALE).startsWith("sk."))) { throw new MapboxConfigurationException(); -- cgit v1.2.1 From af2547776acc0302d2fcfb45661198872348a980 Mon Sep 17 00:00:00 2001 From: Fabian Guerra Date: Wed, 31 May 2017 13:41:09 -0400 Subject: [ios] Update pods spec for iOS v3.6.0-beta.2 --- platform/ios/Mapbox-iOS-SDK-symbols.podspec | 2 +- platform/ios/Mapbox-iOS-SDK.podspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/ios/Mapbox-iOS-SDK-symbols.podspec b/platform/ios/Mapbox-iOS-SDK-symbols.podspec index c94b349b8c..3116ede9f5 100644 --- a/platform/ios/Mapbox-iOS-SDK-symbols.podspec +++ b/platform/ios/Mapbox-iOS-SDK-symbols.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |m| - version = '3.6.0-beta.1' + version = '3.6.0-beta.2' m.name = 'Mapbox-iOS-SDK-symbols' m.version = "#{version}-symbols" diff --git a/platform/ios/Mapbox-iOS-SDK.podspec b/platform/ios/Mapbox-iOS-SDK.podspec index 0d464de400..f6bc3030ab 100644 --- a/platform/ios/Mapbox-iOS-SDK.podspec +++ b/platform/ios/Mapbox-iOS-SDK.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |m| - version = '3.6.0-beta.1' + version = '3.6.0-beta.2' m.name = 'Mapbox-iOS-SDK' m.version = version -- cgit v1.2.1 From 52eba423aecca51dd65c15d2d3dbffe2f06856ba Mon Sep 17 00:00:00 2001 From: Pablo Guardiola Date: Thu, 1 Jun 2017 10:05:31 +0200 Subject: [android] Cherry picking 9133 (#9145) * [android] Fix tracking mode + camera race condition (#9133) * [android] fix tracking mode + camera race condition * fix resetTrackingModesIfRequired bug (comparing current camera position with target camera position * cherry pick #9133 and update CHANGELOG * add null check to prevent null pointer exception --- platform/android/CHANGELOG.md | 5 ++ .../mapboxsdk/constants/MapboxConstants.java | 1 - .../mapbox/mapboxsdk/maps/MapGestureDetector.java | 8 ++-- .../java/com/mapbox/mapboxsdk/maps/MapboxMap.java | 30 +++++++++++- .../mapbox/mapboxsdk/maps/TrackingSettings.java | 54 ++++++---------------- .../java/com/mapbox/mapboxsdk/maps/Transform.java | 9 ++-- .../mapboxsdk/maps/widgets/MyLocationView.java | 49 ++------------------ 7 files changed, 62 insertions(+), 94 deletions(-) diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md index e99276dd20..22bede23f6 100644 --- a/platform/android/CHANGELOG.md +++ b/platform/android/CHANGELOG.md @@ -2,6 +2,11 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to do so please see the [`Contributing Guide`](https://github.com/mapbox/mapbox-gl-native/blob/master/CONTRIBUTING.md) first to get started. +## 5.1.0-rc.1 - TBA + +* Fix tracking mode + camera race condition [#9133](https://github.com/mapbox/mapbox-gl-native/pull/9133) +* Harden orientation changes [#9128](https://github.com/mapbox/mapbox-gl-native/pull/9128) + ## 5.1.0-beta.3 - May 26, 2017 * Add binding support for Light [#9013](https://github.com/mapbox/mapbox-gl-native/pull/9013) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java index 9adefa3221..ecb6ffe24e 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java @@ -113,7 +113,6 @@ public class MapboxConstants { public static final String STATE_MY_BEARING_TRACKING_MODE = "mapbox_myBearingTracking"; public static final String STATE_MY_LOCATION_TRACKING_DISMISS = "mapbox_myLocationTrackingDismiss"; public static final String STATE_MY_BEARING_TRACKING_DISMISS = "mapbox_myBearingTrackingDismiss"; - public static final String STATE_MY_TRACKING_MODE_DISMISS_FOR_CAMERA = "mapbox_myBearingTrackingDismiss"; public static final String STATE_COMPASS_ENABLED = "mapbox_compassEnabled"; public static final String STATE_COMPASS_GRAVITY = "mapbox_compassGravity"; public static final String STATE_COMPASS_MARGIN_LEFT = "mapbox_compassMarginLeft"; 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 39433d8b93..e60f9b1d1e 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 @@ -357,7 +357,7 @@ final class MapGestureDetector { return false; } - trackingSettings.resetTrackingModesIfRequired(true, false); + trackingSettings.resetTrackingModesIfRequired(true, false, false); // cancel any animation transform.cancelTransitions(); @@ -402,7 +402,7 @@ final class MapGestureDetector { } // reset tracking if needed - trackingSettings.resetTrackingModesIfRequired(true, false); + trackingSettings.resetTrackingModesIfRequired(true, false, false); // Scroll the map transform.moveBy(-distanceX, -distanceY, 0 /*no duration*/); @@ -484,7 +484,7 @@ final class MapGestureDetector { // to be in the center of the map. Therefore the zoom will translate the map center, so tracking // should be disabled. - trackingSettings.resetTrackingModesIfRequired(!quickZoom, false); + trackingSettings.resetTrackingModesIfRequired(!quickZoom, false, false); // Scale the map if (focalPoint != null) { // arround user provided focal point @@ -568,7 +568,7 @@ final class MapGestureDetector { } // rotation constitutes translation of anything except the center of // rotation, so cancel both location and bearing tracking if required - trackingSettings.resetTrackingModesIfRequired(true, true); + trackingSettings.resetTrackingModesIfRequired(true, true, false); // Get rotate value double bearing = transform.getRawBearing(); 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 0ba6c10831..7a62f06ad2 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 @@ -746,10 +746,38 @@ public final class MapboxMap { @UiThread public final void easeCamera(final CameraUpdate update, final int durationMs, final boolean easingInterpolator, final MapboxMap.CancelableCallback callback) { + easeCamera(update, durationMs, easingInterpolator, callback, false); + } + + /** + * Gradually move the camera by a specified duration in milliseconds, zoom will not be affected + * unless specified within {@link CameraUpdate}. A callback can be used to be notified when + * easing the camera stops. If {@link #getCameraPosition()} is called during the animation, it + * will return the current location of the camera in flight. + *

    + * Note that this will cancel location tracking mode if enabled. You can change this behaviour by calling + * {@link TrackingSettings#setDismissTrackingModeForCameraPositionChange(boolean)} with false before invoking this + * method and calling it with true in the {@link CancelableCallback#onFinish()}. + *

    + * + * @param update The change that should be applied to the camera. + * @param durationMs The duration of the animation in milliseconds. This must be strictly + * positive, otherwise an IllegalArgumentException will be thrown. + * @param easingInterpolator True for easing interpolator, false for linear. + * @param callback An optional callback to be notified from the main thread when the animation + * stops. If the animation stops due to its natural completion, the callback + * will be notified with onFinish(). If the animation stops due to interruption + * by a later camera movement or a user gesture, onCancel() will be called. + * Do not update or ease the camera from within onCancel(). + * @param isDismissable true will allow animated camera changes dismiss a tracking mode. + */ + @UiThread + public final void easeCamera(final CameraUpdate update, final int durationMs, final boolean easingInterpolator, + final MapboxMap.CancelableCallback callback, final boolean isDismissable) { new Handler().post(new Runnable() { @Override public void run() { - transform.easeCamera(MapboxMap.this, update, durationMs, easingInterpolator, callback); + transform.easeCamera(MapboxMap.this, update, durationMs, easingInterpolator, callback, isDismissable); } }); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java index 25b60aa72d..7dcd84de75 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java @@ -33,7 +33,6 @@ public final class TrackingSettings { private boolean myLocationEnabled; private boolean dismissLocationTrackingOnGesture = true; private boolean dismissBearingTrackingOnGesture = true; - private boolean isResetTrackingWithCameraPositionChange = true; private MapboxMap.OnMyLocationTrackingModeChangeListener onMyLocationTrackingModeChangeListener; private MapboxMap.OnMyBearingTrackingModeChangeListener onMyBearingTrackingModeChangeListener; @@ -57,8 +56,6 @@ public final class TrackingSettings { outState.putBoolean(MapboxConstants.STATE_MY_LOCATION_TRACKING_DISMISS, isDismissLocationTrackingOnGesture()); outState.putBoolean(MapboxConstants.STATE_MY_BEARING_TRACKING_DISMISS, isDismissBearingTrackingOnGesture()); outState.putBoolean(MapboxConstants.STATE_MY_LOCATION_ENABLED, isMyLocationEnabled()); - outState.putBoolean(MapboxConstants.STATE_MY_TRACKING_MODE_DISMISS_FOR_CAMERA, - isDismissTrackingModesForCameraPositionChange()); } void onRestoreInstanceState(Bundle savedInstanceState) { @@ -77,8 +74,6 @@ public final class TrackingSettings { MapboxConstants.STATE_MY_LOCATION_TRACKING_DISMISS, true)); setDismissBearingTrackingOnGesture(savedInstanceState.getBoolean( MapboxConstants.STATE_MY_BEARING_TRACKING_DISMISS, true)); - setDismissTrackingModeForCameraPositionChange(savedInstanceState.getBoolean( - MapboxConstants.STATE_MY_TRACKING_MODE_DISMISS_FOR_CAMERA, true)); } /** @@ -259,15 +254,16 @@ public final class TrackingSettings { } /** - * Reset the tracking modes as necessary. Location tracking is reset if the map center is changed, - * bearing tracking if there is a rotation. + * Reset the tracking modes as necessary. Location tracking is reset if the map center is changed and not from + * location, bearing tracking if there is a rotation. * - * @param translate true if translation - * @param rotate true if rotation + * @param translate true if translation + * @param rotate true if rotation + * @param isFromLocation true if from location */ - void resetTrackingModesIfRequired(boolean translate, boolean rotate) { + void resetTrackingModesIfRequired(boolean translate, boolean rotate, boolean isFromLocation) { // if tracking is on, and we should dismiss tracking with gestures, and this is a scroll action, turn tracking off - if (translate && !isLocationTrackingDisabled() && isDismissLocationTrackingOnGesture()) { + if (translate && !isLocationTrackingDisabled() && isDismissLocationTrackingOnGesture() && !isFromLocation) { setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE); } @@ -280,38 +276,18 @@ public final class TrackingSettings { /** * Reset the tracking modes as necessary. Animated camera position changes can reset the underlying tracking modes. * - * @param cameraPosition the changed camera position + * @param currentCameraPosition the current camera position + * @param targetCameraPosition the changed camera position + * @param isFromLocation true if from location */ - void resetTrackingModesIfRequired(CameraPosition cameraPosition) { - if (isDismissTrackingModesForCameraPositionChange()) { - resetTrackingModesIfRequired(cameraPosition.target != null, false); + void resetTrackingModesIfRequired(CameraPosition currentCameraPosition, CameraPosition targetCameraPosition, + boolean isFromLocation) { + if (currentCameraPosition.target != null) { + resetTrackingModesIfRequired(!currentCameraPosition.target.equals(targetCameraPosition.target), false, + isFromLocation); } } - /** - * Returns if a animation allows to dismiss a tracking mode. - *

    - * By default this is set to true. - *

    - * - * @return True if camera animations will allow to dismiss a tracking mode - */ - public boolean isDismissTrackingModesForCameraPositionChange() { - return isResetTrackingWithCameraPositionChange; - } - - /** - * Sets a flag to allow animated camera position changes to dismiss a tracking mode. - *

    - *

    - *

    - * - * @param willAllowToDismiss True will allow animated camera changes dismiss a trackig mode - */ - public void setDismissTrackingModeForCameraPositionChange(boolean willAllowToDismiss) { - isResetTrackingWithCameraPositionChange = willAllowToDismiss; - } - Location getMyLocation() { return myLocationView.getLocation(); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java index af44a08a81..7f44e0de07 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java @@ -94,7 +94,7 @@ final class Transform implements MapView.OnMapChangedListener { final void moveCamera(MapboxMap mapboxMap, CameraUpdate update, MapboxMap.CancelableCallback callback) { CameraPosition cameraPosition = update.getCameraPosition(mapboxMap); if (!cameraPosition.equals(this.cameraPosition)) { - trackingSettings.resetTrackingModesIfRequired(cameraPosition); + trackingSettings.resetTrackingModesIfRequired(this.cameraPosition, cameraPosition, false); cancelTransitions(); cameraChangeDispatcher.onCameraMoveStarted(OnCameraMoveStartedListener.REASON_API_ANIMATION); mapView.jumpTo(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, cameraPosition.zoom); @@ -107,10 +107,10 @@ final class Transform implements MapView.OnMapChangedListener { @UiThread final void easeCamera(MapboxMap mapboxMap, CameraUpdate update, int durationMs, boolean easingInterpolator, - final MapboxMap.CancelableCallback callback) { + final MapboxMap.CancelableCallback callback, boolean isDismissable) { CameraPosition cameraPosition = update.getCameraPosition(mapboxMap); if (!cameraPosition.equals(this.cameraPosition)) { - trackingSettings.resetTrackingModesIfRequired(cameraPosition); + trackingSettings.resetTrackingModesIfRequired(this.cameraPosition, cameraPosition, isDismissable); cancelTransitions(); cameraChangeDispatcher.onCameraMoveStarted(OnCameraMoveStartedListener.REASON_API_ANIMATION); @@ -118,7 +118,6 @@ final class Transform implements MapView.OnMapChangedListener { cameraCancelableCallback = callback; mapView.addOnMapChangedListener(this); } - mapView.easeTo(cameraPosition.bearing, cameraPosition.target, durationMs, cameraPosition.tilt, cameraPosition.zoom, easingInterpolator); } @@ -129,7 +128,7 @@ final class Transform implements MapView.OnMapChangedListener { final MapboxMap.CancelableCallback callback) { CameraPosition cameraPosition = update.getCameraPosition(mapboxMap); if (!cameraPosition.equals(this.cameraPosition)) { - trackingSettings.resetTrackingModesIfRequired(cameraPosition); + trackingSettings.resetTrackingModesIfRequired(this.cameraPosition, cameraPosition, false); cancelTransitions(); cameraChangeDispatcher.onCameraMoveStarted(OnCameraMoveStartedListener.REASON_API_ANIMATION); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java index 338d29c87c..f5ef46a5d3 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java @@ -485,19 +485,8 @@ public class MyLocationView extends View { if (location != null) { if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) { // center map directly - mapboxMap.getTrackingSettings().setDismissTrackingModeForCameraPositionChange(false); mapboxMap.easeCamera(CameraUpdateFactory.newLatLng(new LatLng(location)), 0, false /*linear interpolator*/, - new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - - } - - @Override - public void onFinish() { - mapboxMap.getTrackingSettings().setDismissTrackingModeForCameraPositionChange(true); - } - }); + null, true); } else { // do not use interpolated location from tracking mode latLng = null; @@ -663,19 +652,8 @@ public class MyLocationView extends View { private void rotateCamera(float rotation) { CameraPosition.Builder builder = new CameraPosition.Builder(); builder.bearing(rotation); - mapboxMap.getTrackingSettings().setDismissTrackingModeForCameraPositionChange(false); mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(builder.build()), COMPASS_UPDATE_RATE_MS, - false /*linear interpolator*/, new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - - } - - @Override - public void onFinish() { - mapboxMap.getTrackingSettings().setDismissTrackingModeForCameraPositionChange(true); - } - }); + false /*linear interpolator*/, null); } @Override @@ -750,7 +728,7 @@ public class MyLocationView extends View { abstract void invalidate(); } - private class MyLocationTrackingBehavior extends MyLocationBehavior implements MapboxMap.CancelableCallback { + private class MyLocationTrackingBehavior extends MyLocationBehavior { @Override void updateLatLng(@NonNull Location location) { @@ -789,10 +767,9 @@ public class MyLocationView extends View { // accuracy updateAccuracy(location); - // disable dismiss of tracking settings, enabled in #onFinish - mapboxMap.getTrackingSettings().setDismissTrackingModeForCameraPositionChange(false); // ease to new camera position with a linear interpolator - mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(builder.build()), animationDuration, false, this); + mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(builder.build()), animationDuration, false, null, + true); } @Override @@ -803,22 +780,6 @@ public class MyLocationView extends View { screenLocation = new PointF(x, y); MyLocationView.this.invalidate(); } - - @Override - public void onCancel() { - //no op - } - - @Override - public void onFinish() { - // Posting to end message queue to avoid race condition #8560 - post(new Runnable() { - @Override - public void run() { - mapboxMap.getTrackingSettings().setDismissTrackingModeForCameraPositionChange(true); - } - }); - } } private class MyLocationShowBehavior extends MyLocationBehavior { -- cgit v1.2.1 From b2f277ac620cc41883dad8e06bb45458c18ffe72 Mon Sep 17 00:00:00 2001 From: Pablo Guardiola Date: Thu, 1 Jun 2017 14:10:18 +0200 Subject: add null check in custom location engine activity to prevent null pointer exception (#9159) --- .../mapboxsdk/testapp/activity/userlocation/MockLocationEngine.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MockLocationEngine.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MockLocationEngine.java index b87c723fda..b02b35b0d0 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MockLocationEngine.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MockLocationEngine.java @@ -63,7 +63,9 @@ public class MockLocationEngine extends LocationEngine { @Override public void removeLocationUpdates() { - handler.removeCallbacksAndMessages(null); + if (handler != null) { + handler.removeCallbacksAndMessages(null); + } } private Location getNextLocation() { -- cgit v1.2.1 From 0d171dbe0e2d172190c21f98fb2cc4a1819ed9a2 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Thu, 1 Jun 2017 00:58:03 +0300 Subject: [core] Make TransformState LatLngBounds optional --- include/mbgl/map/map.hpp | 4 ++-- src/mbgl/map/map.cpp | 4 ++-- src/mbgl/map/transform.cpp | 7 ++++--- src/mbgl/map/transform.hpp | 2 +- src/mbgl/map/transform_state.cpp | 17 +++++++++++------ src/mbgl/map/transform_state.hpp | 7 ++++--- test/map/transform.test.cpp | 10 +++++++--- 7 files changed, 31 insertions(+), 20 deletions(-) diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index 1c0c2c544b..8072eda7dd 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -109,8 +109,8 @@ public: void resetZoom(); // Bounds - void setLatLngBounds(const LatLngBounds&); - LatLngBounds getLatLngBounds() const; + void setLatLngBounds(optional); + optional getLatLngBounds() const; void setMinZoom(double); double getMinZoom() const; void setMaxZoom(double); diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 52ac323df4..181370dc14 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -620,11 +620,11 @@ void Map::resetZoom() { #pragma mark - Bounds -LatLngBounds Map::getLatLngBounds() const { +optional Map::getLatLngBounds() const { return impl->transform.getState().getLatLngBounds(); } -void Map::setLatLngBounds(const LatLngBounds& bounds) { +void Map::setLatLngBounds(optional bounds) { impl->cameraMutated = true; impl->transform.setLatLngBounds(bounds); impl->onUpdate(Update::Repaint); diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp index 9f3a2a83d2..20e29db6ac 100644 --- a/src/mbgl/map/transform.cpp +++ b/src/mbgl/map/transform.cpp @@ -406,10 +406,11 @@ double Transform::getZoom() const { #pragma mark - Bounds -void Transform::setLatLngBounds(const LatLngBounds& bounds) { - if (bounds.valid()) { - state.setLatLngBounds(bounds); +void Transform::setLatLngBounds(optional bounds) { + if (bounds && !bounds->valid()) { + throw std::runtime_error("failed to set bounds: bounds are invalid"); } + state.setLatLngBounds(bounds); } void Transform::setMinZoom(const double minZoom) { diff --git a/src/mbgl/map/transform.hpp b/src/mbgl/map/transform.hpp index af2f821602..749228bdf5 100644 --- a/src/mbgl/map/transform.hpp +++ b/src/mbgl/map/transform.hpp @@ -56,7 +56,7 @@ public: // Bounds - void setLatLngBounds(const LatLngBounds&); + void setLatLngBounds(optional); void setMinZoom(double); void setMaxZoom(double); void setMinPitch(double); diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp index 8c3c70feec..bbf7e22b31 100644 --- a/src/mbgl/map/transform_state.cpp +++ b/src/mbgl/map/transform_state.cpp @@ -142,12 +142,14 @@ double TransformState::getZoomFraction() const { #pragma mark - Bounds -void TransformState::setLatLngBounds(const LatLngBounds& bounds_) { - bounds = bounds_; - setLatLngZoom(getLatLng(LatLng::Unwrapped), getZoom()); +void TransformState::setLatLngBounds(optional bounds_) { + if (bounds_ != bounds) { + bounds = bounds_; + setLatLngZoom(getLatLng(LatLng::Unwrapped), getZoom()); + } } -LatLngBounds TransformState::getLatLngBounds() const { +optional TransformState::getLatLngBounds() const { return bounds; } @@ -350,8 +352,11 @@ void TransformState::moveLatLng(const LatLng& latLng, const ScreenCoordinate& an setLatLngZoom(Projection::unproject(centerCoord + latLngCoord - anchorCoord, scale), getZoom()); } -void TransformState::setLatLngZoom(const LatLng &latLng, double zoom) { - const LatLng constrained = bounds.constrain(latLng); +void TransformState::setLatLngZoom(const LatLng& latLng, double zoom) { + LatLng constrained = latLng; + if (bounds) { + constrained = bounds->constrain(latLng); + } double newScale = zoomScale(zoom); const double newWorldSize = newScale * util::tileSize; diff --git a/src/mbgl/map/transform_state.hpp b/src/mbgl/map/transform_state.hpp index d0bf455ead..e6464aeacc 100644 --- a/src/mbgl/map/transform_state.hpp +++ b/src/mbgl/map/transform_state.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -50,8 +51,8 @@ public: double getZoomFraction() const; // Bounds - void setLatLngBounds(const LatLngBounds&); - LatLngBounds getLatLngBounds() const; + void setLatLngBounds(optional); + optional getLatLngBounds() const; void setMinZoom(double); double getMinZoom() const; void setMaxZoom(double); @@ -89,7 +90,7 @@ private: bool rotatedNorth() const; void constrain(double& scale, double& x, double& y) const; - LatLngBounds bounds = LatLngBounds::world(); + optional bounds; // Limit the amount of zooming possible on the map. double min_scale = std::pow(2, 0); diff --git a/test/map/transform.test.cpp b/test/map/transform.test.cpp index 40cae09d8b..aa49d250b6 100644 --- a/test/map/transform.test.cpp +++ b/test/map/transform.test.cpp @@ -537,12 +537,16 @@ TEST(Transform, LatLngBounds) { transform.setLatLngZoom({ 0, 0 }, transform.getState().getMaxZoom()); // Default bounds. - ASSERT_EQ(transform.getState().getLatLngBounds(), LatLngBounds::world()); + ASSERT_EQ(transform.getState().getLatLngBounds(), optional {}); ASSERT_EQ(transform.getLatLng(), nullIsland); // Invalid bounds. - transform.setLatLngBounds(LatLngBounds::empty()); - ASSERT_EQ(transform.getState().getLatLngBounds(), LatLngBounds::world()); + try { + transform.setLatLngBounds(LatLngBounds::empty()); + ASSERT_TRUE(false) << "Should throw"; + } catch (...) { + ASSERT_EQ(transform.getState().getLatLngBounds(), optional {}); + } transform.setLatLng(sanFrancisco); ASSERT_EQ(transform.getLatLng(), sanFrancisco); -- cgit v1.2.1 From 012e88cc9b069f62824d9072ca3ede6a3c37d04b Mon Sep 17 00:00:00 2001 From: Jesse Bounds Date: Thu, 1 Jun 2017 10:53:02 -0700 Subject: [ios] Make annotation view rotation alignment configurable (#9147) This commit adds `rotatesWithMap` property on `MGLAnnotationView`. This property, when set to `YES` fixes the annotation to a map such that view follows map's rotation angle. This is useful when user wants to display rotation-dependent annotations (e.g. sector lights). --- platform/ios/CHANGELOG.md | 1 + platform/ios/src/MGLAnnotationView.h | 13 +++++++++++++ platform/ios/src/MGLAnnotationView.mm | 24 ++++++++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 7228a94649..c57063707a 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -26,6 +26,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT ### Annotations * Added a new initializer to `MGLAnnotationView` so that it is possible to create a new instance with an associated annotation object. ([#9029](https://github.com/mapbox/mapbox-gl-native/pull/9029)) +* Added a new `rotatesToMatchCamera` property to `MGLAnnotationView` that, when set to true, causes the annotation view to rotate along with the map's rotation angle giving the appearance that the annoation view is pinned to the map. ([#9147](https://github.com/mapbox/mapbox-gl-native/pull/9147)) * Fixed an issue causing a view-backed annotation to disappear immediately instead of animating when the annotation’s `coordinate` property is set to a value outside the current viewport. ([#8565](https://github.com/mapbox/mapbox-gl-native/pull/8565)) * Fixed an issue in which `MGLMapView` overrode the tint colors of its annotation views. ([#8789](https://github.com/mapbox/mapbox-gl-native/pull/8789)) * Fixed an issue causing annotation views to persist in the map’s annotation container view even after their associated annotations were removed. ([#9025](https://github.com/mapbox/mapbox-gl-native/pull/9025)) diff --git a/platform/ios/src/MGLAnnotationView.h b/platform/ios/src/MGLAnnotationView.h index 9b17f05a6e..2802d31b05 100644 --- a/platform/ios/src/MGLAnnotationView.h +++ b/platform/ios/src/MGLAnnotationView.h @@ -171,6 +171,19 @@ typedef NS_ENUM(NSUInteger, MGLAnnotationViewDragState) { */ @property (nonatomic, assign) BOOL scalesWithViewingDistance; +/** + A Boolean value that determines whether the annotation view rotates together + with the map. + + When the value of this property is `YES` and the map is rotated, the annotation + view rotates. This is also the behavior of `MGLAnnotationImage` objects. When the + value of this property is `NO` the annotation has its rotation angle fixed. + + The default value of this property is `NO`. Set this property to `YES` if the + view’s rotation is important. + */ +@property (nonatomic, assign) BOOL rotatesToMatchCamera; + #pragma mark Managing the Selection State /** diff --git a/platform/ios/src/MGLAnnotationView.mm b/platform/ios/src/MGLAnnotationView.mm index 78e38f10cb..94d0649413 100644 --- a/platform/ios/src/MGLAnnotationView.mm +++ b/platform/ios/src/MGLAnnotationView.mm @@ -11,6 +11,7 @@ @property (nonatomic, readwrite, nullable) NSString *reuseIdentifier; @property (nonatomic, readwrite) CATransform3D lastAppliedScaleTransform; +@property (nonatomic, readwrite) CATransform3D lastAppliedRotateTransform; @property (nonatomic, weak) UIPanGestureRecognizer *panGestureRecognizer; @property (nonatomic, weak) UILongPressGestureRecognizer *longPressRecognizer; @property (nonatomic, weak) MGLMapView *mapView; @@ -53,6 +54,7 @@ _annotation = [decoder decodeObjectOfClass:[NSObject class] forKey:@"annotation"]; _centerOffset = [decoder decodeCGVectorForKey:@"centerOffset"]; _scalesWithViewingDistance = [decoder decodeBoolForKey:@"scalesWithViewingDistance"]; + _rotatesToMatchCamera = [decoder decodeBoolForKey:@"rotatesToMatchCamera"]; _selected = [decoder decodeBoolForKey:@"selected"]; _enabled = [decoder decodeBoolForKey:@"enabled"]; self.draggable = [decoder decodeBoolForKey:@"draggable"]; @@ -66,6 +68,7 @@ [coder encodeObject:_annotation forKey:@"annotation"]; [coder encodeCGVector:_centerOffset forKey:@"centerOffset"]; [coder encodeBool:_scalesWithViewingDistance forKey:@"scalesWithViewingDistance"]; + [coder encodeBool:_rotatesToMatchCamera forKey:@"rotatesToMatchCamera"]; [coder encodeBool:_selected forKey:@"selected"]; [coder encodeBool:_enabled forKey:@"enabled"]; [coder encodeBool:_draggable forKey:@"draggable"]; @@ -109,6 +112,7 @@ super.center = center; [self updateScaleTransformForViewingDistance]; + [self updateRotateTransform]; } - (void)setScalesWithViewingDistance:(BOOL)scalesWithViewingDistance @@ -157,6 +161,26 @@ } } +- (void)setRotatesToMatchCamera:(BOOL)rotatesToMatchCamera +{ + if (_rotatesToMatchCamera != rotatesToMatchCamera) + { + _rotatesToMatchCamera = rotatesToMatchCamera; + [self updateRotateTransform]; + } +} + +- (void)updateRotateTransform +{ + if (self.rotatesToMatchCamera == NO) return; + + CGFloat directionRad = self.mapView.direction * M_PI / 180.0; + CATransform3D newRotateTransform = CATransform3DMakeRotation(-directionRad, 0, 0, 1); + self.layer.transform = CATransform3DConcat(CATransform3DIdentity, newRotateTransform); + + _lastAppliedRotateTransform = newRotateTransform; +} + #pragma mark - Draggable - (void)setDraggable:(BOOL)draggable -- cgit v1.2.1 From da532007043b1827e83686faca0de2a45c4ef730 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 2 Jun 2017 12:39:35 +0200 Subject: [android] - validate if gestures should execute (#9173) --- .../com/mapbox/mapboxsdk/maps/MapGestureDetector.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) 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 e60f9b1d1e..33e13c5ecc 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 @@ -383,6 +383,14 @@ final class MapGestureDetector { // Called for drags @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { + if (!trackingSettings.isScrollGestureCurrentlyEnabled()) { + return false; + } + + if (dragStarted) { + return false; + } + if (!scrollInProgress) { scrollInProgress = true; @@ -393,13 +401,6 @@ final class MapGestureDetector { getLocationFromGesture(e1.getX(), e1.getY()), MapboxEvent.GESTURE_PAN_START, transform)); } - if (!trackingSettings.isScrollGestureCurrentlyEnabled()) { - return false; - } - - if (dragStarted) { - return false; - } // reset tracking if needed trackingSettings.resetTrackingModesIfRequired(true, false, false); -- cgit v1.2.1 From ef7b3552b52002c153a0b93a87d27f8b5d378f4f Mon Sep 17 00:00:00 2001 From: Tobrun Date: Tue, 6 Jun 2017 12:13:56 +0200 Subject: [android] - only invoke callback if fling scrolling animation isn't going to be ignored. (#9192) --- .../main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java | 3 ++- .../src/main/java/com/mapbox/mapboxsdk/maps/Transform.java | 7 +++---- 2 files changed, 5 insertions(+), 5 deletions(-) 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 33e13c5ecc..5346baa4e2 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 @@ -346,7 +346,6 @@ final class MapGestureDetector { // and ignore when a scale gesture has occurred return false; } - cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); float screenDensity = uiSettings.getPixelRatio(); @@ -362,6 +361,8 @@ final class MapGestureDetector { // cancel any animation transform.cancelTransitions(); + cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); + // tilt results in a bigger translation, limiting input for #5281 double tilt = transform.getTilt(); double tiltFactor = 1 + ((tilt != 0) ? (tilt / 10) : 0); /* 1 -> 7 */ diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java index 7f44e0de07..9a8997014a 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java @@ -79,7 +79,7 @@ final class Transform implements MapView.OnMapChangedListener { @Override public void onMapChanged(@MapView.MapChange int change) { - if (change == REGION_DID_CHANGE_ANIMATED && cameraCancelableCallback != null) { + if (change == REGION_DID_CHANGE_ANIMATED) { updateCameraPosition(invalidateCameraPosition()); if (cameraCancelableCallback != null) { cameraCancelableCallback.onFinish(); @@ -116,8 +116,8 @@ final class Transform implements MapView.OnMapChangedListener { if (callback != null) { cameraCancelableCallback = callback; - mapView.addOnMapChangedListener(this); } + mapView.addOnMapChangedListener(this); mapView.easeTo(cameraPosition.bearing, cameraPosition.target, durationMs, cameraPosition.tilt, cameraPosition.zoom, easingInterpolator); } @@ -134,9 +134,8 @@ final class Transform implements MapView.OnMapChangedListener { if (callback != null) { cameraCancelableCallback = callback; - mapView.addOnMapChangedListener(this); } - + mapView.addOnMapChangedListener(this); mapView.flyTo(cameraPosition.bearing, cameraPosition.target, durationMs, cameraPosition.tilt, cameraPosition.zoom); } -- cgit v1.2.1 From a1f8de66794f665b69c35ed163b3e554dc5db348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Tue, 6 Jun 2017 12:15:21 +0200 Subject: [android] - dealing with infinite camera move callbacks (#9177) (#9194) --- .../main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java index f5ef46a5d3..098f006f6c 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java @@ -701,6 +701,12 @@ public class MyLocationView extends View { private abstract class MyLocationBehavior { + MyLocationBehavior() { + if (latLng != null) { + locationUpdateTimestamp = SystemClock.elapsedRealtime(); + } + } + void updateLatLng(@NonNull Location newLocation) { location = newLocation; } -- cgit v1.2.1 From 45327b6ac46f8b574a767e20ee6a18ab23936db6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Tue, 6 Jun 2017 21:09:20 +0200 Subject: [android] - keep location tracking mode after screen rotation (#9187) * [android] - keep location tracking mode after screen rotation (#9186) * [android] - using easeCamera to keep location tracking instead of overloaded moveCamera (#9187) * [android] - checkstyle fix up --- .../src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) 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 7a62f06ad2..8e50adb777 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 @@ -141,12 +141,20 @@ public final class MapboxMap { */ void onRestoreInstanceState(Bundle savedInstanceState) { final CameraPosition cameraPosition = savedInstanceState.getParcelable(MapboxConstants.STATE_CAMERA_POSITION); - if (cameraPosition != null) { - moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder(cameraPosition).build())); - } uiSettings.onRestoreInstanceState(savedInstanceState); trackingSettings.onRestoreInstanceState(savedInstanceState); + + if (cameraPosition != null) { + easeCamera(CameraUpdateFactory.newCameraPosition( + new CameraPosition.Builder(cameraPosition).build()), + 0, + false, + null, + !trackingSettings.isLocationTrackingDisabled() + ); + } + nativeMapView.setDebug(savedInstanceState.getBoolean(MapboxConstants.STATE_DEBUG_ACTIVE)); final String styleUrl = savedInstanceState.getString(MapboxConstants.STATE_STYLE_URL); -- cgit v1.2.1 From facc3d54a00f393b5c2f5e3b0ff3494015c9d942 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Tue, 6 Jun 2017 15:43:39 -0400 Subject: fix #8300 flyTo for close points The isClose threshold is switched from 0.000001 pixels to 1 pixel. As a backup, it checks whether r0 and r1 are finite. It might be possible to have just the threshold check or just the finiteness check, but I don't see the harm in having both. std::abs(w0 - w1) < 0.000001 is removed because it doesn't look like it's needed. All calculations should run fine even if w0 === w1. Finally, the point interpolation is tweaked so that at the end of the flying (when k === 1) it ends up at the exact end point. I didn't see any bugs related to this, but it seems like a good thing to have explicitly. --- src/mbgl/map/transform.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp index 20e29db6ac..8d05bc0e91 100644 --- a/src/mbgl/map/transform.cpp +++ b/src/mbgl/map/transform.cpp @@ -235,16 +235,13 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima return std::log(std::sqrt(b * b + 1) - b); }; - // When u₀ = u₁, the optimal path doesn’t require both ascent and descent. - bool isClose = std::abs(u1) < 0.000001; - // Perform a more or less instantaneous transition if the path is too short. - if (isClose && std::abs(w0 - w1) < 0.000001) { - easeTo(camera, animation); - return; - } - /// r₀: Zoom-out factor during ascent. double r0 = r(0); + double r1 = r(1); + + // When u₀ = u₁, the optimal path doesn’t require both ascent and descent. + bool isClose = std::abs(u1) < 1.0 || !std::isfinite(r0) || !std::isfinite(r1); + /** w(s): Returns the visible span on the ground, measured in pixels with respect to the initial scale. @@ -262,7 +259,7 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima }; /// S: Total length of the flight path, measured in ρ-screenfuls. double S = (isClose ? (std::abs(std::log(w1 / w0)) / rho) - : ((r(1) - r0) / rho)); + : ((r1 - r0) / rho)); Duration duration; if (animation.duration) { @@ -290,7 +287,7 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima /// s: The distance traveled along the flight path, measured in /// ρ-screenfuls. double s = k * S; - double us = u(s); + double us = k == 1.0 ? 1.0 : u(s); // Calculate the current point and zoom level along the flight path. Point framePoint = util::interpolate(startPoint, endPoint, us); -- cgit v1.2.1 From ae837f4db242c074206aeb2c214b4418fcfed0c0 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Wed, 7 Jun 2017 12:41:30 +0200 Subject: [android] - remove conversion from pixels to dp (#9205) --- .../src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 63f2e653cc..a31babc1c5 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 @@ -621,7 +621,7 @@ final class NativeMapView { if (isDestroyedOn("getMetersPerPixelAtLatitude")) { return 0; } - return nativeGetMetersPerPixelAtLatitude(lat, getZoom()) / pixelRatio; + return nativeGetMetersPerPixelAtLatitude(lat, getZoom()); } public ProjectedMeters projectedMetersForLatLng(LatLng latLng) { -- cgit v1.2.1 From 78eca869ae239b9686a885be6492196f6b0ae48a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Wed, 7 Jun 2017 18:02:28 +0200 Subject: [android] - option to disable camera animation while following position (#9210) --- .../mapboxsdk/constants/MapboxConstants.java | 1 + .../mapbox/mapboxsdk/maps/TrackingSettings.java | 25 ++++++++++++++++++++++ .../mapboxsdk/maps/widgets/MyLocationView.java | 22 +++++++++++++++---- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java index ecb6ffe24e..0396defe74 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java @@ -133,5 +133,6 @@ public class MapboxConstants { public static final String STATE_ATTRIBUTION_MARGIN_RIGHT = "mapbox_attrMarginRight"; public static final String STATE_ATTRIBUTION_MARGIN_BOTTOM = "mapbox_atrrMarginBottom"; public static final String STATE_ATTRIBUTION_ENABLED = "mapbox_atrrEnabled"; + public static final String STATE_LOCATION_CHANGE_ANIMATION_ENABLED = "mapbox_locationChangeAnimationEnabled"; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java index 7dcd84de75..2e12de8dec 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java @@ -29,6 +29,7 @@ public final class TrackingSettings { private final CameraZoomInvalidator zoomInvalidator; private LocationEngine locationSource; private LocationEngineListener myLocationListener; + private boolean locationChangeAnimationEnabled = true; private boolean myLocationEnabled; private boolean dismissLocationTrackingOnGesture = true; @@ -56,6 +57,7 @@ public final class TrackingSettings { outState.putBoolean(MapboxConstants.STATE_MY_LOCATION_TRACKING_DISMISS, isDismissLocationTrackingOnGesture()); outState.putBoolean(MapboxConstants.STATE_MY_BEARING_TRACKING_DISMISS, isDismissBearingTrackingOnGesture()); outState.putBoolean(MapboxConstants.STATE_MY_LOCATION_ENABLED, isMyLocationEnabled()); + outState.putBoolean(MapboxConstants.STATE_LOCATION_CHANGE_ANIMATION_ENABLED, isLocationChangeAnimationEnabled()); } void onRestoreInstanceState(Bundle savedInstanceState) { @@ -74,6 +76,8 @@ public final class TrackingSettings { MapboxConstants.STATE_MY_LOCATION_TRACKING_DISMISS, true)); setDismissBearingTrackingOnGesture(savedInstanceState.getBoolean( MapboxConstants.STATE_MY_BEARING_TRACKING_DISMISS, true)); + setLocationChangeAnimationEnabled(savedInstanceState.getBoolean( + MapboxConstants.STATE_LOCATION_CHANGE_ANIMATION_ENABLED, true)); } /** @@ -91,6 +95,7 @@ public final class TrackingSettings { */ @UiThread public void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) { + myLocationView.setLocationChangeAnimationEnabled(isLocationChangeAnimationEnabled()); myLocationView.setMyLocationTrackingMode(myLocationTrackingMode); if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) { @@ -253,6 +258,26 @@ public final class TrackingSettings { || myLocationView.getMyLocationTrackingMode() == MyLocationTracking.TRACKING_NONE); } + /** + * Returns whether location change animation is applied for {@link MyLocationTracking#TRACKING_FOLLOW}. + * + * @return True if animation is applied, false otherwise. + */ + public boolean isLocationChangeAnimationEnabled() { + return locationChangeAnimationEnabled; + } + + /** + * Set whether location change animation should be applied for {@link MyLocationTracking#TRACKING_FOLLOW}. + * + * @param locationChangeAnimationEnabled True if animation should be applied, false otherwise. + */ + public void setLocationChangeAnimationEnabled(boolean locationChangeAnimationEnabled) { + this.locationChangeAnimationEnabled = locationChangeAnimationEnabled; + + myLocationView.setLocationChangeAnimationEnabled(locationChangeAnimationEnabled); + } + /** * Reset the tracking modes as necessary. Location tracking is reset if the map center is changed and not from * location, bearing tracking if there is a rotation. diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java index 098f006f6c..afed8635a9 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java @@ -68,6 +68,7 @@ public class MyLocationView extends View { private ValueAnimator locationChangeAnimator; private ValueAnimator accuracyAnimator; private ValueAnimator directionAnimator; + private boolean locationChangeAnimationEnabled; private ValueAnimator.AnimatorUpdateListener invalidateSelfOnUpdateListener = new ValueAnimator.AnimatorUpdateListener() { @@ -462,6 +463,10 @@ public class MyLocationView extends View { myLocationBehavior.updateLatLng(location); } + public void setLocationChangeAnimationEnabled(boolean locationChangeAnimationEnabled) { + this.locationChangeAnimationEnabled = locationChangeAnimationEnabled; + } + public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) { this.myBearingTrackingMode = myBearingTrackingMode; if (myBearingTrackingMode == MyBearingTracking.COMPASS && compassListener.isSensorAvailable()) { @@ -773,9 +778,14 @@ public class MyLocationView extends View { // accuracy updateAccuracy(location); - // ease to new camera position with a linear interpolator - mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(builder.build()), animationDuration, false, null, - true); + if (locationChangeAnimationEnabled) { + // ease to new camera position with a linear interpolator + mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(builder.build()), animationDuration, false, null, + true); + } else { + mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(builder.build()), 0, false, null, + true); + } } @Override @@ -817,7 +827,11 @@ public class MyLocationView extends View { } locationChangeAnimator = ValueAnimator.ofFloat(0.0f, 1.0f); - locationChangeAnimator.setDuration(locationUpdateDuration); + if (locationChangeAnimationEnabled) { + locationChangeAnimator.setDuration(locationUpdateDuration); + } else { + locationChangeAnimator.setDuration(0); + } locationChangeAnimator.addUpdateListener(new MarkerCoordinateAnimatorListener(this, latLng, newLocation )); -- cgit v1.2.1 From 233117fe5797f7f0dabddbee780b31a624053b68 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Thu, 8 Jun 2017 08:44:29 +0200 Subject: [android] - invalidating MyLocationView bearing when not following position (#9212) --- .../main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java index afed8635a9..f648db413d 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java @@ -461,6 +461,11 @@ public class MyLocationView extends View { this.location = location; myLocationBehavior.updateLatLng(location); + + if (mapboxMap != null && myBearingTrackingMode == MyBearingTracking.GPS + && myLocationTrackingMode == MyLocationTracking.TRACKING_NONE) { + setBearing(mapboxMap.getCameraPosition().bearing); + } } public void setLocationChangeAnimationEnabled(boolean locationChangeAnimationEnabled) { -- cgit v1.2.1 From 9f88e373665124464351424e1efc95fe3a1fc05d Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 9 Jun 2017 10:00:00 +0200 Subject: Custom location source fix (#9142) * [android] - custom location engine fixes (#9139) * Update to latest LOST dependency, fixup internal location source integration --- .../src/main/java/com/mapbox/mapboxsdk/Mapbox.java | 12 +- .../mapboxsdk/constants/MapboxConstants.java | 2 +- .../mapbox/mapboxsdk/location/LocationSource.java | 40 ++--- .../java/com/mapbox/mapboxsdk/maps/MapboxMap.java | 3 - .../mapbox/mapboxsdk/maps/TrackingSettings.java | 31 +++- .../mapboxsdk/maps/widgets/MyLocationView.java | 58 ++++--- .../testapp/maps/widgets/MyLocationViewTest.java | 4 +- .../testapp/activity/FeatureOverviewActivity.java | 52 +++--- .../userlocation/BaseLocationActivity.java | 46 ++++-- .../userlocation/CustomLocationEngineActivity.java | 36 ++++- .../activity/userlocation/MockLocationEngine.java | 125 +++++++++------ .../userlocation/MyLocationDrawableActivity.java | 48 +++--- .../userlocation/MyLocationTintActivity.java | 3 - .../userlocation/MyLocationToggleActivity.java | 65 ++------ .../MyLocationTrackingModeActivity.java | 177 ++++++++++++++------- .../res/layout/activity_my_location_tracking.xml | 2 +- .../src/main/res/menu/menu_location_engine.xml | 20 +++ .../src/main/res/values/strings.xml | 3 + .../test/java/com/mapbox/mapboxsdk/MapboxTest.java | 5 +- platform/android/dependencies.gradle | 4 +- 20 files changed, 444 insertions(+), 292 deletions(-) create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_location_engine.xml diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java index 81134e9497..17cd4e0dce 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java @@ -30,6 +30,7 @@ public final class Mapbox { private Context context; private String accessToken; private Boolean connected; + private LocationSource locationSource; /** * Get an instance of Mapbox. @@ -45,8 +46,8 @@ public final class Mapbox { public static synchronized Mapbox getInstance(@NonNull Context context, @NonNull String accessToken) { if (INSTANCE == null) { Context appContext = context.getApplicationContext(); - INSTANCE = new Mapbox(appContext, accessToken); - LocationEngine locationEngine = LocationSource.getLocationEngine(appContext); + INSTANCE = new Mapbox(appContext, accessToken, new LocationSource(appContext)); + LocationEngine locationEngine = new LocationSource(appContext); locationEngine.setPriority(LocationEnginePriority.NO_POWER); MapboxTelemetry.getInstance().initialize( appContext, accessToken, BuildConfig.MAPBOX_EVENTS_USER_AGENT, locationEngine); @@ -55,9 +56,10 @@ public final class Mapbox { return INSTANCE; } - Mapbox(@NonNull Context context, @NonNull String accessToken) { + Mapbox(@NonNull Context context, @NonNull String accessToken, LocationSource locationSource) { this.context = context; this.accessToken = accessToken; + this.locationSource = locationSource; } /** @@ -128,4 +130,8 @@ public final class Mapbox { NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); return (activeNetwork != null && activeNetwork.isConnected()); } + + public static LocationSource getLocationSource() { + return INSTANCE.locationSource; + } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java index 0396defe74..1ee59057d2 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java @@ -134,5 +134,5 @@ public class MapboxConstants { public static final String STATE_ATTRIBUTION_MARGIN_BOTTOM = "mapbox_atrrMarginBottom"; public static final String STATE_ATTRIBUTION_ENABLED = "mapbox_atrrEnabled"; public static final String STATE_LOCATION_CHANGE_ANIMATION_ENABLED = "mapbox_locationChangeAnimationEnabled"; - + public static final String STATE_USING_CUSTOM_LOCATION_SOURCE = "mapbox_usingCustomLocationSource"; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java index 4e934fa3cc..8416bd5b6c 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java @@ -2,7 +2,7 @@ package com.mapbox.mapboxsdk.location; import android.content.Context; import android.location.Location; -import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import com.mapbox.services.android.telemetry.location.LocationEngine; import com.mapbox.services.android.telemetry.location.LocationEngineListener; @@ -13,10 +13,6 @@ import com.mapzen.android.lost.api.LocationRequest; import com.mapzen.android.lost.api.LocationServices; import com.mapzen.android.lost.api.LostApiClient; -import java.lang.ref.WeakReference; - -import timber.log.Timber; - /** * Manages locational updates. Contains methods to register and unregister location listeners. *
      @@ -35,40 +31,24 @@ import timber.log.Timber; public class LocationSource extends LocationEngine implements LostApiClient.ConnectionCallbacks, LocationListener { - private static LocationEngine instance; - - private WeakReference context; + private Context context; private LostApiClient lostApiClient; - private LocationSource(Context context) { + public LocationSource(Context context) { super(); - this.context = new WeakReference<>(context); - lostApiClient = new LostApiClient.Builder(this.context.get()) + this.context = context.getApplicationContext(); + lostApiClient = new LostApiClient.Builder(this.context) .addConnectionCallbacks(this) .build(); } - /** - * Get the LocationEngine instance. - * - * @param context a Context from which the application context is derived - * @return the LocationEngine instance - */ - public static synchronized LocationEngine getLocationEngine(@NonNull Context context) { - if (instance == null) { - instance = new LocationSource(context.getApplicationContext()); - } - - return instance; - } - /** * Activate the location engine which will connect whichever location provider you are using. You'll need to call * this before requesting user location updates using {@link LocationEngine#requestLocationUpdates()}. */ @Override public void activate() { - if (lostApiClient != null && !lostApiClient.isConnected()) { + if (!lostApiClient.isConnected()) { lostApiClient.connect(); } } @@ -80,7 +60,7 @@ public class LocationSource extends LocationEngine implements */ @Override public void deactivate() { - if (lostApiClient != null && lostApiClient.isConnected()) { + if (lostApiClient.isConnected()) { lostApiClient.disconnect(); } } @@ -111,7 +91,6 @@ public class LocationSource extends LocationEngine implements */ @Override public void onConnectionSuspended() { - Timber.d("Connection suspended."); } /** @@ -120,8 +99,9 @@ public class LocationSource extends LocationEngine implements * @return the last known location */ @Override + @Nullable public Location getLastLocation() { - if (lostApiClient.isConnected() && PermissionsManager.areLocationPermissionsGranted(context.get())) { + if (lostApiClient.isConnected() && PermissionsManager.areLocationPermissionsGranted(context)) { //noinspection MissingPermission return LocationServices.FusedLocationApi.getLastLocation(lostApiClient); } @@ -151,7 +131,7 @@ public class LocationSource extends LocationEngine implements request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); } - if (lostApiClient.isConnected() && PermissionsManager.areLocationPermissionsGranted(context.get())) { + if (lostApiClient.isConnected() && PermissionsManager.areLocationPermissionsGranted(context)) { //noinspection MissingPermission LocationServices.FusedLocationApi.requestLocationUpdates(lostApiClient, request, this); } 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 8e50adb777..8a708cb186 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 @@ -37,7 +37,6 @@ import com.mapbox.mapboxsdk.constants.MyLocationTracking; import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; -import com.mapbox.mapboxsdk.location.LocationSource; import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings; import com.mapbox.mapboxsdk.style.layers.Filter; import com.mapbox.mapboxsdk.style.layers.Layer; @@ -1872,8 +1871,6 @@ public final class MapboxMap { * Replaces the location source of the my-location layer. * * @param locationSource A {@link LocationEngine} location source to use in the my-location layer. - * Set to null to use the default {@link LocationSource} - * location source. */ @UiThread public void setLocationSource(@Nullable LocationEngine locationSource) { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java index 2e12de8dec..bd0bf7c83b 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java @@ -6,11 +6,11 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.UiThread; +import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.constants.MyBearingTracking; import com.mapbox.mapboxsdk.constants.MyLocationTracking; -import com.mapbox.mapboxsdk.location.LocationSource; import com.mapbox.mapboxsdk.maps.widgets.MyLocationView; import com.mapbox.services.android.telemetry.location.LocationEngine; import com.mapbox.services.android.telemetry.location.LocationEngineListener; @@ -30,6 +30,7 @@ public final class TrackingSettings { private LocationEngine locationSource; private LocationEngineListener myLocationListener; private boolean locationChangeAnimationEnabled = true; + private boolean isCustomLocationSource; private boolean myLocationEnabled; private boolean dismissLocationTrackingOnGesture = true; @@ -47,7 +48,7 @@ public final class TrackingSettings { } void initialise(MapboxMapOptions options) { - locationSource = LocationSource.getLocationEngine(myLocationView.getContext()); + locationSource = Mapbox.getLocationSource(); setMyLocationEnabled(options.getLocationEnabled()); } @@ -58,11 +59,15 @@ public final class TrackingSettings { outState.putBoolean(MapboxConstants.STATE_MY_BEARING_TRACKING_DISMISS, isDismissBearingTrackingOnGesture()); outState.putBoolean(MapboxConstants.STATE_MY_LOCATION_ENABLED, isMyLocationEnabled()); outState.putBoolean(MapboxConstants.STATE_LOCATION_CHANGE_ANIMATION_ENABLED, isLocationChangeAnimationEnabled()); + outState.putBoolean(MapboxConstants.STATE_USING_CUSTOM_LOCATION_SOURCE, isCustomLocationSource()); } void onRestoreInstanceState(Bundle savedInstanceState) { try { - setMyLocationEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_MY_LOCATION_ENABLED)); + setMyLocationEnabled( + savedInstanceState.getBoolean(MapboxConstants.STATE_MY_LOCATION_ENABLED), + savedInstanceState.getBoolean(MapboxConstants.STATE_USING_CUSTOM_LOCATION_SOURCE) + ); } catch (SecurityException ignore) { // User did not accept location permissions } @@ -339,6 +344,10 @@ public final class TrackingSettings { } } + public boolean isCustomLocationSource() { + return isCustomLocationSource; + } + void setOnMyLocationTrackingModeChangeListener(MapboxMap.OnMyLocationTrackingModeChangeListener listener) { this.onMyLocationTrackingModeChangeListener = listener; } @@ -357,16 +366,30 @@ public final class TrackingSettings { } void setMyLocationEnabled(boolean locationEnabled) { + setMyLocationEnabled(locationEnabled, isCustomLocationSource()); + } + + private void setMyLocationEnabled(boolean locationEnabled, boolean isCustomLocationSource) { if (!PermissionsManager.areLocationPermissionsGranted(myLocationView.getContext())) { Timber.e("Could not activate user location tracking: " + "user did not accept the permission or permissions were not requested."); return; } myLocationEnabled = locationEnabled; - myLocationView.setEnabled(locationEnabled); + this.isCustomLocationSource = isCustomLocationSource; + myLocationView.setEnabled(locationEnabled, isCustomLocationSource); } void setLocationSource(LocationEngine locationSource) { + if (this.locationSource != null && this.locationSource.equals(locationSource)) { + // this source is already active + return; + } + + this.isCustomLocationSource = locationSource != null; + if (locationSource == null) { + locationSource = Mapbox.getLocationSource(); + } this.locationSource = locationSource; myLocationView.setLocationSource(locationSource); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java index f648db413d..9740679cf5 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java @@ -26,6 +26,7 @@ import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; +import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.constants.MyBearingTracking; @@ -40,6 +41,8 @@ import com.mapbox.services.android.telemetry.location.LocationEnginePriority; import java.lang.ref.WeakReference; +import timber.log.Timber; + /** * UI element overlaid on a map to show the user's location. */ @@ -148,6 +151,10 @@ public class MyLocationView extends View { compassListener = new CompassListener(context); } + public void init(LocationSource locationSource) { + this.locationSource = locationSource; + } + public final void setForegroundDrawables(Drawable defaultDrawable, Drawable bearingDrawable) { if (defaultDrawable == null) { return; @@ -391,9 +398,13 @@ public class MyLocationView extends View { @Override public void setEnabled(boolean enabled) { + setEnabled(enabled, false); + } + + public void setEnabled(boolean enabled, boolean isCustomLocationSource) { super.setEnabled(enabled); setVisibility(enabled ? View.VISIBLE : View.INVISIBLE); - toggleGps(enabled); + toggleGps(enabled, isCustomLocationSource); } @Override @@ -414,22 +425,23 @@ public class MyLocationView extends View { super.onRestoreInstanceState(state); } + private void toggleGps(boolean enableGps) { + toggleGps(enableGps, mapboxMap != null && mapboxMap.getTrackingSettings().isCustomLocationSource()); + } + /** * Enabled / Disable GPS location updates along with updating the UI * * @param enableGps true if GPS is to be enabled, false if GPS is to be disabled */ - private void toggleGps(boolean enableGps) { - if (locationSource == null) { - locationSource = LocationSource.getLocationEngine(this.getContext()); - } - + private void toggleGps(boolean enableGps, boolean isCustomLocationSource) { if (enableGps) { - // Set an initial location if one available - Location lastLocation = locationSource.getLastLocation(); - - if (lastLocation != null) { - setLocation(lastLocation); + if (locationSource == null) { + if (!isCustomLocationSource) { + locationSource = Mapbox.getLocationSource(); + } else { + return; + } } if (userLocationListener == null) { @@ -437,16 +449,18 @@ public class MyLocationView extends View { } locationSource.addLocationEngineListener(userLocationListener); + locationSource.setPriority(LocationEnginePriority.HIGH_ACCURACY); locationSource.activate(); } else { + if (locationSource == null) { + return; + } // Disable location and user dot location = null; - locationSource.removeLocationUpdates(); locationSource.removeLocationEngineListener(userLocationListener); + locationSource.removeLocationUpdates(); locationSource.deactivate(); } - - locationSource.setPriority(LocationEnginePriority.HIGH_ACCURACY); } public Location getLocation() { @@ -564,7 +578,10 @@ public class MyLocationView extends View { } public void setLocationSource(LocationEngine locationSource) { + toggleGps(false); this.locationSource = locationSource; + this.userLocationListener = null; + setEnabled(isEnabled(), locationSource != null); } private static class GpsLocationListener implements LocationEngineListener { @@ -580,10 +597,12 @@ public class MyLocationView extends View { @Override public void onConnected() { MyLocationView locationView = userLocationView.get(); - if (locationView != null) { - LocationEngine locationEngine = locationSource.get(); - Location location = locationEngine.getLastLocation(); - locationView.setLocation(location); + LocationEngine locationEngine = locationSource.get(); + if (locationView != null && locationEngine != null) { + Location lastKnownLocation = locationEngine.getLastLocation(); + if (lastKnownLocation != null) { + locationView.setLocation(lastKnownLocation); + } locationEngine.requestLocationUpdates(); } } @@ -627,6 +646,9 @@ public class MyLocationView extends View { } public boolean isSensorAvailable() { + if (rotationVectorSensor == null) { + Timber.e("Sensor.TYPE_ROTATION_VECTOR is missing from this device. Unable to use MyBearingTracking.COMPASS."); + } return rotationVectorSensor != null; } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/MyLocationViewTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/MyLocationViewTest.java index efd67db356..fa19235ad0 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/MyLocationViewTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/MyLocationViewTest.java @@ -9,12 +9,12 @@ import android.support.test.espresso.UiController; import android.support.test.espresso.ViewAction; import android.view.View; +import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.constants.MyBearingTracking; import com.mapbox.mapboxsdk.constants.MyLocationTracking; import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.location.LocationSource; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.widgets.MyLocationView; import com.mapbox.mapboxsdk.testapp.R; @@ -104,7 +104,7 @@ public class MyLocationViewTest extends BaseActivityTest { mapboxMap.moveCamera( CameraUpdateFactory.newCameraPosition( new CameraPosition.Builder() - .target(new LatLng(LocationSource.getLocationEngine(view.getContext()).getLastLocation())) + .target(new LatLng(Mapbox.getLocationSource().getLastLocation())) .build() ) ); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/FeatureOverviewActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/FeatureOverviewActivity.java index 074be98f5c..f8617366a0 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/FeatureOverviewActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/FeatureOverviewActivity.java @@ -1,6 +1,5 @@ package com.mapbox.mapboxsdk.testapp.activity; -import android.Manifest; import android.content.ComponentName; import android.content.Intent; import android.content.pm.ActivityInfo; @@ -13,11 +12,10 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.StringRes; import android.support.design.widget.Snackbar; -import android.support.v4.app.ActivityCompat; -import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.text.TextUtils; import android.view.View; import com.mapbox.mapboxsdk.testapp.R; @@ -25,6 +23,8 @@ import com.mapbox.mapboxsdk.testapp.adapter.FeatureAdapter; import com.mapbox.mapboxsdk.testapp.adapter.FeatureSectionAdapter; import com.mapbox.mapboxsdk.testapp.model.activity.Feature; import com.mapbox.mapboxsdk.testapp.utils.ItemClickSupport; +import com.mapbox.services.android.telemetry.permissions.PermissionsListener; +import com.mapbox.services.android.telemetry.permissions.PermissionsManager; import java.util.ArrayList; import java.util.Collections; @@ -40,19 +40,23 @@ import timber.log.Timber; * It uses tags as category and description to order the different entries. *

      */ -public class FeatureOverviewActivity extends AppCompatActivity { +public class FeatureOverviewActivity extends AppCompatActivity implements PermissionsListener { private static final String KEY_STATE_FEATURES = "featureList"; + private PermissionsManager permissionsManager; private RecyclerView recyclerView; private FeatureSectionAdapter sectionAdapter; private List features; + private int locationActivityInList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_feature_overview); + permissionsManager = new PermissionsManager(this); + recyclerView = (RecyclerView) findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener()); @@ -119,22 +123,26 @@ public class FeatureOverviewActivity extends AppCompatActivity { } private boolean requestLocationPermission(final int positionInList) { - if ((ContextCompat.checkSelfPermission(FeatureOverviewActivity.this, - Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) - || (ContextCompat.checkSelfPermission(FeatureOverviewActivity.this, - Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) { - ActivityCompat.requestPermissions(FeatureOverviewActivity.this, new String[] { - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, positionInList); + if (isRuntimePermissionsRequired()) { + locationActivityInList = positionInList; + permissionsManager.requestLocationPermissions(this); return true; - } else { - return false; } + return false; } @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - if (!isRuntimePermissionsRequired() || isPermissionAccepted(grantResults)) { - startFeature(features.get(requestCode)); + public void onExplanationNeeded(List list) { + Snackbar.make( + findViewById(android.R.id.content), + TextUtils.join("", list.toArray()), + Snackbar.LENGTH_SHORT).show(); + } + + @Override + public void onPermissionResult(boolean isPermissionGranted) { + if (isPermissionGranted) { + startFeature(features.get(locationActivityInList)); } else { Snackbar.make( findViewById(android.R.id.content), @@ -143,12 +151,14 @@ public class FeatureOverviewActivity extends AppCompatActivity { } } - private boolean isRuntimePermissionsRequired() { - return android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults); } - private boolean isPermissionAccepted(@NonNull int[] grantResults) { - return grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED; + private boolean isRuntimePermissionsRequired() { + return android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; } @Override @@ -219,13 +229,13 @@ public class FeatureOverviewActivity extends AppCompatActivity { } }; - List requiresPermissionActvities = new ArrayList() { + List requiresPermissionActivities = new ArrayList() { { add(resources.getString(R.string.activity_double_map)); } }; - return requiresPermissionCategories.contains(category) || requiresPermissionActvities.contains(name); + return requiresPermissionCategories.contains(category) || requiresPermissionActivities.contains(name); } @Override diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/BaseLocationActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/BaseLocationActivity.java index a8d1772cb2..f41e5e38f0 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/BaseLocationActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/BaseLocationActivity.java @@ -1,25 +1,34 @@ package com.mapbox.mapboxsdk.testapp.activity.userlocation; -import android.Manifest; -import android.content.pm.PackageManager; import android.os.Build; +import android.os.Bundle; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.annotation.UiThread; -import android.support.v4.app.ActivityCompat; +import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; +import android.text.TextUtils; +import com.mapbox.services.android.telemetry.permissions.PermissionsListener; import com.mapbox.services.android.telemetry.permissions.PermissionsManager; -public abstract class BaseLocationActivity extends AppCompatActivity { +import java.util.List; - private static final int PERMISSIONS_LOCATION = 0; +public abstract class BaseLocationActivity extends AppCompatActivity implements PermissionsListener { + + private PermissionsManager permissionsManager; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + permissionsManager = new PermissionsManager(this); + } @UiThread protected final void toggleGps(boolean enableGps) { if (enableGps) { - if (!PermissionsManager.areLocationPermissionsGranted(this)) { - ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_LOCATION); + if (!isRuntimePermissionsRequired()) { + permissionsManager.requestLocationPermissions(this); } else { enableLocation(true); } @@ -29,16 +38,21 @@ public abstract class BaseLocationActivity extends AppCompatActivity { } @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - if (requestCode == PERMISSIONS_LOCATION) { - if (!isRuntimePermissionsRequired() || isPermissionAccepted(grantResults)) { - enableLocation(true); - } - } + public void onExplanationNeeded(List list) { + Snackbar.make( + findViewById(android.R.id.content), + TextUtils.join("", list.toArray()), + Snackbar.LENGTH_SHORT).show(); + } + + @Override + public void onPermissionResult(boolean isPermissionAccepted) { + enableLocation(isPermissionAccepted); } - private boolean isPermissionAccepted(int[] grantResults) { - return grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED; + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults); } private boolean isRuntimePermissionsRequired() { diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/CustomLocationEngineActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/CustomLocationEngineActivity.java index 660404f144..b0ea9c608b 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/CustomLocationEngineActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/CustomLocationEngineActivity.java @@ -2,13 +2,15 @@ package com.mapbox.mapboxsdk.testapp.activity.userlocation; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; +import com.mapbox.mapboxsdk.Mapbox; 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 com.mapbox.services.android.telemetry.location.LocationEngine; public class CustomLocationEngineActivity extends BaseLocationActivity { @@ -16,22 +18,18 @@ public class CustomLocationEngineActivity extends BaseLocationActivity { private MapboxMap mapboxMap; private FloatingActionButton locationToggleFab; - private LocationEngine locationServices; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_custom_location_engine); - locationServices = new MockLocationEngine(); - mapView = (MapView) findViewById(R.id.mapView); mapView.onCreate(savedInstanceState); mapView.getMapAsync(new OnMapReadyCallback() { @Override public void onMapReady(MapboxMap map) { mapboxMap = map; - mapboxMap.setLocationSource(locationServices); + mapboxMap.setLocationSource(MockLocationEngine.getInstance()); } }); @@ -40,7 +38,7 @@ public class CustomLocationEngineActivity extends BaseLocationActivity { @Override public void onClick(View view) { if (mapboxMap != null) { - toggleGps(!mapboxMap.isMyLocationEnabled()); + enableLocation(!mapboxMap.isMyLocationEnabled()); } } }); @@ -56,6 +54,30 @@ public class CustomLocationEngineActivity extends BaseLocationActivity { } } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_location_engine, menu); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (mapboxMap != null) { + int itemId = item.getItemId(); + if (itemId == R.id.action_id_location_source_lost) { + mapboxMap.setLocationSource(Mapbox.getLocationSource()); + return true; + } else if (itemId == R.id.action_id_location_source_mock) { + mapboxMap.setLocationSource(MockLocationEngine.getInstance()); + return true; + } else if (itemId == R.id.action_id_location_source_null) { + mapboxMap.setLocationSource(null); + return true; + } + } + return super.onOptionsItemSelected(item); + } + @Override protected void onStart() { super.onStart(); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MockLocationEngine.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MockLocationEngine.java index b02b35b0d0..da3c78b07a 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MockLocationEngine.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MockLocationEngine.java @@ -1,38 +1,55 @@ package com.mapbox.mapboxsdk.testapp.activity.userlocation; - +import android.animation.AnimatorListenerAdapter; +import android.animation.TypeEvaluator; +import android.animation.ValueAnimator; import android.location.Location; -import android.os.Handler; import com.mapbox.services.android.telemetry.location.LocationEngine; import com.mapbox.services.android.telemetry.location.LocationEngineListener; +import timber.log.Timber; + /** - * Sample LocationEngine that provides mocked locations simulating GPS updates + * Sample LocationEngine that provides mocked LOCATIONS simulating GPS updates */ public class MockLocationEngine extends LocationEngine { + private static MockLocationEngine INSTANCE; + + private final LocationAnimator locationAnimator; + private boolean running; + private static int counter; + + MockLocationEngine(Location start, Location end) { + locationAnimator = new LocationAnimator(start, end, new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + for (LocationEngineListener listener : locationListeners) { + listener.onLocationChanged((Location) animation.getAnimatedValue()); + } + } + }); + } + + public static synchronized MockLocationEngine getInstance() { + if (INSTANCE == null) { + INSTANCE = new MockLocationEngine( + MockLocationEngine.createLocation(40.416913, -3.703861), + MockLocationEngine.createLocation(39.461643, -0.368041) + ); + } + return INSTANCE; + } - // Mocked data - private static final int UPDATE_INTERVAL_MS = 1000; - private static final double[][] locations = new double[][] { - new double[] {39.489309, -0.360415}, - new double[] {39.492469, -0.358777}, - new double[] {40.393285, -3.707260}, - new double[] {40.394374, -3.707767}, - new double[] {40.398012, -3.715943}, - new double[] {40.416913, -3.703861}}; - - private Handler handler; - int currentIndex; - - public MockLocationEngine() { - super(); + public static Location createLocation(double latitude, double longitude) { + Location location = new Location(MockLocationEngine.class.getSimpleName()); + location.setLatitude(latitude); + location.setLongitude(longitude); + return location; } @Override public void activate() { - currentIndex = 0; - // "Connection" is immediate here for (LocationEngineListener listener : locationListeners) { listener.onConnected(); @@ -41,7 +58,6 @@ public class MockLocationEngine extends LocationEngine { @Override public void deactivate() { - handler = null; } @Override @@ -51,44 +67,61 @@ public class MockLocationEngine extends LocationEngine { @Override public Location getLastLocation() { - return getNextLocation(); + return null; } @Override public void requestLocationUpdates() { - // Fake regular updates with a handler - handler = new Handler(); - handler.postDelayed(new LocationUpdateRunnable(), UPDATE_INTERVAL_MS); + if (!running) { + locationAnimator.start(); + running = true; + } } @Override public void removeLocationUpdates() { - if (handler != null) { - handler.removeCallbacksAndMessages(null); + if (running) { + locationAnimator.stop(); + running = false; + Timber.e("LOC %s", counter); } } - private Location getNextLocation() { - // Build the next location and rotate the index - Location location = new Location(MockLocationEngine.class.getSimpleName()); - location.setLatitude(locations[currentIndex][0]); - location.setLongitude(locations[currentIndex][1]); - currentIndex = (currentIndex == locations.length - 1 ? 0 : currentIndex + 1); - return location; - } + private static class LocationAnimator extends AnimatorListenerAdapter { - private class LocationUpdateRunnable implements Runnable { - @Override - public void run() { - // Notify of an update - Location location = getNextLocation(); - for (LocationEngineListener listener : locationListeners) { - listener.onLocationChanged(location); - } + private static final long DURATION_ANIMATION = 10000; + private final ValueAnimator locationAnimator; + private long animationTime; + + LocationAnimator(Location start, Location end, ValueAnimator.AnimatorUpdateListener listener) { + locationAnimator = ValueAnimator.ofObject(new LocationEvaluator(), start, end); + locationAnimator.setDuration(DURATION_ANIMATION); + locationAnimator.addUpdateListener(listener); + locationAnimator.addListener(this); + } + + void start() { + locationAnimator.start(); + locationAnimator.setCurrentPlayTime(animationTime); + } + + void stop() { + animationTime = locationAnimator.getCurrentPlayTime(); + locationAnimator.cancel(); + } + + private static class LocationEvaluator implements TypeEvaluator { + + private Location location = new Location(MockLocationEngine.class.getSimpleName()); - if (handler != null) { - // Schedule the next update - handler.postDelayed(new LocationUpdateRunnable(), UPDATE_INTERVAL_MS); + @Override + public Location evaluate(float fraction, Location startValue, Location endValue) { + counter++; + location.setLatitude(startValue.getLatitude() + + ((endValue.getLatitude() - startValue.getLatitude()) * fraction)); + location.setLongitude(startValue.getLongitude() + + ((endValue.getLongitude() - startValue.getLongitude()) * fraction)); + return location; } } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java index 5560f81fa9..8657434127 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java @@ -11,33 +11,35 @@ import android.view.ViewGroup; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.location.LocationSource; 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.testapp.R; -import com.mapbox.services.android.telemetry.location.LocationEngineListener; + +import com.mapzen.android.lost.api.LocationListener; +import com.mapzen.android.lost.api.LocationRequest; +import com.mapzen.android.lost.api.LocationServices; +import com.mapzen.android.lost.api.LostApiClient; /** * Test activity showcasing how to change the MyLocationView drawable. */ -public class MyLocationDrawableActivity extends BaseLocationActivity implements LocationEngineListener { +public class MyLocationDrawableActivity extends BaseLocationActivity implements LostApiClient.ConnectionCallbacks, + LocationListener { private MapView mapView; private MapboxMap mapboxMap; + private LostApiClient lostApiClient; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_location_customization); - findViewById(R.id.progress).setVisibility(View.GONE); MapboxMapOptions mapboxMapOptions = new MapboxMapOptions(); mapboxMapOptions.styleUrl(Style.MAPBOX_STREETS); - - // configure MyLocationView drawables mapboxMapOptions.myLocationForegroundDrawable(ContextCompat.getDrawable(this, R.drawable.ic_android)); mapboxMapOptions.myLocationBackgroundDrawable(ContextCompat.getDrawable(this, R.drawable.ic_android)); mapboxMapOptions.myLocationForegroundTintColor(Color.GREEN); @@ -45,7 +47,6 @@ public class MyLocationDrawableActivity extends BaseLocationActivity implements mapboxMapOptions.myLocationBackgroundPadding(new int[] {0, 0, (int) getResources().getDimension(R.dimen.locationview_background_drawable_padding), (int) getResources().getDimension(R.dimen.locationview_background_drawable_padding)}); - mapboxMapOptions.myLocationAccuracyTint(Color.RED); mapboxMapOptions.myLocationAccuracyAlpha(155); @@ -66,29 +67,29 @@ public class MyLocationDrawableActivity extends BaseLocationActivity implements @Override protected void enableLocation(boolean enabled) { - if (enabled) { - mapboxMap.setMyLocationEnabled(true); - Location location = mapboxMap.getMyLocation(); - if (location != null) { - onLocationChanged(location); - } else { - LocationSource.getLocationEngine(this).addLocationEngineListener(this); - } - } else { - mapboxMap.setMyLocationEnabled(false); + mapboxMap.setMyLocationEnabled(enabled); + if (lostApiClient == null) { + lostApiClient = new LostApiClient.Builder(this).addConnectionCallbacks(this).build(); + lostApiClient.connect(); } } @Override public void onConnected() { - // Nothing + LocationRequest request = LocationRequest.create() + .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) + .setInterval(5000) + .setSmallestDisplacement(10); + LocationServices.FusedLocationApi.requestLocationUpdates(lostApiClient, request, this); } @Override public void onLocationChanged(Location location) { - if (mapboxMap != null) { - mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location), 14)); - } + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location), 14)); + } + + @Override + public void onConnectionSuspended() { } @Override @@ -113,6 +114,11 @@ public class MyLocationDrawableActivity extends BaseLocationActivity implements protected void onStop() { super.onStop(); mapView.onStop(); + if (lostApiClient.isConnected()) { + LocationServices.FusedLocationApi.removeLocationUpdates(lostApiClient, this); + lostApiClient.disconnect(); + } + lostApiClient.unregisterConnectionCallbacks(this); } @Override diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTintActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTintActivity.java index a219b369f6..44ee030885 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTintActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTintActivity.java @@ -13,7 +13,6 @@ import android.view.View; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.constants.MyLocationTracking; import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.location.LocationSource; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; @@ -133,7 +132,6 @@ public class MyLocationTintActivity extends BaseLocationActivity implements Loca protected void onStart() { super.onStart(); mapView.onStart(); - LocationSource.getLocationEngine(this).addLocationEngineListener(this); } @Override @@ -151,7 +149,6 @@ public class MyLocationTintActivity extends BaseLocationActivity implements Loca @Override protected void onStop() { super.onStop(); - LocationSource.getLocationEngine(this).removeLocationEngineListener(this); mapView.onStop(); } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationToggleActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationToggleActivity.java index ac6c346a88..d465d676f7 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationToggleActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationToggleActivity.java @@ -1,19 +1,15 @@ package com.mapbox.mapboxsdk.testapp.activity.userlocation; -import android.location.Location; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.view.View; -import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; -import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.location.LocationSource; 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 com.mapbox.services.android.telemetry.location.LocationEngine; -import com.mapbox.services.android.telemetry.location.LocationEngineListener; + +import timber.log.Timber; public class MyLocationToggleActivity extends BaseLocationActivity { @@ -21,16 +17,11 @@ public class MyLocationToggleActivity extends BaseLocationActivity { private MapboxMap mapboxMap; private FloatingActionButton locationToggleFab; - private LocationEngine locationServices; - private LocationEngineListener locationListener; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_location_toggle); - locationServices = LocationSource.getLocationEngine(this); - mapView = (MapView) findViewById(R.id.mapView); mapView.onCreate(savedInstanceState); mapView.getMapAsync(new OnMapReadyCallback() { @@ -51,6 +42,17 @@ public class MyLocationToggleActivity extends BaseLocationActivity { }); } + @Override + protected void enableLocation(boolean enabled) { + Timber.e("Enabling location: %s", enabled); + mapboxMap.setMyLocationEnabled(enabled); + if (enabled) { + locationToggleFab.setImageResource(R.drawable.ic_location_disabled); + } else { + locationToggleFab.setImageResource(R.drawable.ic_my_location); + } + } + @Override protected void onStart() { super.onStart(); @@ -85,11 +87,6 @@ public class MyLocationToggleActivity extends BaseLocationActivity { protected void onDestroy() { super.onDestroy(); mapView.onDestroy(); - // Ensure no memory leak occurs if we register the location listener but the call hasn't - // been made yet. - if (locationListener != null) { - locationServices.removeLocationEngineListener(locationListener); - } } @Override @@ -98,40 +95,4 @@ public class MyLocationToggleActivity extends BaseLocationActivity { mapView.onLowMemory(); } - @Override - protected void enableLocation(boolean enabled) { - if (enabled) { - // To move the camera instantly, we attempt to get the last known location and either - // ease or animate the camera to that position depending on the zoom level. - Location lastLocation = LocationSource.getLocationEngine(this).getLastLocation(); - - if (lastLocation != null) { - if (mapboxMap.getCameraPosition().zoom > 15.99) { - mapboxMap.easeCamera(CameraUpdateFactory.newLatLng(new LatLng(lastLocation)), 1000); - } else { - mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lastLocation), 16), 1000); - } - } else { - locationListener = new LocationEngineListener() { - @Override - public void onConnected() { - // Nothing - } - - @Override - public void onLocationChanged(Location location) { - if (location != null) { - mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location), 16)); - locationServices.removeLocationEngineListener(this); - } - } - }; - locationServices.addLocationEngineListener(locationListener); - } - locationToggleFab.setImageResource(R.drawable.ic_location_disabled); - } else { - locationToggleFab.setImageResource(R.drawable.ic_my_location); - } - mapboxMap.setMyLocationEnabled(enabled); - } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java index 3a3301b87f..91f3de0837 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java @@ -1,5 +1,6 @@ package com.mapbox.mapboxsdk.testapp.activity.userlocation; +import android.location.Location; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v7.app.ActionBar; @@ -13,14 +14,22 @@ import android.widget.ArrayAdapter; import android.widget.Spinner; import android.widget.Toast; +import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.constants.MyBearingTracking; import com.mapbox.mapboxsdk.constants.MyLocationTracking; +import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; import com.mapbox.mapboxsdk.maps.TrackingSettings; import com.mapbox.mapboxsdk.maps.UiSettings; import com.mapbox.mapboxsdk.testapp.R; +import com.mapzen.android.lost.api.LocationListener; +import com.mapzen.android.lost.api.LocationRequest; +import com.mapzen.android.lost.api.LocationServices; +import com.mapzen.android.lost.api.LostApiClient; + +import timber.log.Timber; /** * Test activity showcasing the different tracking modes the SDK exposes. @@ -29,7 +38,11 @@ import com.mapbox.mapboxsdk.testapp.R; * using gesture configurations. *

      */ -public class MyLocationTrackingModeActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener { +public class MyLocationTrackingModeActivity extends AppCompatActivity implements + AdapterView.OnItemSelectedListener, OnMapReadyCallback, LostApiClient.ConnectionCallbacks, LocationListener { + + // Testing for user defined LostApiClient + private LostApiClient lostApiClient; public static final int TRACKING_NONE_INDEX = 0; public static final int TRACKING_FOLLOW_INDEX = 1; @@ -41,6 +54,7 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements private MapboxMap mapboxMap; private Spinner locationSpinner; private Spinner bearingSpinner; + private boolean firstRun = true; private MenuItem dismissLocationTrackingOnGestureItem; private MenuItem dismissBearingTrackingOnGestureItem; @@ -51,7 +65,55 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_location_tracking); + setupToolbar(); + + mapView = (MapView) findViewById(R.id.mapView); + mapView.onCreate(savedInstanceState); + mapView.getMapAsync(this); + } + + @Override + public void onMapReady(MapboxMap mapboxMap) { + MyLocationTrackingModeActivity.this.mapboxMap = mapboxMap; + lostApiClient = new LostApiClient.Builder(this).addConnectionCallbacks(this).build(); + lostApiClient.connect(); + } + + @Override + public void onConnected() { + LocationRequest request = LocationRequest.create() + .setPriority(LocationRequest.PRIORITY_LOW_POWER) + .setInterval(5000) + .setSmallestDisplacement(10); + + Location location = LocationServices.FusedLocationApi.getLastLocation(lostApiClient); + if (location != null) { + setInitialLocation(location, 15); + } + LocationServices.FusedLocationApi.requestLocationUpdates(lostApiClient, request, this); + } + + @Override + public void onConnectionSuspended() { + } + + @Override + public void onLocationChanged(Location location) { + Timber.e("Location changed %s", location); + if (firstRun) { + setInitialLocation(location, 16); + } + } + + private void setInitialLocation(Location location, double zoom) { + mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location), zoom)); + mapboxMap.setMyLocationEnabled(true); + setupSpinners(mapboxMap); + firstRun = false; + } + + private void setupToolbar() { Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); @@ -60,72 +122,60 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements actionBar.setDisplayShowTitleEnabled(false); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setDisplayShowHomeEnabled(true); - } - - locationSpinner = (Spinner) findViewById(R.id.spinner_location); - ArrayAdapter locationTrackingAdapter = ArrayAdapter.createFromResource( - actionBar.getThemedContext(), R.array.user_tracking_mode, android.R.layout.simple_spinner_item); - locationTrackingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - locationSpinner.setAdapter(locationTrackingAdapter); - bearingSpinner = (Spinner) findViewById(R.id.spinner_bearing); - ArrayAdapter bearingTrackingAdapter = ArrayAdapter.createFromResource( - actionBar.getThemedContext(), R.array.user_bearing_mode, android.R.layout.simple_spinner_item); - bearingTrackingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - bearingSpinner.setAdapter(bearingTrackingAdapter); + locationSpinner = (Spinner) findViewById(R.id.spinner_location); + ArrayAdapter locationTrackingAdapter = ArrayAdapter.createFromResource( + actionBar.getThemedContext(), R.array.user_tracking_mode, android.R.layout.simple_spinner_item); + locationTrackingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + locationSpinner.setAdapter(locationTrackingAdapter); + + bearingSpinner = (Spinner) findViewById(R.id.spinner_bearing); + ArrayAdapter bearingTrackingAdapter = ArrayAdapter.createFromResource( + actionBar.getThemedContext(), R.array.user_bearing_mode, android.R.layout.simple_spinner_item); + bearingTrackingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + bearingSpinner.setAdapter(bearingTrackingAdapter); + } + } - mapView = (MapView) findViewById(R.id.mapView); - mapView.onCreate(savedInstanceState); + private void setupSpinners(@NonNull MapboxMap mapboxMap) { + locationSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this); + bearingSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this); + setCheckBoxes(); - mapView.getMapAsync(new OnMapReadyCallback() { + mapboxMap.setOnMyLocationTrackingModeChangeListener(new MapboxMap.OnMyLocationTrackingModeChangeListener() { @Override - public void onMapReady(@NonNull MapboxMap mapboxMap) { - MyLocationTrackingModeActivity.this.mapboxMap = mapboxMap; - + public void onMyLocationTrackingModeChange(@MyLocationTracking.Mode int myLocationTrackingMode) { + locationSpinner.setOnItemSelectedListener(null); + switch (myLocationTrackingMode) { + case MyLocationTracking.TRACKING_NONE: + locationSpinner.setSelection(TRACKING_NONE_INDEX); + break; + case MyLocationTracking.TRACKING_FOLLOW: + locationSpinner.setSelection(TRACKING_FOLLOW_INDEX); + break; + } locationSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this); - bearingSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this); - setCheckBoxes(); - - mapboxMap.setOnMyLocationTrackingModeChangeListener(new MapboxMap.OnMyLocationTrackingModeChangeListener() { - @Override - public void onMyLocationTrackingModeChange(@MyLocationTracking.Mode int myLocationTrackingMode) { - locationSpinner.setOnItemSelectedListener(null); - switch (myLocationTrackingMode) { - case MyLocationTracking.TRACKING_NONE: - locationSpinner.setSelection(TRACKING_NONE_INDEX); - break; - case MyLocationTracking.TRACKING_FOLLOW: - locationSpinner.setSelection(TRACKING_FOLLOW_INDEX); - break; - } - locationSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this); - } - }); - - mapboxMap.setOnMyBearingTrackingModeChangeListener(new MapboxMap.OnMyBearingTrackingModeChangeListener() { - @Override - public void onMyBearingTrackingModeChange(@MyBearingTracking.Mode int myBearingTrackingMode) { - bearingSpinner.setOnItemSelectedListener(null); - switch (myBearingTrackingMode) { - case MyBearingTracking.NONE: - bearingSpinner.setSelection(BEARING_NONE_INDEX); - break; - - case MyBearingTracking.GPS: - bearingSpinner.setSelection(BEARING_GPS_INDEX); - break; - - case MyBearingTracking.COMPASS: - bearingSpinner.setSelection(BEARING_COMPASS_INDEX); - break; - } - bearingSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this); - } - }); - - if (savedInstanceState == null) { - mapboxMap.setMyLocationEnabled(true); + } + }); + + mapboxMap.setOnMyBearingTrackingModeChangeListener(new MapboxMap.OnMyBearingTrackingModeChangeListener() { + @Override + public void onMyBearingTrackingModeChange(@MyBearingTracking.Mode int myBearingTrackingMode) { + bearingSpinner.setOnItemSelectedListener(null); + switch (myBearingTrackingMode) { + case MyBearingTracking.NONE: + bearingSpinner.setSelection(BEARING_NONE_INDEX); + break; + + case MyBearingTracking.GPS: + bearingSpinner.setSelection(BEARING_GPS_INDEX); + break; + + case MyBearingTracking.COMPASS: + bearingSpinner.setSelection(BEARING_COMPASS_INDEX); + break; } + bearingSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this); } }); } @@ -186,6 +236,11 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements @Override protected void onStop() { super.onStop(); + LocationServices.FusedLocationApi.removeLocationUpdates(lostApiClient, this); + if (lostApiClient.isConnected()) { + lostApiClient.unregisterConnectionCallbacks(this); + lostApiClient.disconnect(); + } mapView.onStop(); } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_tracking.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_tracking.xml index 95f084506b..7236a944e9 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_tracking.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_tracking.xml @@ -45,6 +45,6 @@ app:mapbox_myLocationTintColor="@color/primary" app:mapbox_myLocationAccuracyTintColor="@color/primary" app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets" - app:mapbox_cameraZoom="15" /> + app:mapbox_cameraZoom="8" /> diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_location_engine.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_location_engine.xml new file mode 100644 index 0000000000..dd7408df09 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_location_engine.xml @@ -0,0 +1,20 @@ + + + + + + + + + + \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml index 5b6cbb8c42..74833105a4 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml @@ -151,6 +151,9 @@ Reset Enable rotate gestures Enable scroll gestures + Change to LOST location source + Change to mock location source + Reset location source to null Move diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/MapboxTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/MapboxTest.java index 6ee5c157b9..e05190cd57 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/MapboxTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/MapboxTest.java @@ -5,6 +5,7 @@ import android.net.ConnectivityManager; import android.net.NetworkInfo; import com.mapbox.mapboxsdk.exceptions.MapboxConfigurationException; +import com.mapbox.mapboxsdk.location.LocationSource; import org.junit.Before; import org.junit.Test; @@ -24,11 +25,13 @@ public class MapboxTest { private Context context; private Context appContext; + private LocationSource locationSource; @Before public void before() { context = mock(Context.class); appContext = mock(Context.class); + locationSource = mock(LocationSource.class); when(context.getApplicationContext()).thenReturn(appContext); } @@ -80,7 +83,7 @@ public class MapboxTest { } private void injectMapboxSingleton(String accessToken) { - Mapbox mapbox = new Mapbox(appContext, accessToken); + Mapbox mapbox = new Mapbox(appContext, accessToken, locationSource); try { Field field = Mapbox.class.getDeclaredField("INSTANCE"); field.setAccessible(true); diff --git a/platform/android/dependencies.gradle b/platform/android/dependencies.gradle index 5e80e344e4..e71e077104 100644 --- a/platform/android/dependencies.gradle +++ b/platform/android/dependencies.gradle @@ -21,8 +21,8 @@ ext { mapboxAndroidTelemetry : "com.mapbox.mapboxsdk:mapbox-android-telemetry:${mapboxServicesVersion}@aar", // mapzen lost - lost : 'com.mapzen.android:lost:3.0.0', - + lost : 'com.mapzen.android:lost:3.0.1-20170607.212149-4', + // unit test junit : 'junit:junit:4.12', mockito : 'org.mockito:mockito-core:2.2.27', -- cgit v1.2.1 From fa972fad60e58e5b8f9f9622f508e9732c8c9ffd Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 9 Jun 2017 11:11:33 +0200 Subject: [android] - update components with camera values when animating (#9174) --- .../src/main/java/com/mapbox/mapboxsdk/maps/Transform.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java index 9a8997014a..505e440dcb 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java @@ -150,6 +150,10 @@ final class Transform implements MapView.OnMapChangedListener { cameraChangeDispatcher.onCameraMove(); } + if (isComponentUpdateRequired(cameraPosition)) { + updateCameraPosition(cameraPosition); + } + this.cameraPosition = cameraPosition; if (onCameraChangeListener != null) { onCameraChangeListener.onCameraChange(this.cameraPosition); @@ -158,6 +162,11 @@ final class Transform implements MapView.OnMapChangedListener { return cameraPosition; } + private boolean isComponentUpdateRequired(@NonNull CameraPosition cameraPosition) { + return this.cameraPosition != null && (this.cameraPosition.tilt != cameraPosition.tilt + || this.cameraPosition.bearing != cameraPosition.bearing); + } + void cancelTransitions() { // notify user about cancel cameraChangeDispatcher.onCameraMoveCanceled(); -- cgit v1.2.1 From 6ec5e4f8cdb98227db11e5989376c31832ca2048 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 9 Jun 2017 12:05:54 +0200 Subject: Cherry picks to release branch (#9230) * [ios][macos] test remove source in use * [android] test remove source in use * [core] check source usage before remove * [core] ensure layer::accept works with non-void return values on gcc * [android] - remove upgrade runtime exceptions (#9191) --- include/mbgl/style/layer.hpp | 7 +++++ .../java/com/mapbox/mapboxsdk/maps/MapView.java | 18 ++---------- .../mapboxsdk/testapp/style/RuntimeStyleTests.java | 18 ++++++++++++ platform/darwin/test/MGLStyleTests.mm | 16 +++++++++++ src/mbgl/style/style.cpp | 23 ++++++++++++++++ test/style/style.test.cpp | 32 ++++++++++++++++++++++ 6 files changed, 98 insertions(+), 16 deletions(-) diff --git a/include/mbgl/style/layer.hpp b/include/mbgl/style/layer.hpp index 56f2c48fa7..016b3a1c8b 100644 --- a/include/mbgl/style/layer.hpp +++ b/include/mbgl/style/layer.hpp @@ -5,8 +5,10 @@ #include #include +#include #include #include +#include namespace mbgl { namespace style { @@ -96,6 +98,11 @@ public: case LayerType::FillExtrusion: return visitor(*as()); } + + + // Not reachable, but placate GCC. + assert(false); + throw new std::runtime_error("unknown layer type"); } const std::string& getID() const; 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 d00da4c155..9a1f2fc515 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 @@ -67,8 +67,6 @@ public class MapView extends FrameLayout { private MapboxMap mapboxMap; private MapCallback mapCallback; - private boolean onStartCalled; - private boolean onStopCalled; private MapGestureDetector mapGestureDetector; private MapKeyListener mapKeyListener; @@ -233,7 +231,6 @@ public class MapView extends FrameLayout { */ @UiThread public void onStart() { - onStartCalled = true; mapboxMap.onStart(); ConnectivityReceiver.instance(getContext()).activate(); } @@ -243,11 +240,7 @@ public class MapView extends FrameLayout { */ @UiThread public void onResume() { - if (!onStartCalled) { - // TODO: 26/10/16, can be removed after 5.0.0 release - throw new IllegalStateException("MapView#onStart() was not called. " - + "You must call this method from the parent's {@link Activity#onStart()} or {@link Fragment#onStart()}."); - } + // replaced by onStart in v5.0.0 } /** @@ -255,7 +248,7 @@ public class MapView extends FrameLayout { */ @UiThread public void onPause() { - // replaced by onStop in v5.0.0, keep around for future development + // replaced by onStop in v5.0.0 } /** @@ -263,7 +256,6 @@ public class MapView extends FrameLayout { */ @UiThread public void onStop() { - onStopCalled = true; mapboxMap.onStop(); ConnectivityReceiver.instance(getContext()).deactivate(); } @@ -273,12 +265,6 @@ public class MapView extends FrameLayout { */ @UiThread public void onDestroy() { - if (!onStopCalled) { - // TODO: 26/10/16, can be removed after 5.0.0 release - throw new IllegalStateException("MapView#onStop() was not called. " - + "You must call this method from the parent's {@link Activity#onStop()} or {@link Fragment#onStop()}."); - } - destroyed = true; nativeMapView.terminateContext(); nativeMapView.terminateDisplay(); 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 a1c46903bf..a37615aadc 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 @@ -12,6 +12,7 @@ import com.mapbox.mapboxsdk.style.layers.CannotAddLayerException; import com.mapbox.mapboxsdk.style.layers.CircleLayer; import com.mapbox.mapboxsdk.style.layers.FillLayer; import com.mapbox.mapboxsdk.style.layers.Layer; +import com.mapbox.mapboxsdk.style.layers.LineLayer; import com.mapbox.mapboxsdk.style.layers.Property; import com.mapbox.mapboxsdk.style.layers.PropertyFactory; import com.mapbox.mapboxsdk.style.sources.CannotAddSourceException; @@ -223,6 +224,23 @@ public class RuntimeStyleTests extends BaseActivityTest { assertEquals("http://mapbox.com/my-file.json", source.getUrl()); } + @Test + public void testRemoveSourceInUse() { + validateTestSetup(); + + onView(withId(R.id.mapView)).perform(new BaseViewAction() { + + @Override + public void perform(UiController uiController, View view) { + mapboxMap.addSource(new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2")); + mapboxMap.addLayer(new LineLayer("my-layer", "my-source")); + mapboxMap.removeSource("my-source"); + assertNotNull(mapboxMap.getSource("my-source")); + } + + }); + } + /** * https://github.com/mapbox/mapbox-gl-native/issues/7973 */ diff --git a/platform/darwin/test/MGLStyleTests.mm b/platform/darwin/test/MGLStyleTests.mm index f80d5776f0..d93483ea6e 100644 --- a/platform/darwin/test/MGLStyleTests.mm +++ b/platform/darwin/test/MGLStyleTests.mm @@ -240,6 +240,22 @@ XCTAssertTrue([[self.style sourceWithIdentifier:shapeSource.identifier] isMemberOfClass:[MGLVectorSource class]]); } +- (void)testRemovingSourceInUse { + // Add a raster source + MGLRasterSource *rasterSource = [[MGLRasterSource alloc] initWithIdentifier:@"some-identifier" tileURLTemplates:@[] options:nil]; + [self.style addSource:rasterSource]; + + // Add a layer using it + MGLFillStyleLayer *fillLayer = [[MGLFillStyleLayer alloc] initWithIdentifier:@"fillLayer" source:rasterSource]; + [self.style addLayer:fillLayer]; + + // Attempt to remove the raster source + [self.style removeSource:rasterSource]; + + // Ensure it is still there + XCTAssertTrue([[self.style sourceWithIdentifier:rasterSource.identifier] isMemberOfClass:[MGLRasterSource class]]); +} + - (void)testLayers { NSArray *initialLayers = self.style.layers; if ([initialLayers.firstObject.identifier isEqualToString:@"com.mapbox.annotations.points"]) { diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index f083ca47b8..568b575dfa 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -196,7 +196,30 @@ void Style::addSource(std::unique_ptr source) { sources.emplace_back(std::move(source)); } +struct SourceIdUsageEvaluator { + const std::string& sourceId; + + bool operator()(BackgroundLayer&) { return false; } + bool operator()(CustomLayer&) { return false; } + + template + bool operator()(LayerType& layer) { + return layer.getSourceID() == sourceId; + } +}; + std::unique_ptr Style::removeSource(const std::string& id) { + // Check if source is in use + SourceIdUsageEvaluator sourceIdEvaluator {id}; + auto layerIt = std::find_if(layers.begin(), layers.end(), [&](const auto& layer) { + return layer->accept(sourceIdEvaluator); + }); + + if (layerIt != layers.end()) { + Log::Warning(Event::General, "Source '%s' is in use, cannot remove", id.c_str()); + return nullptr; + } + auto it = std::find_if(sources.begin(), sources.end(), [&](const auto& source) { return source->getID() == id; }); diff --git a/test/style/style.test.cpp b/test/style/style.test.cpp index b529abad4a..841c7b291b 100644 --- a/test/style/style.test.cpp +++ b/test/style/style.test.cpp @@ -1,10 +1,12 @@ #include #include +#include #include #include #include #include +#include #include #include #include @@ -67,3 +69,33 @@ TEST(Style, DuplicateSource) { // Expected } } + +TEST(Style, RemoveSourceInUse) { + util::RunLoop loop; + + auto log = new FixtureLogObserver(); + Log::setObserver(std::unique_ptr(log)); + + ThreadPool threadPool{ 1 }; + StubFileSource fileSource; + Style style { threadPool, fileSource, 1.0 }; + + style.setJSON(util::read_file("test/fixtures/resources/style-unused-sources.json")); + + style.addSource(std::make_unique("sourceId", "mapbox://mapbox.mapbox-terrain-v2")); + style.addLayer(std::make_unique("layerId", "sourceId")); + + // Should not remove the source + auto removed = style.removeSource("sourceId"); + ASSERT_EQ(nullptr, removed); + ASSERT_NE(nullptr, style.getSource("sourceId")); + + const FixtureLogObserver::LogMessage logMessage { + EventSeverity::Warning, + Event::General, + int64_t(-1), + "Source 'sourceId' is in use, cannot remove", + }; + + EXPECT_EQ(log->count(logMessage), 1u); +} -- cgit v1.2.1 From 294f4f8df9541f735d3928c605f123c444c60a28 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 9 Jun 2017 15:47:21 +0200 Subject: [android] - update changelog for v5.1.0-beta.4 (#9232) --- platform/android/CHANGELOG.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md index 22bede23f6..eb2fd0554c 100644 --- a/platform/android/CHANGELOG.md +++ b/platform/android/CHANGELOG.md @@ -2,10 +2,22 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to do so please see the [`Contributing Guide`](https://github.com/mapbox/mapbox-gl-native/blob/master/CONTRIBUTING.md) first to get started. -## 5.1.0-rc.1 - TBA +## 5.1.0 - TBA +## 5.1.0-beta.4 - June 9, 2017 + +* Option to disable location change animation [#9210](https://github.com/mapbox/mapbox-gl-native/pull/9210) +* Invalidating MyLocationView bearing when not following [#9212](https://github.com/mapbox/mapbox-gl-native/pull/9212) +* Remove upgrade runtime exceptions [#9191](https://github.com/mapbox/mapbox-gl-native/pull/9191) +* Check source usage before removal [#9129](https://github.com/mapbox/mapbox-gl-native/pull/9129) * Fix tracking mode + camera race condition [#9133](https://github.com/mapbox/mapbox-gl-native/pull/9133) * Harden orientation changes [#9128](https://github.com/mapbox/mapbox-gl-native/pull/9128) +* Infinite location animation updates [#9194](https://github.com/mapbox/mapbox-gl-native/pull/9194) +* Invoke callback with valid fling gestures [#9192](https://github.com/mapbox/mapbox-gl-native/pull/9192) +* Keep location tracking after screen rotation [#9187](https://github.com/mapbox/mapbox-gl-native/pull/9187) +* Update components with camera values when animating [#9174](https://github.com/mapbox/mapbox-gl-native/pull/9174) +* Validate if gestures should execute [#9173](https://github.com/mapbox/mapbox-gl-native/pull/9173) +* Custom location source and LOST integration [#9142](https://github.com/mapbox/mapbox-gl-native/pull/9142) ## 5.1.0-beta.3 - May 26, 2017 -- cgit v1.2.1 From e59766f4e805a2cd081fbf30ab2365d05ddda8a3 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Mon, 12 Jun 2017 11:02:36 +0200 Subject: [android] - run MapboxMap invocations to ui thread for instrumentation tests (#9198) --- .../gradle-checkstyle.gradle | 1 + .../mapboxsdk/testapp/action/MapboxMapAction.java | 49 + .../mapboxsdk/testapp/annotations/MarkerTest.java | 111 +- .../testapp/annotations/MarkerViewTest.java | 123 +- .../mapboxsdk/testapp/annotations/PolygonTest.java | 86 +- .../testapp/annotations/PolylineTest.java | 79 +- .../testapp/camera/CameraAnimateTest.java | 303 +- .../mapboxsdk/testapp/camera/CameraEaseTest.java | 305 +- .../mapboxsdk/testapp/camera/CameraMoveTest.java | 304 +- .../testapp/maps/widgets/CompassViewTest.java | 101 +- .../testapp/style/BackgroundLayerTest.java | 284 +- .../mapboxsdk/testapp/style/BaseStyleTest.java | 15 - .../mapboxsdk/testapp/style/CircleLayerTest.java | 2025 ++++--- .../testapp/style/FillExtrusionLayerTest.java | 1035 ++-- .../mapboxsdk/testapp/style/FillLayerTest.java | 970 ++-- .../mapbox/mapboxsdk/testapp/style/LightTest.java | 122 +- .../mapboxsdk/testapp/style/LineLayerTest.java | 1942 ++++--- .../mapboxsdk/testapp/style/RasterLayerTest.java | 596 ++- .../style/RuntimeStyleBackgroundLayerTest.java | 61 - .../mapboxsdk/testapp/style/RuntimeStyleTests.java | 123 +- .../mapboxsdk/testapp/style/SymbolLayerTest.java | 5510 ++++++++++++-------- .../mapbox/mapboxsdk/testapp/style/layer.junit.ejs | 482 +- .../mapbox/mapboxsdk/testapp/style/light.junit.ejs | 58 +- platform/android/scripts/generate-style-code.js | 4 +- 24 files changed, 8298 insertions(+), 6391 deletions(-) create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/MapboxMapAction.java delete mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BaseStyleTest.java delete mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleBackgroundLayerTest.java diff --git a/platform/android/MapboxGLAndroidSDKTestApp/gradle-checkstyle.gradle b/platform/android/MapboxGLAndroidSDKTestApp/gradle-checkstyle.gradle index fdc4399f16..e4e1ba0453 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/gradle-checkstyle.gradle +++ b/platform/android/MapboxGLAndroidSDKTestApp/gradle-checkstyle.gradle @@ -13,6 +13,7 @@ task checkstyle(type: Checkstyle) { include '**/*.java' exclude '**/gen/**' exclude '**/style/*LayerTest.java' + exclude '**/style/LightTest.java' classpath = files() ignoreFailures = false } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/MapboxMapAction.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/MapboxMapAction.java new file mode 100644 index 0000000000..47af80cab9 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/action/MapboxMapAction.java @@ -0,0 +1,49 @@ +package com.mapbox.mapboxsdk.testapp.action; + +import android.support.test.espresso.UiController; +import android.support.test.espresso.ViewAction; +import android.view.View; + +import com.mapbox.mapboxsdk.maps.MapboxMap; + +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.withId; + +public class MapboxMapAction implements ViewAction { + + private OnInvokeActionListener invokeViewAction; + private MapboxMap mapboxMap; + + private MapboxMapAction(OnInvokeActionListener invokeViewAction, MapboxMap mapboxMap) { + this.invokeViewAction = invokeViewAction; + this.mapboxMap = mapboxMap; + } + + @Override + public Matcher getConstraints() { + return isDisplayed(); + } + + @Override + public String getDescription() { + return getClass().getSimpleName(); + } + + @Override + public void perform(UiController uiController, View view) { + invokeViewAction.onInvokeAction(uiController, mapboxMap); + } + + public static void invoke(MapboxMap mapboxMap, OnInvokeActionListener invokeViewAction) { + onView(withId(android.R.id.content)).perform(new MapboxMapAction(invokeViewAction, mapboxMap)); + } + + public interface OnInvokeActionListener { + void onInvokeAction(UiController uiController, MapboxMap mapboxMap); + } +} + + diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/MarkerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/MarkerTest.java index 2f638ff651..e511135b99 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/MarkerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/MarkerTest.java @@ -1,27 +1,24 @@ package com.mapbox.mapboxsdk.testapp.annotations; import android.support.test.espresso.UiController; -import android.support.test.espresso.ViewAction; -import android.view.View; import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.annotations.MarkerOptions; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity; import com.mapbox.mapboxsdk.testapp.utils.TestConstants; -import org.hamcrest.Matcher; import org.junit.Ignore; import org.junit.Test; 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 static android.support.test.espresso.matcher.ViewMatchers.withText; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; import static org.junit.Assert.assertEquals; public class MarkerTest extends BaseActivityTest { @@ -37,87 +34,45 @@ public class MarkerTest extends BaseActivityTest { @Ignore public void addMarkerTest() { validateTestSetup(); - assertEquals("Markers should be empty", 0, mapboxMap.getMarkers().size()); - - MarkerOptions options = new MarkerOptions(); - options.setPosition(new LatLng()); - options.setSnippet(TestConstants.TEXT_MARKER_SNIPPET); - options.setTitle(TestConstants.TEXT_MARKER_TITLE); - - onView(withId(R.id.mapView)).perform(new AddMarkerAction(mapboxMap, options)); - assertEquals("Markers sze should be 1, ", 1, mapboxMap.getMarkers().size()); - assertEquals("Marker id should be 0", 0, marker.getId()); - assertEquals("Marker target should match", new LatLng(), marker.getPosition()); - assertEquals("Marker snippet should match", TestConstants.TEXT_MARKER_SNIPPET, marker.getSnippet()); - assertEquals("Marker target should match", TestConstants.TEXT_MARKER_TITLE, marker.getTitle()); - mapboxMap.clear(); - assertEquals("Markers should be empty", 0, mapboxMap.getMarkers().size()); + MapboxMapAction.invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertEquals("Markers should be empty", 0, mapboxMap.getMarkers().size()); + + MarkerOptions options = new MarkerOptions(); + options.setPosition(new LatLng()); + options.setSnippet(TestConstants.TEXT_MARKER_SNIPPET); + options.setTitle(TestConstants.TEXT_MARKER_TITLE); + marker = mapboxMap.addMarker(options); + + assertEquals("Markers size should be 1, ", 1, mapboxMap.getMarkers().size()); + assertEquals("Marker id should be 0", 0, marker.getId()); + assertEquals("Marker target should match", new LatLng(), marker.getPosition()); + assertEquals("Marker snippet should match", TestConstants.TEXT_MARKER_SNIPPET, marker.getSnippet()); + assertEquals("Marker target should match", TestConstants.TEXT_MARKER_TITLE, marker.getTitle()); + mapboxMap.clear(); + assertEquals("Markers should be empty", 0, mapboxMap.getMarkers().size()); + } + }); } @Test @Ignore public void showInfoWindowTest() { validateTestSetup(); - - final MarkerOptions options = new MarkerOptions(); - options.setPosition(new LatLng()); - options.setSnippet(TestConstants.TEXT_MARKER_SNIPPET); - options.setTitle(TestConstants.TEXT_MARKER_TITLE); - - onView(withId(R.id.mapView)).perform(new AddMarkerAction(mapboxMap, options)); - onView(withId(R.id.mapView)).perform(new ShowInfoWindowAction(mapboxMap)); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + final MarkerOptions options = new MarkerOptions(); + options.setPosition(new LatLng()); + options.setSnippet(TestConstants.TEXT_MARKER_SNIPPET); + options.setTitle(TestConstants.TEXT_MARKER_TITLE); + marker = mapboxMap.addMarker(options); + mapboxMap.selectMarker(marker); + } + }); onView(withText(TestConstants.TEXT_MARKER_TITLE)).check(matches(isDisplayed())); onView(withText(TestConstants.TEXT_MARKER_SNIPPET)).check(matches(isDisplayed())); } - private class AddMarkerAction implements ViewAction { - - private MapboxMap mapboxMap; - private MarkerOptions options; - - AddMarkerAction(MapboxMap map, MarkerOptions markerOptions) { - mapboxMap = map; - options = markerOptions; - } - - @Override - public Matcher getConstraints() { - return isDisplayed(); - } - - @Override - public String getDescription() { - return getClass().getSimpleName(); - } - - @Override - public void perform(UiController uiController, View view) { - marker = mapboxMap.addMarker(options); - } - } - - private class ShowInfoWindowAction implements ViewAction { - - private MapboxMap mapboxMap; - - ShowInfoWindowAction(MapboxMap map) { - mapboxMap = map; - } - - @Override - public Matcher getConstraints() { - return isDisplayed(); - } - - @Override - public String getDescription() { - return getClass().getSimpleName(); - } - - @Override - public void perform(UiController uiController, View view) { - mapboxMap.selectMarker(marker); - - } - } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/MarkerViewTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/MarkerViewTest.java index bee20c3150..8bf847c2e7 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/MarkerViewTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/MarkerViewTest.java @@ -1,28 +1,25 @@ package com.mapbox.mapboxsdk.testapp.annotations; import android.support.test.espresso.UiController; -import android.support.test.espresso.ViewAction; -import android.view.View; import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; import com.mapbox.mapboxsdk.testapp.activity.annotation.MarkerViewActivity; import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity; import com.mapbox.mapboxsdk.testapp.model.annotations.TextMarkerViewOptions; import com.mapbox.mapboxsdk.testapp.utils.TestConstants; -import org.hamcrest.Matcher; import org.junit.Ignore; import org.junit.Test; 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 static android.support.test.espresso.matcher.ViewMatchers.withText; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; import static org.junit.Assert.assertEquals; public class MarkerViewTest extends BaseActivityTest { @@ -38,20 +35,26 @@ public class MarkerViewTest extends BaseActivityTest { @Ignore public void addMarkerViewTest() { validateTestSetup(); - assertEquals("Markers should be empty", 0, mapboxMap.getMarkers().size()); - - TextMarkerViewOptions options = new TextMarkerViewOptions(); - options.text(TestConstants.TEXT_MARKER_TEXT); - options.position(new LatLng()); - options.snippet(TestConstants.TEXT_MARKER_SNIPPET); - options.title(TestConstants.TEXT_MARKER_TITLE); - - onView(withId(R.id.mapView)).perform(new AddTextMarkerViewAction(mapboxMap, options)); - assertEquals("Markers sze should be 1, ", 1, mapboxMap.getMarkers().size()); - assertEquals("Marker id should be 0", 0, marker.getId()); - assertEquals("Marker target should match", new LatLng(), marker.getPosition()); - assertEquals("Marker snippet should match", TestConstants.TEXT_MARKER_SNIPPET, marker.getSnippet()); - assertEquals("Marker target should match", TestConstants.TEXT_MARKER_TITLE, marker.getTitle()); + addAdapter(); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertEquals("Markers should be empty", 0, mapboxMap.getMarkers().size()); + + TextMarkerViewOptions options = new TextMarkerViewOptions(); + options.text(TestConstants.TEXT_MARKER_TEXT); + options.position(new LatLng()); + options.snippet(TestConstants.TEXT_MARKER_SNIPPET); + options.title(TestConstants.TEXT_MARKER_TITLE); + marker = mapboxMap.addMarker(options); + assertEquals("Markers size should be 1, ", 1, mapboxMap.getMarkers().size()); + assertEquals("Marker id should be 0", 0, marker.getId()); + assertEquals("Marker target should match", new LatLng(), marker.getPosition()); + assertEquals("Marker snippet should match", TestConstants.TEXT_MARKER_SNIPPET, marker.getSnippet()); + assertEquals("Marker target should match", TestConstants.TEXT_MARKER_TITLE, marker.getTitle()); + uiController.loopMainThreadForAtLeast(500); + } + }); onView(withText(TestConstants.TEXT_MARKER_TEXT)).check(matches(isDisplayed())); } @@ -59,71 +62,33 @@ public class MarkerViewTest extends BaseActivityTest { @Ignore public void showInfoWindowTest() { validateTestSetup(); - - final TextMarkerViewOptions options = new TextMarkerViewOptions(); - options.position(new LatLng()); - options.text(TestConstants.TEXT_MARKER_TEXT); - options.snippet(TestConstants.TEXT_MARKER_SNIPPET); - options.title(TestConstants.TEXT_MARKER_TITLE); - - onView(withId(R.id.mapView)).perform(new AddTextMarkerViewAction(mapboxMap, options)); + addAdapter(); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + final TextMarkerViewOptions options = new TextMarkerViewOptions(); + options.position(new LatLng()); + options.text(TestConstants.TEXT_MARKER_TEXT); + options.snippet(TestConstants.TEXT_MARKER_SNIPPET); + options.title(TestConstants.TEXT_MARKER_TITLE); + marker = mapboxMap.addMarker(options); + uiController.loopMainThreadForAtLeast(500); + mapboxMap.selectMarker(marker); + } + }); onView(withText(TestConstants.TEXT_MARKER_TEXT)).check(matches(isDisplayed())); - onView(withId(R.id.mapView)).perform(new ShowInfoWindowAction(mapboxMap)); onView(withText(TestConstants.TEXT_MARKER_TITLE)).check(matches(isDisplayed())); onView(withText(TestConstants.TEXT_MARKER_SNIPPET)).check(matches(isDisplayed())); } - private class AddTextMarkerViewAction implements ViewAction { - - private MapboxMap mapboxMap; - private TextMarkerViewOptions options; - - AddTextMarkerViewAction(MapboxMap map, TextMarkerViewOptions markerOptions) { - mapboxMap = map; - options = markerOptions; - } - - @Override - public Matcher getConstraints() { - return isDisplayed(); - } - - @Override - public String getDescription() { - return getClass().getSimpleName(); - } - - @Override - public void perform(UiController uiController, View view) { - mapboxMap.getMarkerViewManager().addMarkerViewAdapter( - new MarkerViewActivity.TextAdapter(view.getContext(), mapboxMap)); - marker = mapboxMap.addMarker(options); - uiController.loopMainThreadForAtLeast(250); - } + private void addAdapter() { + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + mapboxMap.getMarkerViewManager().addMarkerViewAdapter( + new MarkerViewActivity.TextAdapter(rule.getActivity(), mapboxMap)); + } + }); } - private class ShowInfoWindowAction implements ViewAction { - - private MapboxMap mapboxMap; - - ShowInfoWindowAction(MapboxMap map) { - mapboxMap = map; - } - - @Override - public Matcher getConstraints() { - return isDisplayed(); - } - - @Override - public String getDescription() { - return getClass().getSimpleName(); - } - - @Override - public void perform(UiController uiController, View view) { - mapboxMap.selectMarker(marker); - uiController.loopMainThreadForAtLeast(250); - } - } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolygonTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolygonTest.java index 325568bec4..c90a5f60c6 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolygonTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolygonTest.java @@ -2,24 +2,19 @@ package com.mapbox.mapboxsdk.testapp.annotations; import android.graphics.Color; import android.support.test.espresso.UiController; -import android.support.test.espresso.ViewAction; -import android.view.View; import com.mapbox.mapboxsdk.annotations.Polygon; import com.mapbox.mapboxsdk.annotations.PolygonOptions; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity; -import org.hamcrest.Matcher; import org.junit.Ignore; import org.junit.Test; -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; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; import static org.junit.Assert.assertEquals; public class PolygonTest extends BaseActivityTest { @@ -29,60 +24,35 @@ public class PolygonTest extends BaseActivityTest { return EspressoTestActivity.class; } - private Polygon polygon; - @Test @Ignore - /** native crash **/ public void addPolygonTest() { validateTestSetup(); - LatLng latLngOne = new LatLng(); - LatLng latLngTwo = new LatLng(1, 0); - LatLng latLngThree = new LatLng(1, 1); - - assertEquals("Polygons should be empty", 0, mapboxMap.getPolygons().size()); - - final PolygonOptions options = new PolygonOptions(); - options.strokeColor(Color.BLUE); - options.fillColor(Color.RED); - options.add(latLngOne); - options.add(latLngTwo); - options.add(latLngThree); - - onView(withId(R.id.mapView)).perform(new AddPolygonAction(mapboxMap, options)); - - assertEquals("Polygons should be 1", 1, mapboxMap.getPolygons().size()); - assertEquals("Polygon id should be 0", 0, polygon.getId()); - assertEquals("Polygon points size should match", 3, polygon.getPoints().size()); - assertEquals("Polygon stroke color should match", Color.BLUE, polygon.getStrokeColor()); - assertEquals("Polygon target should match", Color.RED, polygon.getFillColor()); - mapboxMap.clear(); - assertEquals("Polygons should be empty", 0, mapboxMap.getPolygons().size()); - } - - private class AddPolygonAction implements ViewAction { - - private MapboxMap mapboxMap; - private PolygonOptions options; - - AddPolygonAction(MapboxMap map, PolygonOptions polygonOptions) { - mapboxMap = map; - options = polygonOptions; - } - - @Override - public Matcher getConstraints() { - return isDisplayed(); - } - - @Override - public String getDescription() { - return getClass().getSimpleName(); - } - - @Override - public void perform(UiController uiController, View view) { - polygon = mapboxMap.addPolygon(options); - } + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + LatLng latLngOne = new LatLng(); + LatLng latLngTwo = new LatLng(1, 0); + LatLng latLngThree = new LatLng(1, 1); + + assertEquals("Polygons should be empty", 0, mapboxMap.getPolygons().size()); + + final PolygonOptions options = new PolygonOptions(); + options.strokeColor(Color.BLUE); + options.fillColor(Color.RED); + options.add(latLngOne); + options.add(latLngTwo); + options.add(latLngThree); + Polygon polygon = mapboxMap.addPolygon(options); + + assertEquals("Polygons should be 1", 1, mapboxMap.getPolygons().size()); + assertEquals("Polygon id should be 0", 0, polygon.getId()); + assertEquals("Polygon points size should match", 3, polygon.getPoints().size()); + assertEquals("Polygon stroke color should match", Color.BLUE, polygon.getStrokeColor()); + assertEquals("Polygon target should match", Color.RED, polygon.getFillColor()); + mapboxMap.clear(); + assertEquals("Polygons should be empty", 0, mapboxMap.getPolygons().size()); + } + }); } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolylineTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolylineTest.java index 91553f7042..e6aa661729 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolylineTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolylineTest.java @@ -2,82 +2,53 @@ package com.mapbox.mapboxsdk.testapp.annotations; import android.graphics.Color; import android.support.test.espresso.UiController; -import android.support.test.espresso.ViewAction; -import android.view.View; import com.mapbox.mapboxsdk.annotations.Polyline; import com.mapbox.mapboxsdk.annotations.PolylineOptions; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity; -import org.hamcrest.Matcher; import org.junit.Ignore; import org.junit.Test; -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; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; import static org.junit.Assert.assertEquals; public class PolylineTest extends BaseActivityTest { - private Polyline polyline; - @Override protected Class getActivityClass() { return EspressoTestActivity.class; } - @Ignore @Test + @Ignore public void addPolylineTest() { validateTestSetup(); - LatLng latLngOne = new LatLng(); - LatLng latLngTwo = new LatLng(1, 0); - - assertEquals("Polygons should be empty", 0, mapboxMap.getPolygons().size()); - - final PolylineOptions options = new PolylineOptions(); - options.color(Color.BLUE); - options.add(latLngOne); - options.add(latLngTwo); - - onView(withId(R.id.mapView)).perform(new AddPolyLineAction(mapboxMap, options)); - - assertEquals("Polylines should be 1", 1, mapboxMap.getPolylines().size()); - assertEquals("Polyline id should be 0", 0, polyline.getId()); - assertEquals("Polyline points size should match", 2, polyline.getPoints().size()); - assertEquals("Polyline stroke color should match", Color.BLUE, polyline.getColor()); - mapboxMap.clear(); - assertEquals("Polyline should be empty", 0, mapboxMap.getPolylines().size()); - } - - private class AddPolyLineAction implements ViewAction { - - private MapboxMap mapboxMap; - private PolylineOptions options; - - AddPolyLineAction(MapboxMap map, PolylineOptions polylineOptions) { - mapboxMap = map; - options = polylineOptions; - } - - @Override - public Matcher getConstraints() { - return isDisplayed(); - } - - @Override - public String getDescription() { - return getClass().getSimpleName(); - } - - @Override - public void perform(UiController uiController, View view) { - polyline = mapboxMap.addPolyline(options); - } + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + LatLng latLngOne = new LatLng(); + LatLng latLngTwo = new LatLng(1, 0); + + assertEquals("Polygons should be empty", 0, mapboxMap.getPolygons().size()); + + final PolylineOptions options = new PolylineOptions(); + options.color(Color.BLUE); + options.add(latLngOne); + options.add(latLngTwo); + Polyline polyline = mapboxMap.addPolyline(options); + + assertEquals("Polylines should be 1", 1, mapboxMap.getPolylines().size()); + assertEquals("Polyline id should be 0", 0, polyline.getId()); + assertEquals("Polyline points size should match", 2, polyline.getPoints().size()); + assertEquals("Polyline stroke color should match", Color.BLUE, polyline.getColor()); + mapboxMap.clear(); + assertEquals("Polyline should be empty", 0, mapboxMap.getPolylines().size()); + } + }); } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraAnimateTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraAnimateTest.java index af1a146ca2..c16c8f05bb 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraAnimateTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraAnimateTest.java @@ -2,27 +2,21 @@ package com.mapbox.mapboxsdk.testapp.camera; import android.graphics.PointF; import android.support.test.espresso.UiController; -import android.support.test.espresso.ViewAction; -import android.view.View; import com.mapbox.mapboxsdk.camera.CameraPosition; -import com.mapbox.mapboxsdk.camera.CameraUpdate; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity; import com.mapbox.mapboxsdk.testapp.utils.TestConstants; -import org.hamcrest.Matcher; import org.junit.Ignore; import org.junit.Test; -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; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; import static org.junit.Assert.assertEquals; public class CameraAnimateTest extends BaseActivityTest { @@ -36,202 +30,199 @@ public class CameraAnimateTest extends BaseActivityTest { @Ignore public void testAnimateToCameraPositionTarget() { validateTestSetup(); - - /*TODO remove zoom #6474*/ - float zoom = 1.0f; - LatLng moveTarget = new LatLng(1, 1); - - CameraPosition initialPosition = new CameraPosition.Builder().target( - new LatLng()).zoom(zoom).bearing(0).tilt(0).build(); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Default camera position should match default", cameraPosition, initialPosition); - - onView(withId(R.id.mapView)).perform(new AnimateCameraAction(mapboxMap, CameraUpdateFactory.newLatLng(moveTarget))); - cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), - moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), - moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + float zoom = 1.0f; + LatLng moveTarget = new LatLng(1, 1); + CameraPosition initialPosition = new CameraPosition.Builder().target( + new LatLng()).zoom(zoom).bearing(0).tilt(0).build(); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Default camera position should match default", cameraPosition, initialPosition); + mapboxMap.animateCamera(CameraUpdateFactory.newLatLng(moveTarget)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), + moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); + assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), + moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); + } + }); } @Test @Ignore public void testAnimateToCameraPositionTargetZoom() { validateTestSetup(); - - final float moveZoom = 15.5f; - final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); - - onView(withId(R.id.mapView)).perform(new AnimateCameraAction(mapboxMap, - CameraUpdateFactory.newLatLngZoom(moveTarget, moveZoom))); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), - moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), - moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + final float moveZoom = 15.5f; + final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); + mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(moveTarget, moveZoom)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), + moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); + assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), + moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); + assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA); + } + }); } @Test @Ignore public void testAnimateToCameraPosition() { validateTestSetup(); - - final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); - final float moveZoom = 15.5f; - final float moveTilt = 45.5f; - final float moveBearing = 12.5f; - - onView(withId(R.id.mapView)).perform( - new AnimateCameraAction(mapboxMap, CameraUpdateFactory.newCameraPosition( - new CameraPosition.Builder() - .target(moveTarget) - .zoom(moveZoom) - .tilt(moveTilt) - .bearing(moveBearing) - .build())) - ); - - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), - moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), - moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA); - assertEquals("Moved zoom should match", cameraPosition.tilt, moveTilt, TestConstants.TILT_DELTA); - assertEquals("Moved bearing should match", cameraPosition.bearing, moveBearing, TestConstants.BEARING_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); + final float moveZoom = 15.5f; + final float moveTilt = 45.5f; + final float moveBearing = 12.5f; + + mapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition( + new CameraPosition.Builder() + .target(moveTarget) + .zoom(moveZoom) + .tilt(moveTilt) + .bearing(moveBearing) + .build()) + ); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), + moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); + assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), + moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); + assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA); + assertEquals("Moved zoom should match", cameraPosition.tilt, moveTilt, TestConstants.TILT_DELTA); + assertEquals("Moved bearing should match", cameraPosition.bearing, moveBearing, TestConstants.BEARING_DELTA); + } + }); } @Test @Ignore public void testAnimateToBounds() { validateTestSetup(); - - final LatLng centerBounds = new LatLng(1, 1); - LatLng cornerOne = new LatLng(); - LatLng cornerTwo = new LatLng(2, 2); - - final LatLngBounds.Builder builder = new LatLngBounds.Builder(); - builder.include(cornerOne); - builder.include(cornerTwo); - - onView(withId(R.id.mapView)).perform(new AnimateCameraAction(mapboxMap, - CameraUpdateFactory.newLatLngBounds(builder.build(), 0))); - - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera position latitude should match center bounds", - cameraPosition.target.getLatitude(), - centerBounds.getLatitude(), - TestConstants.LAT_LNG_DELTA); - - assertEquals("Moved camera position longitude should match center bounds", - cameraPosition.target.getLongitude(), - centerBounds.getLongitude(), - TestConstants.LAT_LNG_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + final LatLng centerBounds = new LatLng(1, 1); + LatLng cornerOne = new LatLng(); + LatLng cornerTwo = new LatLng(2, 2); + final LatLngBounds.Builder builder = new LatLngBounds.Builder(); + builder.include(cornerOne); + builder.include(cornerTwo); + mapboxMap.animateCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 0)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera position latitude should match center bounds", + cameraPosition.target.getLatitude(), + centerBounds.getLatitude(), + TestConstants.LAT_LNG_DELTA); + assertEquals("Moved camera position longitude should match center bounds", + cameraPosition.target.getLongitude(), + centerBounds.getLongitude(), + TestConstants.LAT_LNG_DELTA); + } + }); } @Test @Ignore public void testAnimateToMoveBy() { validateTestSetup(); - - final PointF centerPoint = mapboxMap.getProjection().toScreenLocation(mapboxMap.getCameraPosition().target); - final LatLng moveTarget = new LatLng(2, 2); - final PointF moveTargetPoint = mapboxMap.getProjection().toScreenLocation(moveTarget); - - onView(withId(R.id.mapView)).perform(new AnimateCameraAction(mapboxMap, CameraUpdateFactory.scrollBy( - moveTargetPoint.x - centerPoint.x, moveTargetPoint.y - centerPoint.y))); - - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), - moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA_LARGE); - assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), - moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA_LARGE); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + final PointF centerPoint = mapboxMap.getProjection().toScreenLocation(mapboxMap.getCameraPosition().target); + final LatLng moveTarget = new LatLng(2, 2); + final PointF moveTargetPoint = mapboxMap.getProjection().toScreenLocation(moveTarget); + mapboxMap.animateCamera(CameraUpdateFactory.scrollBy( + moveTargetPoint.x - centerPoint.x, moveTargetPoint.y - centerPoint.y)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), + moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA_LARGE); + assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), + moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA_LARGE); + } + }); } @Test @Ignore public void testAnimateToZoomIn() { validateTestSetup(); - - /*TODO fix zoom #6474*/ - float zoom = 1.0f; - - onView(withId(R.id.mapView)).perform(new AnimateCameraAction(mapboxMap, CameraUpdateFactory.zoomIn())); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom + 1, - TestConstants.ZOOM_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + float zoom = 1.0f; + mapboxMap.animateCamera(CameraUpdateFactory.zoomIn()); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom + 1, + TestConstants.ZOOM_DELTA); + } + }); } @Test @Ignore public void testAnimateToZoomOut() { validateTestSetup(); - - /*TODO fix zoom #6474*/ - float zoom = 10.0f; - onView(withId(R.id.mapView)).perform(new AnimateCameraAction(mapboxMap, - CameraUpdateFactory.newLatLngZoom(new LatLng(), zoom))); - onView(withId(R.id.mapView)).perform(new AnimateCameraAction(mapboxMap, CameraUpdateFactory.zoomOut())); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom - 1, - TestConstants.ZOOM_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + float zoom = 10.0f; + mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(), zoom)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + mapboxMap.animateCamera(CameraUpdateFactory.zoomOut()); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom - 1, + TestConstants.ZOOM_DELTA); + } + }); } @Test @Ignore public void testAnimateToZoomBy() { validateTestSetup(); - - /*TODO fix zoom #6474*/ - float zoom = 1.0f; - final float zoomBy = 2.45f; - - onView(withId(R.id.mapView)).perform(new AnimateCameraAction(mapboxMap, CameraUpdateFactory.zoomBy(zoomBy))); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom + zoomBy, - TestConstants.ZOOM_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + float zoom = 1.0f; + final float zoomBy = 2.45f; + mapboxMap.animateCamera(CameraUpdateFactory.zoomBy(zoomBy)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom + zoomBy, + TestConstants.ZOOM_DELTA); + } + }); } @Test @Ignore public void testAnimateToZoomTo() { validateTestSetup(); - - /*TODO fix zoom #6474*/ - final float zoomTo = 2.45f; - - onView(withId(R.id.mapView)).perform(new AnimateCameraAction(mapboxMap, CameraUpdateFactory.zoomTo(zoomTo))); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoomTo, - TestConstants.ZOOM_DELTA); - } - - private class AnimateCameraAction implements ViewAction { - - private MapboxMap mapboxMap; - private CameraUpdate cameraUpdate; - - AnimateCameraAction(MapboxMap map, CameraUpdate update) { - mapboxMap = map; - cameraUpdate = update; - } - - @Override - public Matcher getConstraints() { - return isDisplayed(); - } - - @Override - public String getDescription() { - return getClass().getSimpleName(); - } - - @Override - public void perform(UiController uiController, View view) { - mapboxMap.animateCamera(cameraUpdate); - uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); - } + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + final float zoomTo = 2.45f; + mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(zoomTo)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoomTo, + TestConstants.ZOOM_DELTA); + } + }); } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraEaseTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraEaseTest.java index 4fae894039..8c67af7da3 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraEaseTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraEaseTest.java @@ -2,27 +2,21 @@ package com.mapbox.mapboxsdk.testapp.camera; import android.graphics.PointF; import android.support.test.espresso.UiController; -import android.support.test.espresso.ViewAction; -import android.view.View; import com.mapbox.mapboxsdk.camera.CameraPosition; -import com.mapbox.mapboxsdk.camera.CameraUpdate; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity; import com.mapbox.mapboxsdk.testapp.utils.TestConstants; -import org.hamcrest.Matcher; import org.junit.Ignore; import org.junit.Test; -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; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; import static org.junit.Assert.assertEquals; public class CameraEaseTest extends BaseActivityTest { @@ -36,201 +30,198 @@ public class CameraEaseTest extends BaseActivityTest { @Ignore public void testEaseToCameraPositionTarget() { validateTestSetup(); - - /*TODO remove zoom #6474*/ - float zoom = 1.0f; - LatLng moveTarget = new LatLng(1, 1); - - CameraPosition initialPosition = new CameraPosition.Builder().target( - new LatLng()).zoom(zoom).bearing(0).tilt(0).build(); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Default camera position should match default", cameraPosition, initialPosition); - - onView(withId(R.id.mapView)).perform(new EaseCameraAction(mapboxMap, CameraUpdateFactory.newLatLng(moveTarget))); - cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), - moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), - moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + float zoom = 1.0f; + LatLng moveTarget = new LatLng(1, 1); + CameraPosition initialPosition = new CameraPosition.Builder().target( + new LatLng()).zoom(zoom).bearing(0).tilt(0).build(); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Default camera position should match default", cameraPosition, initialPosition); + mapboxMap.easeCamera(CameraUpdateFactory.newLatLng(moveTarget)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), + moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); + assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), + moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); + } + }); } @Test @Ignore public void testEaseToCameraPositionTargetZoom() { validateTestSetup(); - - final float moveZoom = 15.5f; - final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); - - onView(withId(R.id.mapView)).perform(new EaseCameraAction(mapboxMap, - CameraUpdateFactory.newLatLngZoom(moveTarget, moveZoom))); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), - moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), - moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + final float moveZoom = 15.5f; + final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); + mapboxMap.easeCamera(CameraUpdateFactory.newLatLngZoom(moveTarget, moveZoom)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), + moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); + assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), + moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); + assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA); + } + }); } @Test @Ignore public void testEaseToCameraPosition() { validateTestSetup(); - - final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); - final float moveZoom = 15.5f; - final float moveTilt = 45.5f; - final float moveBearing = 12.5f; - - onView(withId(R.id.mapView)).perform( - new EaseCameraAction(mapboxMap, CameraUpdateFactory.newCameraPosition( - new CameraPosition.Builder() - .target(moveTarget) - .zoom(moveZoom) - .tilt(moveTilt) - .bearing(moveBearing) - .build())) - ); - - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), - moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), - moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA); - assertEquals("Moved zoom should match", cameraPosition.tilt, moveTilt, TestConstants.TILT_DELTA); - assertEquals("Moved bearing should match", cameraPosition.bearing, moveBearing, TestConstants.BEARING_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); + final float moveZoom = 15.5f; + final float moveTilt = 45.5f; + final float moveBearing = 12.5f; + + mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition( + new CameraPosition.Builder() + .target(moveTarget) + .zoom(moveZoom) + .tilt(moveTilt) + .bearing(moveBearing) + .build()) + ); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), + moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); + assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), + moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); + assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA); + assertEquals("Moved zoom should match", cameraPosition.tilt, moveTilt, TestConstants.TILT_DELTA); + assertEquals("Moved bearing should match", cameraPosition.bearing, moveBearing, TestConstants.BEARING_DELTA); + } + }); } @Test @Ignore public void testEaseToBounds() { validateTestSetup(); - - final LatLng centerBounds = new LatLng(1, 1); - LatLng cornerOne = new LatLng(); - LatLng cornerTwo = new LatLng(2, 2); - - final LatLngBounds.Builder builder = new LatLngBounds.Builder(); - builder.include(cornerOne); - builder.include(cornerTwo); - - onView(withId(R.id.mapView)).perform(new EaseCameraAction(mapboxMap, - CameraUpdateFactory.newLatLngBounds(builder.build(), 0))); - - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera position latitude should match center bounds", - cameraPosition.target.getLatitude(), - centerBounds.getLatitude(), - TestConstants.LAT_LNG_DELTA); - - assertEquals("Moved camera position longitude should match center bounds", - cameraPosition.target.getLongitude(), - centerBounds.getLongitude(), - TestConstants.LAT_LNG_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + final LatLng centerBounds = new LatLng(1, 1); + LatLng cornerOne = new LatLng(); + LatLng cornerTwo = new LatLng(2, 2); + final LatLngBounds.Builder builder = new LatLngBounds.Builder(); + builder.include(cornerOne); + builder.include(cornerTwo); + mapboxMap.easeCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 0)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera position latitude should match center bounds", + cameraPosition.target.getLatitude(), + centerBounds.getLatitude(), + TestConstants.LAT_LNG_DELTA); + assertEquals("Moved camera position longitude should match center bounds", + cameraPosition.target.getLongitude(), + centerBounds.getLongitude(), + TestConstants.LAT_LNG_DELTA); + } + }); } @Test @Ignore public void testEaseToMoveBy() { validateTestSetup(); - - final PointF centerPoint = mapboxMap.getProjection().toScreenLocation(mapboxMap.getCameraPosition().target); - final LatLng moveTarget = new LatLng(2, 2); - final PointF moveTargetPoint = mapboxMap.getProjection().toScreenLocation(moveTarget); - - onView(withId(R.id.mapView)).perform(new EaseCameraAction(mapboxMap, CameraUpdateFactory.scrollBy( - moveTargetPoint.x - centerPoint.x, moveTargetPoint.y - centerPoint.y))); - - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), - moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA_LARGE); - assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), - moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA_LARGE); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + final PointF centerPoint = mapboxMap.getProjection().toScreenLocation(mapboxMap.getCameraPosition().target); + final LatLng moveTarget = new LatLng(2, 2); + final PointF moveTargetPoint = mapboxMap.getProjection().toScreenLocation(moveTarget); + mapboxMap.easeCamera(CameraUpdateFactory.scrollBy( + moveTargetPoint.x - centerPoint.x, moveTargetPoint.y - centerPoint.y)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), + moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA_LARGE); + assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), + moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA_LARGE); + } + }); } @Test @Ignore public void testEaseToZoomIn() { validateTestSetup(); - - /*TODO fix zoom #6474*/ - float zoom = 1.0f; - - onView(withId(R.id.mapView)).perform(new EaseCameraAction(mapboxMap, CameraUpdateFactory.zoomIn())); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom + 1, - TestConstants.ZOOM_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + float zoom = 1.0f; + mapboxMap.easeCamera(CameraUpdateFactory.zoomIn()); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom + 1, + TestConstants.ZOOM_DELTA); + } + }); } @Test @Ignore public void testEaseToZoomOut() { validateTestSetup(); - - /*TODO fix zoom #6474*/ - float zoom = 10.0f; - onView(withId(R.id.mapView)).perform(new EaseCameraAction(mapboxMap, - CameraUpdateFactory.newLatLngZoom(new LatLng(), zoom))); - onView(withId(R.id.mapView)).perform(new EaseCameraAction(mapboxMap, CameraUpdateFactory.zoomOut())); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera zoom should match moved camera zoom", 9, cameraPosition.zoom, TestConstants.ZOOM_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + float zoom = 10.0f; + mapboxMap.easeCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(), zoom)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + mapboxMap.easeCamera(CameraUpdateFactory.zoomOut()); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom - 1, + TestConstants.ZOOM_DELTA); + } + }); } @Test @Ignore public void testEaseToZoomBy() { validateTestSetup(); - - /*TODO fix zoom #6474*/ - float zoom = 1.0f; - final float zoomBy = 2.45f; - - onView(withId(R.id.mapView)).perform(new EaseCameraAction(mapboxMap, CameraUpdateFactory.zoomBy(zoomBy))); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom + zoomBy, - TestConstants.ZOOM_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + float zoom = 1.0f; + final float zoomBy = 2.45f; + mapboxMap.easeCamera(CameraUpdateFactory.zoomBy(zoomBy)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom + zoomBy, + TestConstants.ZOOM_DELTA); + } + }); } @Test @Ignore public void testEaseToZoomTo() { validateTestSetup(); - - /*TODO fix zoom #6474*/ - final float zoomTo = 2.45f; - - onView(withId(R.id.mapView)).perform(new EaseCameraAction(mapboxMap, CameraUpdateFactory.zoomTo(zoomTo))); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoomTo, - TestConstants.ZOOM_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + final float zoomTo = 2.45f; + mapboxMap.easeCamera(CameraUpdateFactory.zoomTo(zoomTo)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoomTo, + TestConstants.ZOOM_DELTA); + } + }); } - - private class EaseCameraAction implements ViewAction { - - private MapboxMap mapboxMap; - private CameraUpdate cameraUpdate; - - EaseCameraAction(MapboxMap map, CameraUpdate update) { - mapboxMap = map; - cameraUpdate = update; - } - - @Override - public Matcher getConstraints() { - return isDisplayed(); - } - - @Override - public String getDescription() { - return getClass().getSimpleName(); - } - - @Override - public void perform(UiController uiController, View view) { - mapboxMap.easeCamera(cameraUpdate); - uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); - } - } -} - +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraMoveTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraMoveTest.java index ea8398fc8e..54590981fa 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraMoveTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraMoveTest.java @@ -2,27 +2,21 @@ package com.mapbox.mapboxsdk.testapp.camera; import android.graphics.PointF; import android.support.test.espresso.UiController; -import android.support.test.espresso.ViewAction; -import android.view.View; import com.mapbox.mapboxsdk.camera.CameraPosition; -import com.mapbox.mapboxsdk.camera.CameraUpdate; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity; import com.mapbox.mapboxsdk.testapp.utils.TestConstants; -import org.hamcrest.Matcher; import org.junit.Ignore; import org.junit.Test; -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; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; import static org.junit.Assert.assertEquals; public class CameraMoveTest extends BaseActivityTest { @@ -36,201 +30,199 @@ public class CameraMoveTest extends BaseActivityTest { @Ignore public void testMoveToCameraPositionTarget() { validateTestSetup(); - - /*TODO remove zoom #6474*/ - float zoom = 1.0f; - LatLng moveTarget = new LatLng(1, 1); - - CameraPosition initialPosition = new CameraPosition.Builder().target( - new LatLng()).zoom(zoom).bearing(0).tilt(0).build(); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Default camera position should match default", cameraPosition, initialPosition); - - onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap, CameraUpdateFactory.newLatLng(moveTarget))); - cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), - moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), - moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + float zoom = 1.0f; + LatLng moveTarget = new LatLng(1, 1); + CameraPosition initialPosition = new CameraPosition.Builder().target( + new LatLng()).zoom(zoom).bearing(0).tilt(0).build(); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Default camera position should match default", cameraPosition, initialPosition); + mapboxMap.moveCamera(CameraUpdateFactory.newLatLng(moveTarget)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), + moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); + assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), + moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); + } + }); } @Test @Ignore public void testMoveToCameraPositionTargetZoom() { validateTestSetup(); - - final float moveZoom = 15.5f; - final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); - - onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap, - CameraUpdateFactory.newLatLngZoom(moveTarget, moveZoom))); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), - moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), - moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + final float moveZoom = 15.5f; + final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(moveTarget, moveZoom)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), + moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); + assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), + moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); + assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA); + } + }); } @Test @Ignore public void testMoveToCameraPosition() { validateTestSetup(); - - final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); - final float moveZoom = 15.5f; - final float moveTilt = 45.5f; - final float moveBearing = 12.5f; - - onView(withId(R.id.mapView)).perform( - new MoveCameraAction(mapboxMap, CameraUpdateFactory.newCameraPosition( - new CameraPosition.Builder() - .target(moveTarget) - .zoom(moveZoom) - .tilt(moveTilt) - .bearing(moveBearing) - .build())) - ); - - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), - moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), - moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA); - assertEquals("Moved zoom should match", cameraPosition.tilt, moveTilt, TestConstants.TILT_DELTA); - assertEquals("Moved bearing should match", cameraPosition.bearing, moveBearing, TestConstants.BEARING_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); + final float moveZoom = 15.5f; + final float moveTilt = 45.5f; + final float moveBearing = 12.5f; + + mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition( + new CameraPosition.Builder() + .target(moveTarget) + .zoom(moveZoom) + .tilt(moveTilt) + .bearing(moveBearing) + .build()) + ); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), + moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); + assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), + moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); + assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA); + assertEquals("Moved zoom should match", cameraPosition.tilt, moveTilt, TestConstants.TILT_DELTA); + assertEquals("Moved bearing should match", cameraPosition.bearing, moveBearing, TestConstants.BEARING_DELTA); + } + }); } @Test @Ignore public void testMoveToBounds() { validateTestSetup(); - - final LatLng centerBounds = new LatLng(1, 1); - LatLng cornerOne = new LatLng(); - LatLng cornerTwo = new LatLng(2, 2); - - final LatLngBounds.Builder builder = new LatLngBounds.Builder(); - builder.include(cornerOne); - builder.include(cornerTwo); - - onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap, - CameraUpdateFactory.newLatLngBounds(builder.build(), 0))); - - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera position latitude should match center bounds", - cameraPosition.target.getLatitude(), - centerBounds.getLatitude(), - TestConstants.LAT_LNG_DELTA); - - assertEquals("Moved camera position longitude should match center bounds", - cameraPosition.target.getLongitude(), - centerBounds.getLongitude(), - TestConstants.LAT_LNG_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + final LatLng centerBounds = new LatLng(1, 1); + LatLng cornerOne = new LatLng(); + LatLng cornerTwo = new LatLng(2, 2); + final LatLngBounds.Builder builder = new LatLngBounds.Builder(); + builder.include(cornerOne); + builder.include(cornerTwo); + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 0)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera position latitude should match center bounds", + cameraPosition.target.getLatitude(), + centerBounds.getLatitude(), + TestConstants.LAT_LNG_DELTA); + assertEquals("Moved camera position longitude should match center bounds", + cameraPosition.target.getLongitude(), + centerBounds.getLongitude(), + TestConstants.LAT_LNG_DELTA); + } + }); } @Test @Ignore public void testMoveToMoveBy() { validateTestSetup(); - - final PointF centerPoint = mapboxMap.getProjection().toScreenLocation(mapboxMap.getCameraPosition().target); - final LatLng moveTarget = new LatLng(2, 2); - final PointF moveTargetPoint = mapboxMap.getProjection().toScreenLocation(moveTarget); - - onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap, CameraUpdateFactory.scrollBy( - moveTargetPoint.x - centerPoint.x, moveTargetPoint.y - centerPoint.y))); - - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), - moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA_LARGE); - assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), - moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA_LARGE); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + final PointF centerPoint = mapboxMap.getProjection().toScreenLocation(mapboxMap.getCameraPosition().target); + final LatLng moveTarget = new LatLng(2, 2); + final PointF moveTargetPoint = mapboxMap.getProjection().toScreenLocation(moveTarget); + mapboxMap.moveCamera(CameraUpdateFactory.scrollBy( + moveTargetPoint.x - centerPoint.x, moveTargetPoint.y - centerPoint.y)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), + moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA_LARGE); + assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), + moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA_LARGE); + } + }); } @Test @Ignore public void testMoveToZoomIn() { validateTestSetup(); - - /*TODO fix zoom #6474*/ - float zoom = 1.0f; - - onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap, CameraUpdateFactory.zoomIn())); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom + 1, - TestConstants.ZOOM_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + float zoom = 1.0f; + mapboxMap.moveCamera(CameraUpdateFactory.zoomIn()); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom + 1, + TestConstants.ZOOM_DELTA); + } + }); } @Test @Ignore public void testMoveToZoomOut() { validateTestSetup(); - - /*TODO fix zoom #6474*/ - float zoom = 10.0f; - onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap, - CameraUpdateFactory.newLatLngZoom(new LatLng(), zoom))); - onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap, CameraUpdateFactory.zoomOut())); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom - 1, - TestConstants.ZOOM_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + float zoom = 10.0f; + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(), zoom)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + mapboxMap.moveCamera(CameraUpdateFactory.zoomOut()); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom - 1, + TestConstants.ZOOM_DELTA); + } + }); } @Test @Ignore public void testMoveToZoomBy() { validateTestSetup(); - - /*TODO fix zoom #6474*/ - float zoom = 1.0f; - final float zoomBy = 2.45f; - - onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap, CameraUpdateFactory.zoomBy(zoomBy))); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom + zoomBy, - TestConstants.ZOOM_DELTA); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + float zoom = 1.0f; + final float zoomBy = 2.45f; + mapboxMap.moveCamera(CameraUpdateFactory.zoomBy(zoomBy)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom + zoomBy, + TestConstants.ZOOM_DELTA); + } + }); } @Test @Ignore public void testMoveToZoomTo() { validateTestSetup(); - - /*TODO fix zoom #6474*/ - final float zoomTo = 2.45f; - - onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap, CameraUpdateFactory.zoomTo(zoomTo))); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoomTo, - TestConstants.ZOOM_DELTA); - } - - private class MoveCameraAction implements ViewAction { - - private MapboxMap mapboxMap; - private CameraUpdate cameraUpdate; - - MoveCameraAction(MapboxMap map, CameraUpdate update) { - mapboxMap = map; - cameraUpdate = update; - } - - @Override - public Matcher getConstraints() { - return isDisplayed(); - } - - @Override - public String getDescription() { - return getClass().getSimpleName(); - } - - @Override - public void perform(UiController uiController, View view) { - mapboxMap.moveCamera(cameraUpdate); - uiController.loopMainThreadForAtLeast(100); - } + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + final float zoomTo = 2.45f; + mapboxMap.moveCamera(CameraUpdateFactory.zoomTo(zoomTo)); + uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoomTo, + TestConstants.ZOOM_DELTA); + } + }); } } + 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 f15605042b..28389a3386 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 @@ -1,20 +1,17 @@ package com.mapbox.mapboxsdk.testapp.maps.widgets; import android.support.test.espresso.UiController; -import android.support.test.espresso.ViewAction; -import android.view.View; import com.mapbox.mapboxsdk.camera.CameraPosition; -import com.mapbox.mapboxsdk.camera.CameraUpdate; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity; import com.mapbox.mapboxsdk.testapp.utils.TestConstants; -import org.hamcrest.Matcher; import org.junit.Ignore; import org.junit.Test; @@ -23,6 +20,7 @@ import static android.support.test.espresso.action.ViewActions.click; 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 static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertEquals; @@ -40,96 +38,51 @@ public class CompassViewTest extends BaseActivityTest { } @Test + @Ignore public void testVisible() { validateTestSetup(); - - onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap, - CameraUpdateFactory.newCameraPosition( + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition( new CameraPosition.Builder() .bearing(45) .zoom(1) .target(new LatLng()) .build() - ) - ) - ); - waitLoop(); + )); + uiController.loopMainThreadForAtLeast(500); + } + }); onView(withId(R.id.compassView)).check(matches(isDisplayed())); } @Test - @Ignore // 10-31-2016 click action is not working + @Ignore public void testClick() { validateTestSetup(); - - onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap, - CameraUpdateFactory.newCameraPosition( + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition( new CameraPosition.Builder() .bearing(45) .zoom(1) .target(new LatLng()) .build() - ) - ) - ); - - waitLoop(); + )); + } + }); onView(withId(R.id.compassView)).perform(click()); - onView(withId(R.id.mapView)).perform(new WaitAction(3000)); + waitLoop(); onView(withId(R.id.compassView)).check(matches(not(isDisplayed()))); - - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Camera bearing should face north, ", 0, cameraPosition.bearing, TestConstants.BEARING_DELTA); - } - - private class WaitAction implements ViewAction { - - private long waitTime; - - WaitAction(long waitTime) { - this.waitTime = waitTime; - } - - @Override - public Matcher getConstraints() { - return isDisplayed(); - } - - @Override - public String getDescription() { - return getClass().getSimpleName(); - } - - @Override - public void perform(UiController uiController, View view) { - uiController.loopMainThreadForAtLeast(waitTime); - } - } - - private class MoveCameraAction implements ViewAction { - - private MapboxMap mapboxMap; - private CameraUpdate cameraUpdate; - - MoveCameraAction(MapboxMap map, CameraUpdate update) { - mapboxMap = map; - cameraUpdate = update; - } - - @Override - public Matcher getConstraints() { - return isDisplayed(); - } - - @Override - public String getDescription() { - return getClass().getSimpleName(); - } - - @Override - public void perform(UiController uiController, View view) { - mapboxMap.moveCamera(cameraUpdate); - } + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Camera bearing should face north, ", 0, cameraPosition.bearing, TestConstants.BEARING_DELTA); + } + }); } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerTest.java index 851660f06e..0e4cf6a8ca 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerTest.java @@ -3,9 +3,9 @@ package com.mapbox.mapboxsdk.testapp.style; import android.graphics.Color; -import android.support.test.espresso.Espresso; -import android.support.test.rule.ActivityTestRule; +import android.support.test.espresso.UiController; import android.support.test.runner.AndroidJUnit4; + import timber.log.Timber; import com.mapbox.mapboxsdk.maps.MapboxMap; @@ -19,20 +19,16 @@ import com.mapbox.mapboxsdk.style.functions.stops.IntervalStops; import com.mapbox.mapboxsdk.style.functions.stops.Stop; import com.mapbox.mapboxsdk.style.functions.stops.Stops; import com.mapbox.mapboxsdk.style.layers.BackgroundLayer; -import com.mapbox.mapboxsdk.testapp.R; -import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; -import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import static com.mapbox.mapboxsdk.style.functions.Function.*; import static com.mapbox.mapboxsdk.style.functions.stops.Stop.stop; import static com.mapbox.mapboxsdk.style.functions.stops.Stops.*; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; import static org.junit.Assert.*; import static com.mapbox.mapboxsdk.style.layers.Property.*; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; @@ -53,9 +49,14 @@ public class BackgroundLayerTest extends BaseActivityTest { return EspressoTestActivity.class; } - private void setupLayer(){ + private void setupLayer() { Timber.i("Retrieving layer"); - layer = mapboxMap.getLayerAs("background"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + layer = mapboxMap.getLayerAs("background"); + } + }); } @Test @@ -63,14 +64,19 @@ public class BackgroundLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("Visibility"); - assertNotNull(layer); - - // Get initial - assertEquals(layer.getVisibility().getValue(), VISIBLE); - - // Set - layer.setProperties(visibility(NONE)); - assertEquals(layer.getVisibility().getValue(), NONE); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + // Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + }); } @Test @@ -78,12 +84,17 @@ public class BackgroundLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("background-colorTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setBackgroundColorTransition(options); - assertEquals(layer.getBackgroundColorTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setBackgroundColorTransition(options); + assertEquals(layer.getBackgroundColorTransition(), options); + } + }); } @Test @@ -91,11 +102,16 @@ public class BackgroundLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("background-color"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(backgroundColor("rgba(0, 0, 0, 1)")); - assertEquals((String) layer.getBackgroundColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(backgroundColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getBackgroundColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + }); } @Test @@ -103,26 +119,31 @@ public class BackgroundLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("background-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - backgroundColor( - zoom( - exponential( - stop(2, backgroundColor("rgba(0, 0, 0, 1)")) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getBackgroundColor()); - assertNotNull(layer.getBackgroundColor().getFunction()); - assertEquals(CameraFunction.class, layer.getBackgroundColor().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getBackgroundColor().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getBackgroundColor().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getBackgroundColor().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + backgroundColor( + zoom( + exponential( + stop(2, backgroundColor("rgba(0, 0, 0, 1)")) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getBackgroundColor()); + assertNotNull(layer.getBackgroundColor().getFunction()); + assertEquals(CameraFunction.class, layer.getBackgroundColor().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getBackgroundColor().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getBackgroundColor().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getBackgroundColor().getFunction().getStops()).size()); + } + }); } @Test @@ -130,11 +151,16 @@ public class BackgroundLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("background-color"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(backgroundColor(Color.RED)); - assertEquals(layer.getBackgroundColorAsInt(), Color.RED); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(backgroundColor(Color.RED)); + assertEquals(layer.getBackgroundColorAsInt(), Color.RED); + } + }); } @Test @@ -142,12 +168,17 @@ public class BackgroundLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("background-patternTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setBackgroundPatternTransition(options); - assertEquals(layer.getBackgroundPatternTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setBackgroundPatternTransition(options); + assertEquals(layer.getBackgroundPatternTransition(), options); + } + }); } @Test @@ -155,11 +186,16 @@ public class BackgroundLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("background-pattern"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(backgroundPattern("pedestrian-polygon")); - assertEquals((String) layer.getBackgroundPattern().getValue(), (String) "pedestrian-polygon"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(backgroundPattern("pedestrian-polygon")); + assertEquals((String) layer.getBackgroundPattern().getValue(), (String) "pedestrian-polygon"); + } + }); } @Test @@ -167,25 +203,30 @@ public class BackgroundLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("background-pattern"); - assertNotNull(layer); - - // Set - layer.setProperties( - backgroundPattern( - zoom( - interval( - stop(2, backgroundPattern("pedestrian-polygon")) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + backgroundPattern( + zoom( + interval( + stop(2, backgroundPattern("pedestrian-polygon")) + ) + ) ) - ) - ) - ); - - // Verify - assertNotNull(layer.getBackgroundPattern()); - assertNotNull(layer.getBackgroundPattern().getFunction()); - assertEquals(CameraFunction.class, layer.getBackgroundPattern().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getBackgroundPattern().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getBackgroundPattern().getFunction().getStops()).size()); + ); + + // Verify + assertNotNull(layer.getBackgroundPattern()); + assertNotNull(layer.getBackgroundPattern().getFunction()); + assertEquals(CameraFunction.class, layer.getBackgroundPattern().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getBackgroundPattern().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getBackgroundPattern().getFunction().getStops()).size()); + } + }); } @Test @@ -193,12 +234,17 @@ public class BackgroundLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("background-opacityTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setBackgroundOpacityTransition(options); - assertEquals(layer.getBackgroundOpacityTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setBackgroundOpacityTransition(options); + assertEquals(layer.getBackgroundOpacityTransition(), options); + } + }); } @Test @@ -206,11 +252,16 @@ public class BackgroundLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("background-opacity"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(backgroundOpacity(0.3f)); - assertEquals((Float) layer.getBackgroundOpacity().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(backgroundOpacity(0.3f)); + assertEquals((Float) layer.getBackgroundOpacity().getValue(), (Float) 0.3f); + } + }); } @Test @@ -218,26 +269,31 @@ public class BackgroundLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("background-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - backgroundOpacity( - zoom( - exponential( - stop(2, backgroundOpacity(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getBackgroundOpacity()); - assertNotNull(layer.getBackgroundOpacity().getFunction()); - assertEquals(CameraFunction.class, layer.getBackgroundOpacity().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getBackgroundOpacity().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getBackgroundOpacity().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getBackgroundOpacity().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + backgroundOpacity( + zoom( + exponential( + stop(2, backgroundOpacity(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getBackgroundOpacity()); + assertNotNull(layer.getBackgroundOpacity().getFunction()); + assertEquals(CameraFunction.class, layer.getBackgroundOpacity().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getBackgroundOpacity().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getBackgroundOpacity().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getBackgroundOpacity().getFunction().getStops()).size()); + } + }); } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BaseStyleTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BaseStyleTest.java deleted file mode 100644 index 3d56752150..0000000000 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BaseStyleTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.mapbox.mapboxsdk.testapp.style; - -import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; -import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; - -/** - * Base Test class for Style tests - */ -public class BaseStyleTest extends BaseActivityTest { - - @Override - protected Class getActivityClass() { - return RuntimeStyleTestActivity.class; - } -} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java index bf31a935f8..c8f9640433 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java @@ -3,9 +3,9 @@ package com.mapbox.mapboxsdk.testapp.style; import android.graphics.Color; -import android.support.test.espresso.Espresso; -import android.support.test.rule.ActivityTestRule; +import android.support.test.espresso.UiController; import android.support.test.runner.AndroidJUnit4; + import timber.log.Timber; import com.mapbox.mapboxsdk.maps.MapboxMap; @@ -19,20 +19,16 @@ import com.mapbox.mapboxsdk.style.functions.stops.IntervalStops; import com.mapbox.mapboxsdk.style.functions.stops.Stop; import com.mapbox.mapboxsdk.style.functions.stops.Stops; import com.mapbox.mapboxsdk.style.layers.CircleLayer; -import com.mapbox.mapboxsdk.testapp.R; -import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; -import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import static com.mapbox.mapboxsdk.style.functions.Function.*; import static com.mapbox.mapboxsdk.style.functions.stops.Stop.stop; import static com.mapbox.mapboxsdk.style.functions.stops.Stops.*; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; import static org.junit.Assert.*; import static com.mapbox.mapboxsdk.style.layers.Property.*; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; @@ -53,15 +49,21 @@ public class CircleLayerTest extends BaseActivityTest { return EspressoTestActivity.class; } - private void setupLayer(){ - if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { - Timber.i("Adding layer"); - layer = new CircleLayer("my-layer", "composite"); - layer.setSourceLayer("composite"); - mapboxMap.addLayer(layer); - // Layer reference is now stale, get new reference - layer = mapboxMap.getLayerAs("my-layer"); - } + private void setupLayer() { + Timber.i("Retrieving layer"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Timber.i("Adding layer"); + layer = new CircleLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + // Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + } + }); } @Test @@ -69,14 +71,19 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("Visibility"); - assertNotNull(layer); - - // Get initial - assertEquals(layer.getVisibility().getValue(), VISIBLE); - - // Set - layer.setProperties(visibility(NONE)); - assertEquals(layer.getVisibility().getValue(), NONE); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + // Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + }); } @Test @@ -84,15 +91,20 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("SourceLayer"); - assertNotNull(layer); - - // Get initial - assertEquals(layer.getSourceLayer(), "composite"); - - // Set - final String sourceLayer = "test"; - layer.setSourceLayer(sourceLayer); - assertEquals(layer.getSourceLayer(), sourceLayer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Get initial + assertEquals(layer.getSourceLayer(), "composite"); + + // Set + final String sourceLayer = "test"; + layer.setSourceLayer(sourceLayer); + assertEquals(layer.getSourceLayer(), sourceLayer); + } + }); } @Test @@ -100,12 +112,17 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-radiusTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setCircleRadiusTransition(options); - assertEquals(layer.getCircleRadiusTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setCircleRadiusTransition(options); + assertEquals(layer.getCircleRadiusTransition(), options); + } + }); } @Test @@ -113,11 +130,16 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-radius"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(circleRadius(0.3f)); - assertEquals((Float) layer.getCircleRadius().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(circleRadius(0.3f)); + assertEquals((Float) layer.getCircleRadius().getValue(), (Float) 0.3f); + } + }); } @Test @@ -125,26 +147,31 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-radius"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleRadius( - zoom( - exponential( - stop(2, circleRadius(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getCircleRadius()); - assertNotNull(layer.getCircleRadius().getFunction()); - assertEquals(CameraFunction.class, layer.getCircleRadius().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getCircleRadius().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getCircleRadius().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getCircleRadius().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleRadius( + zoom( + exponential( + stop(2, circleRadius(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getCircleRadius()); + assertNotNull(layer.getCircleRadius().getFunction()); + assertEquals(CameraFunction.class, layer.getCircleRadius().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getCircleRadius().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getCircleRadius().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getCircleRadius().getFunction().getStops()).size()); + } + }); } @Test @@ -152,19 +179,24 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-radius"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleRadius(property("FeaturePropertyA", Stops.identity())) - ); - - // Verify - assertNotNull(layer.getCircleRadius()); - assertNotNull(layer.getCircleRadius().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleRadius().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleRadius().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getCircleRadius().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleRadius(property("FeaturePropertyA", Stops.identity())) + ); + + // Verify + assertNotNull(layer.getCircleRadius()); + assertNotNull(layer.getCircleRadius().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleRadius().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleRadius().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getCircleRadius().getFunction().getStops().getClass()); + } + }); } @Test @@ -172,26 +204,31 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-radius"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleRadius( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, circleRadius(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getCircleRadius()); - assertNotNull(layer.getCircleRadius().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleRadius().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleRadius().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getCircleRadius().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleRadius( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, circleRadius(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getCircleRadius()); + assertNotNull(layer.getCircleRadius().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleRadius().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleRadius().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getCircleRadius().getFunction().getStops().getClass()); + } + }); } @Test @@ -199,29 +236,35 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-radius"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleRadius( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, circleRadius(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleRadius( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, circleRadius(0.3f)) + ) + ).withDefaultValue(circleRadius(0.3f)) ) - ).withDefaultValue(circleRadius(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getCircleRadius()); - assertNotNull(layer.getCircleRadius().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleRadius().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleRadius().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getCircleRadius().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getCircleRadius().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getCircleRadius().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getCircleRadius().getFunction()).getDefaultValue().getValue()); + ); + + // Verify + assertNotNull(layer.getCircleRadius()); + assertNotNull(layer.getCircleRadius().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleRadius().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleRadius().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getCircleRadius().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getCircleRadius().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getCircleRadius().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getCircleRadius().getFunction()).getDefaultValue().getValue()); + } + }); + } @Test @@ -229,34 +272,39 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-radius"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleRadius( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, circleRadius(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(circleRadius(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getCircleRadius()); - assertNotNull(layer.getCircleRadius().getFunction()); - assertEquals(CompositeFunction.class, layer.getCircleRadius().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getCircleRadius().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getCircleRadius().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getCircleRadius().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getCircleRadius().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleRadius( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, circleRadius(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(circleRadius(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getCircleRadius()); + assertNotNull(layer.getCircleRadius().getFunction()); + assertEquals(CompositeFunction.class, layer.getCircleRadius().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getCircleRadius().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getCircleRadius().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getCircleRadius().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getCircleRadius().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -264,12 +312,17 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-colorTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setCircleColorTransition(options); - assertEquals(layer.getCircleColorTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setCircleColorTransition(options); + assertEquals(layer.getCircleColorTransition(), options); + } + }); } @Test @@ -277,11 +330,16 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-color"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(circleColor("rgba(0, 0, 0, 1)")); - assertEquals((String) layer.getCircleColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(circleColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getCircleColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + }); } @Test @@ -289,26 +347,31 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleColor( - zoom( - exponential( - stop(2, circleColor("rgba(0, 0, 0, 1)")) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getCircleColor()); - assertNotNull(layer.getCircleColor().getFunction()); - assertEquals(CameraFunction.class, layer.getCircleColor().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getCircleColor().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getCircleColor().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getCircleColor().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleColor( + zoom( + exponential( + stop(2, circleColor("rgba(0, 0, 0, 1)")) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getCircleColor()); + assertNotNull(layer.getCircleColor().getFunction()); + assertEquals(CameraFunction.class, layer.getCircleColor().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getCircleColor().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getCircleColor().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getCircleColor().getFunction().getStops()).size()); + } + }); } @Test @@ -316,19 +379,24 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleColor(property("FeaturePropertyA", Stops.identity())) - ); - - // Verify - assertNotNull(layer.getCircleColor()); - assertNotNull(layer.getCircleColor().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleColor().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getCircleColor().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleColor(property("FeaturePropertyA", Stops.identity())) + ); + + // Verify + assertNotNull(layer.getCircleColor()); + assertNotNull(layer.getCircleColor().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleColor().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getCircleColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -336,26 +404,31 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleColor( - property( - "FeaturePropertyA", - exponential( - stop(Color.RED, circleColor(Color.RED)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getCircleColor()); - assertNotNull(layer.getCircleColor().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleColor().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getCircleColor().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleColor( + property( + "FeaturePropertyA", + exponential( + stop(Color.RED, circleColor(Color.RED)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getCircleColor()); + assertNotNull(layer.getCircleColor().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleColor().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getCircleColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -363,29 +436,35 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleColor( - property( - "FeaturePropertyA", - categorical( - stop("valueA", circleColor(Color.RED)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleColor( + property( + "FeaturePropertyA", + categorical( + stop("valueA", circleColor(Color.RED)) + ) + ).withDefaultValue(circleColor(Color.GREEN)) ) - ).withDefaultValue(circleColor(Color.GREEN)) - ) - ); - - // Verify - assertNotNull(layer.getCircleColor()); - assertNotNull(layer.getCircleColor().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleColor().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getCircleColor().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getCircleColor().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getCircleColor().getFunction()).getDefaultValue().getValue()); - assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getCircleColor().getFunction()).getDefaultValue().getColorInt()); + ); + + // Verify + assertNotNull(layer.getCircleColor()); + assertNotNull(layer.getCircleColor().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleColor().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getCircleColor().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getCircleColor().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getCircleColor().getFunction()).getDefaultValue().getValue()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getCircleColor().getFunction()).getDefaultValue().getColorInt()); + } + }); + } @Test @@ -393,11 +472,16 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-color"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(circleColor(Color.RED)); - assertEquals(layer.getCircleColorAsInt(), Color.RED); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(circleColor(Color.RED)); + assertEquals(layer.getCircleColorAsInt(), Color.RED); + } + }); } @Test @@ -405,12 +489,17 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-blurTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setCircleBlurTransition(options); - assertEquals(layer.getCircleBlurTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setCircleBlurTransition(options); + assertEquals(layer.getCircleBlurTransition(), options); + } + }); } @Test @@ -418,11 +507,16 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-blur"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(circleBlur(0.3f)); - assertEquals((Float) layer.getCircleBlur().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(circleBlur(0.3f)); + assertEquals((Float) layer.getCircleBlur().getValue(), (Float) 0.3f); + } + }); } @Test @@ -430,26 +524,31 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-blur"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleBlur( - zoom( - exponential( - stop(2, circleBlur(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getCircleBlur()); - assertNotNull(layer.getCircleBlur().getFunction()); - assertEquals(CameraFunction.class, layer.getCircleBlur().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getCircleBlur().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getCircleBlur().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getCircleBlur().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleBlur( + zoom( + exponential( + stop(2, circleBlur(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getCircleBlur()); + assertNotNull(layer.getCircleBlur().getFunction()); + assertEquals(CameraFunction.class, layer.getCircleBlur().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getCircleBlur().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getCircleBlur().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getCircleBlur().getFunction().getStops()).size()); + } + }); } @Test @@ -457,19 +556,24 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-blur"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleBlur(property("FeaturePropertyA", Stops.identity())) - ); - - // Verify - assertNotNull(layer.getCircleBlur()); - assertNotNull(layer.getCircleBlur().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleBlur().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleBlur().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getCircleBlur().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleBlur(property("FeaturePropertyA", Stops.identity())) + ); + + // Verify + assertNotNull(layer.getCircleBlur()); + assertNotNull(layer.getCircleBlur().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleBlur().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleBlur().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getCircleBlur().getFunction().getStops().getClass()); + } + }); } @Test @@ -477,26 +581,31 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-blur"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleBlur( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, circleBlur(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getCircleBlur()); - assertNotNull(layer.getCircleBlur().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleBlur().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleBlur().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getCircleBlur().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleBlur( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, circleBlur(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getCircleBlur()); + assertNotNull(layer.getCircleBlur().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleBlur().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleBlur().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getCircleBlur().getFunction().getStops().getClass()); + } + }); } @Test @@ -504,29 +613,35 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-blur"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleBlur( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, circleBlur(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleBlur( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, circleBlur(0.3f)) + ) + ).withDefaultValue(circleBlur(0.3f)) ) - ).withDefaultValue(circleBlur(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getCircleBlur()); - assertNotNull(layer.getCircleBlur().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleBlur().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleBlur().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getCircleBlur().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getCircleBlur().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getCircleBlur().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getCircleBlur().getFunction()).getDefaultValue().getValue()); + ); + + // Verify + assertNotNull(layer.getCircleBlur()); + assertNotNull(layer.getCircleBlur().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleBlur().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleBlur().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getCircleBlur().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getCircleBlur().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getCircleBlur().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getCircleBlur().getFunction()).getDefaultValue().getValue()); + } + }); + } @Test @@ -534,34 +649,39 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-blur"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleBlur( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, circleBlur(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(circleBlur(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getCircleBlur()); - assertNotNull(layer.getCircleBlur().getFunction()); - assertEquals(CompositeFunction.class, layer.getCircleBlur().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getCircleBlur().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getCircleBlur().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getCircleBlur().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getCircleBlur().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleBlur( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, circleBlur(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(circleBlur(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getCircleBlur()); + assertNotNull(layer.getCircleBlur().getFunction()); + assertEquals(CompositeFunction.class, layer.getCircleBlur().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getCircleBlur().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getCircleBlur().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getCircleBlur().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getCircleBlur().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -569,12 +689,17 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-opacityTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setCircleOpacityTransition(options); - assertEquals(layer.getCircleOpacityTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setCircleOpacityTransition(options); + assertEquals(layer.getCircleOpacityTransition(), options); + } + }); } @Test @@ -582,11 +707,16 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-opacity"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(circleOpacity(0.3f)); - assertEquals((Float) layer.getCircleOpacity().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(circleOpacity(0.3f)); + assertEquals((Float) layer.getCircleOpacity().getValue(), (Float) 0.3f); + } + }); } @Test @@ -594,26 +724,31 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleOpacity( - zoom( - exponential( - stop(2, circleOpacity(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getCircleOpacity()); - assertNotNull(layer.getCircleOpacity().getFunction()); - assertEquals(CameraFunction.class, layer.getCircleOpacity().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getCircleOpacity().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getCircleOpacity().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getCircleOpacity().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleOpacity( + zoom( + exponential( + stop(2, circleOpacity(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getCircleOpacity()); + assertNotNull(layer.getCircleOpacity().getFunction()); + assertEquals(CameraFunction.class, layer.getCircleOpacity().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getCircleOpacity().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getCircleOpacity().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getCircleOpacity().getFunction().getStops()).size()); + } + }); } @Test @@ -621,19 +756,24 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleOpacity(property("FeaturePropertyA", Stops.identity())) - ); - - // Verify - assertNotNull(layer.getCircleOpacity()); - assertNotNull(layer.getCircleOpacity().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleOpacity().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getCircleOpacity().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleOpacity(property("FeaturePropertyA", Stops.identity())) + ); + + // Verify + assertNotNull(layer.getCircleOpacity()); + assertNotNull(layer.getCircleOpacity().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleOpacity().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getCircleOpacity().getFunction().getStops().getClass()); + } + }); } @Test @@ -641,26 +781,31 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleOpacity( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, circleOpacity(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getCircleOpacity()); - assertNotNull(layer.getCircleOpacity().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleOpacity().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getCircleOpacity().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleOpacity( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, circleOpacity(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getCircleOpacity()); + assertNotNull(layer.getCircleOpacity().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleOpacity().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getCircleOpacity().getFunction().getStops().getClass()); + } + }); } @Test @@ -668,29 +813,35 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleOpacity( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, circleOpacity(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleOpacity( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, circleOpacity(0.3f)) + ) + ).withDefaultValue(circleOpacity(0.3f)) ) - ).withDefaultValue(circleOpacity(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getCircleOpacity()); - assertNotNull(layer.getCircleOpacity().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleOpacity().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getCircleOpacity().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getCircleOpacity().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getCircleOpacity().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getCircleOpacity().getFunction()).getDefaultValue().getValue()); + ); + + // Verify + assertNotNull(layer.getCircleOpacity()); + assertNotNull(layer.getCircleOpacity().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleOpacity().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getCircleOpacity().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getCircleOpacity().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getCircleOpacity().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getCircleOpacity().getFunction()).getDefaultValue().getValue()); + } + }); + } @Test @@ -698,34 +849,39 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleOpacity( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, circleOpacity(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(circleOpacity(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getCircleOpacity()); - assertNotNull(layer.getCircleOpacity().getFunction()); - assertEquals(CompositeFunction.class, layer.getCircleOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getCircleOpacity().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getCircleOpacity().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getCircleOpacity().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getCircleOpacity().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleOpacity( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, circleOpacity(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(circleOpacity(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getCircleOpacity()); + assertNotNull(layer.getCircleOpacity().getFunction()); + assertEquals(CompositeFunction.class, layer.getCircleOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getCircleOpacity().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getCircleOpacity().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getCircleOpacity().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getCircleOpacity().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -733,12 +889,17 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-translateTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setCircleTranslateTransition(options); - assertEquals(layer.getCircleTranslateTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setCircleTranslateTransition(options); + assertEquals(layer.getCircleTranslateTransition(), options); + } + }); } @Test @@ -746,11 +907,16 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-translate"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(circleTranslate(new Float[]{0f,0f})); - assertEquals((Float[]) layer.getCircleTranslate().getValue(), (Float[]) new Float[]{0f,0f}); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(circleTranslate(new Float[] {0f, 0f})); + assertEquals((Float[]) layer.getCircleTranslate().getValue(), (Float[]) new Float[] {0f, 0f}); + } + }); } @Test @@ -758,26 +924,31 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-translate"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleTranslate( - zoom( - exponential( - stop(2, circleTranslate(new Float[]{0f,0f})) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getCircleTranslate()); - assertNotNull(layer.getCircleTranslate().getFunction()); - assertEquals(CameraFunction.class, layer.getCircleTranslate().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getCircleTranslate().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getCircleTranslate().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getCircleTranslate().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleTranslate( + zoom( + exponential( + stop(2, circleTranslate(new Float[] {0f, 0f})) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getCircleTranslate()); + assertNotNull(layer.getCircleTranslate().getFunction()); + assertEquals(CameraFunction.class, layer.getCircleTranslate().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getCircleTranslate().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getCircleTranslate().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getCircleTranslate().getFunction().getStops()).size()); + } + }); } @Test @@ -785,11 +956,16 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-translate-anchor"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(circleTranslateAnchor(CIRCLE_TRANSLATE_ANCHOR_MAP)); - assertEquals((String) layer.getCircleTranslateAnchor().getValue(), (String) CIRCLE_TRANSLATE_ANCHOR_MAP); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(circleTranslateAnchor(CIRCLE_TRANSLATE_ANCHOR_MAP)); + assertEquals((String) layer.getCircleTranslateAnchor().getValue(), (String) CIRCLE_TRANSLATE_ANCHOR_MAP); + } + }); } @Test @@ -797,25 +973,30 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-translate-anchor"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleTranslateAnchor( - zoom( - interval( - stop(2, circleTranslateAnchor(CIRCLE_TRANSLATE_ANCHOR_MAP)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleTranslateAnchor( + zoom( + interval( + stop(2, circleTranslateAnchor(CIRCLE_TRANSLATE_ANCHOR_MAP)) + ) + ) ) - ) - ) - ); - - // Verify - assertNotNull(layer.getCircleTranslateAnchor()); - assertNotNull(layer.getCircleTranslateAnchor().getFunction()); - assertEquals(CameraFunction.class, layer.getCircleTranslateAnchor().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getCircleTranslateAnchor().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getCircleTranslateAnchor().getFunction().getStops()).size()); + ); + + // Verify + assertNotNull(layer.getCircleTranslateAnchor()); + assertNotNull(layer.getCircleTranslateAnchor().getFunction()); + assertEquals(CameraFunction.class, layer.getCircleTranslateAnchor().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getCircleTranslateAnchor().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getCircleTranslateAnchor().getFunction().getStops()).size()); + } + }); } @Test @@ -823,11 +1004,16 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-pitch-scale"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(circlePitchScale(CIRCLE_PITCH_SCALE_MAP)); - assertEquals((String) layer.getCirclePitchScale().getValue(), (String) CIRCLE_PITCH_SCALE_MAP); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(circlePitchScale(CIRCLE_PITCH_SCALE_MAP)); + assertEquals((String) layer.getCirclePitchScale().getValue(), (String) CIRCLE_PITCH_SCALE_MAP); + } + }); } @Test @@ -835,25 +1021,30 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-pitch-scale"); - assertNotNull(layer); - - // Set - layer.setProperties( - circlePitchScale( - zoom( - interval( - stop(2, circlePitchScale(CIRCLE_PITCH_SCALE_MAP)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circlePitchScale( + zoom( + interval( + stop(2, circlePitchScale(CIRCLE_PITCH_SCALE_MAP)) + ) + ) ) - ) - ) - ); - - // Verify - assertNotNull(layer.getCirclePitchScale()); - assertNotNull(layer.getCirclePitchScale().getFunction()); - assertEquals(CameraFunction.class, layer.getCirclePitchScale().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getCirclePitchScale().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getCirclePitchScale().getFunction().getStops()).size()); + ); + + // Verify + assertNotNull(layer.getCirclePitchScale()); + assertNotNull(layer.getCirclePitchScale().getFunction()); + assertEquals(CameraFunction.class, layer.getCirclePitchScale().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getCirclePitchScale().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getCirclePitchScale().getFunction().getStops()).size()); + } + }); } @Test @@ -861,12 +1052,17 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-widthTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setCircleStrokeWidthTransition(options); - assertEquals(layer.getCircleStrokeWidthTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setCircleStrokeWidthTransition(options); + assertEquals(layer.getCircleStrokeWidthTransition(), options); + } + }); } @Test @@ -874,11 +1070,16 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-width"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(circleStrokeWidth(0.3f)); - assertEquals((Float) layer.getCircleStrokeWidth().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(circleStrokeWidth(0.3f)); + assertEquals((Float) layer.getCircleStrokeWidth().getValue(), (Float) 0.3f); + } + }); } @Test @@ -886,26 +1087,31 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleStrokeWidth( - zoom( - exponential( - stop(2, circleStrokeWidth(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getCircleStrokeWidth()); - assertNotNull(layer.getCircleStrokeWidth().getFunction()); - assertEquals(CameraFunction.class, layer.getCircleStrokeWidth().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getCircleStrokeWidth().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getCircleStrokeWidth().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getCircleStrokeWidth().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleStrokeWidth( + zoom( + exponential( + stop(2, circleStrokeWidth(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getCircleStrokeWidth()); + assertNotNull(layer.getCircleStrokeWidth().getFunction()); + assertEquals(CameraFunction.class, layer.getCircleStrokeWidth().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getCircleStrokeWidth().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getCircleStrokeWidth().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getCircleStrokeWidth().getFunction().getStops()).size()); + } + }); } @Test @@ -913,19 +1119,24 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleStrokeWidth(property("FeaturePropertyA", Stops.identity())) - ); - - // Verify - assertNotNull(layer.getCircleStrokeWidth()); - assertNotNull(layer.getCircleStrokeWidth().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleStrokeWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeWidth().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getCircleStrokeWidth().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleStrokeWidth(property("FeaturePropertyA", Stops.identity())) + ); + + // Verify + assertNotNull(layer.getCircleStrokeWidth()); + assertNotNull(layer.getCircleStrokeWidth().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleStrokeWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeWidth().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getCircleStrokeWidth().getFunction().getStops().getClass()); + } + }); } @Test @@ -933,26 +1144,31 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleStrokeWidth( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, circleStrokeWidth(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getCircleStrokeWidth()); - assertNotNull(layer.getCircleStrokeWidth().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleStrokeWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeWidth().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getCircleStrokeWidth().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleStrokeWidth( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, circleStrokeWidth(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getCircleStrokeWidth()); + assertNotNull(layer.getCircleStrokeWidth().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleStrokeWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeWidth().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getCircleStrokeWidth().getFunction().getStops().getClass()); + } + }); } @Test @@ -960,29 +1176,35 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleStrokeWidth( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, circleStrokeWidth(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleStrokeWidth( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, circleStrokeWidth(0.3f)) + ) + ).withDefaultValue(circleStrokeWidth(0.3f)) ) - ).withDefaultValue(circleStrokeWidth(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getCircleStrokeWidth()); - assertNotNull(layer.getCircleStrokeWidth().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleStrokeWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeWidth().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getCircleStrokeWidth().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getCircleStrokeWidth().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getCircleStrokeWidth().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getCircleStrokeWidth().getFunction()).getDefaultValue().getValue()); + ); + + // Verify + assertNotNull(layer.getCircleStrokeWidth()); + assertNotNull(layer.getCircleStrokeWidth().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleStrokeWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeWidth().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getCircleStrokeWidth().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getCircleStrokeWidth().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getCircleStrokeWidth().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getCircleStrokeWidth().getFunction()).getDefaultValue().getValue()); + } + }); + } @Test @@ -990,34 +1212,39 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleStrokeWidth( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, circleStrokeWidth(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(circleStrokeWidth(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getCircleStrokeWidth()); - assertNotNull(layer.getCircleStrokeWidth().getFunction()); - assertEquals(CompositeFunction.class, layer.getCircleStrokeWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getCircleStrokeWidth().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getCircleStrokeWidth().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getCircleStrokeWidth().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getCircleStrokeWidth().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleStrokeWidth( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, circleStrokeWidth(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(circleStrokeWidth(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getCircleStrokeWidth()); + assertNotNull(layer.getCircleStrokeWidth().getFunction()); + assertEquals(CompositeFunction.class, layer.getCircleStrokeWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getCircleStrokeWidth().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getCircleStrokeWidth().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getCircleStrokeWidth().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getCircleStrokeWidth().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -1025,12 +1252,17 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-colorTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setCircleStrokeColorTransition(options); - assertEquals(layer.getCircleStrokeColorTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setCircleStrokeColorTransition(options); + assertEquals(layer.getCircleStrokeColorTransition(), options); + } + }); } @Test @@ -1038,11 +1270,16 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-color"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(circleStrokeColor("rgba(0, 0, 0, 1)")); - assertEquals((String) layer.getCircleStrokeColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(circleStrokeColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getCircleStrokeColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + }); } @Test @@ -1050,26 +1287,31 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleStrokeColor( - zoom( - exponential( - stop(2, circleStrokeColor("rgba(0, 0, 0, 1)")) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getCircleStrokeColor()); - assertNotNull(layer.getCircleStrokeColor().getFunction()); - assertEquals(CameraFunction.class, layer.getCircleStrokeColor().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getCircleStrokeColor().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getCircleStrokeColor().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getCircleStrokeColor().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleStrokeColor( + zoom( + exponential( + stop(2, circleStrokeColor("rgba(0, 0, 0, 1)")) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getCircleStrokeColor()); + assertNotNull(layer.getCircleStrokeColor().getFunction()); + assertEquals(CameraFunction.class, layer.getCircleStrokeColor().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getCircleStrokeColor().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getCircleStrokeColor().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getCircleStrokeColor().getFunction().getStops()).size()); + } + }); } @Test @@ -1077,19 +1319,24 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleStrokeColor(property("FeaturePropertyA", Stops.identity())) - ); - - // Verify - assertNotNull(layer.getCircleStrokeColor()); - assertNotNull(layer.getCircleStrokeColor().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleStrokeColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeColor().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getCircleStrokeColor().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleStrokeColor(property("FeaturePropertyA", Stops.identity())) + ); + + // Verify + assertNotNull(layer.getCircleStrokeColor()); + assertNotNull(layer.getCircleStrokeColor().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleStrokeColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeColor().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getCircleStrokeColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -1097,26 +1344,31 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleStrokeColor( - property( - "FeaturePropertyA", - exponential( - stop(Color.RED, circleStrokeColor(Color.RED)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getCircleStrokeColor()); - assertNotNull(layer.getCircleStrokeColor().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleStrokeColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeColor().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getCircleStrokeColor().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleStrokeColor( + property( + "FeaturePropertyA", + exponential( + stop(Color.RED, circleStrokeColor(Color.RED)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getCircleStrokeColor()); + assertNotNull(layer.getCircleStrokeColor().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleStrokeColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeColor().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getCircleStrokeColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -1124,29 +1376,35 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleStrokeColor( - property( - "FeaturePropertyA", - categorical( - stop("valueA", circleStrokeColor(Color.RED)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleStrokeColor( + property( + "FeaturePropertyA", + categorical( + stop("valueA", circleStrokeColor(Color.RED)) + ) + ).withDefaultValue(circleStrokeColor(Color.GREEN)) ) - ).withDefaultValue(circleStrokeColor(Color.GREEN)) - ) - ); - - // Verify - assertNotNull(layer.getCircleStrokeColor()); - assertNotNull(layer.getCircleStrokeColor().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleStrokeColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeColor().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getCircleStrokeColor().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getCircleStrokeColor().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getCircleStrokeColor().getFunction()).getDefaultValue().getValue()); - assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getCircleStrokeColor().getFunction()).getDefaultValue().getColorInt()); + ); + + // Verify + assertNotNull(layer.getCircleStrokeColor()); + assertNotNull(layer.getCircleStrokeColor().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleStrokeColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeColor().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getCircleStrokeColor().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getCircleStrokeColor().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getCircleStrokeColor().getFunction()).getDefaultValue().getValue()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getCircleStrokeColor().getFunction()).getDefaultValue().getColorInt()); + } + }); + } @Test @@ -1154,11 +1412,16 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-color"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(circleStrokeColor(Color.RED)); - assertEquals(layer.getCircleStrokeColorAsInt(), Color.RED); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(circleStrokeColor(Color.RED)); + assertEquals(layer.getCircleStrokeColorAsInt(), Color.RED); + } + }); } @Test @@ -1166,12 +1429,17 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-opacityTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setCircleStrokeOpacityTransition(options); - assertEquals(layer.getCircleStrokeOpacityTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setCircleStrokeOpacityTransition(options); + assertEquals(layer.getCircleStrokeOpacityTransition(), options); + } + }); } @Test @@ -1179,11 +1447,16 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-opacity"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(circleStrokeOpacity(0.3f)); - assertEquals((Float) layer.getCircleStrokeOpacity().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(circleStrokeOpacity(0.3f)); + assertEquals((Float) layer.getCircleStrokeOpacity().getValue(), (Float) 0.3f); + } + }); } @Test @@ -1191,26 +1464,31 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleStrokeOpacity( - zoom( - exponential( - stop(2, circleStrokeOpacity(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getCircleStrokeOpacity()); - assertNotNull(layer.getCircleStrokeOpacity().getFunction()); - assertEquals(CameraFunction.class, layer.getCircleStrokeOpacity().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getCircleStrokeOpacity().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getCircleStrokeOpacity().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getCircleStrokeOpacity().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleStrokeOpacity( + zoom( + exponential( + stop(2, circleStrokeOpacity(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getCircleStrokeOpacity()); + assertNotNull(layer.getCircleStrokeOpacity().getFunction()); + assertEquals(CameraFunction.class, layer.getCircleStrokeOpacity().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getCircleStrokeOpacity().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getCircleStrokeOpacity().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getCircleStrokeOpacity().getFunction().getStops()).size()); + } + }); } @Test @@ -1218,19 +1496,24 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleStrokeOpacity(property("FeaturePropertyA", Stops.identity())) - ); - - // Verify - assertNotNull(layer.getCircleStrokeOpacity()); - assertNotNull(layer.getCircleStrokeOpacity().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleStrokeOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeOpacity().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getCircleStrokeOpacity().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleStrokeOpacity(property("FeaturePropertyA", Stops.identity())) + ); + + // Verify + assertNotNull(layer.getCircleStrokeOpacity()); + assertNotNull(layer.getCircleStrokeOpacity().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleStrokeOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeOpacity().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getCircleStrokeOpacity().getFunction().getStops().getClass()); + } + }); } @Test @@ -1238,26 +1521,31 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleStrokeOpacity( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, circleStrokeOpacity(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getCircleStrokeOpacity()); - assertNotNull(layer.getCircleStrokeOpacity().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleStrokeOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeOpacity().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getCircleStrokeOpacity().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleStrokeOpacity( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, circleStrokeOpacity(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getCircleStrokeOpacity()); + assertNotNull(layer.getCircleStrokeOpacity().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleStrokeOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeOpacity().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getCircleStrokeOpacity().getFunction().getStops().getClass()); + } + }); } @Test @@ -1265,29 +1553,35 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleStrokeOpacity( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, circleStrokeOpacity(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleStrokeOpacity( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, circleStrokeOpacity(0.3f)) + ) + ).withDefaultValue(circleStrokeOpacity(0.3f)) ) - ).withDefaultValue(circleStrokeOpacity(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getCircleStrokeOpacity()); - assertNotNull(layer.getCircleStrokeOpacity().getFunction()); - assertEquals(SourceFunction.class, layer.getCircleStrokeOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeOpacity().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getCircleStrokeOpacity().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getCircleStrokeOpacity().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getCircleStrokeOpacity().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getCircleStrokeOpacity().getFunction()).getDefaultValue().getValue()); + ); + + // Verify + assertNotNull(layer.getCircleStrokeOpacity()); + assertNotNull(layer.getCircleStrokeOpacity().getFunction()); + assertEquals(SourceFunction.class, layer.getCircleStrokeOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeOpacity().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getCircleStrokeOpacity().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getCircleStrokeOpacity().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getCircleStrokeOpacity().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getCircleStrokeOpacity().getFunction()).getDefaultValue().getValue()); + } + }); + } @Test @@ -1295,34 +1589,39 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-stroke-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - circleStrokeOpacity( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, circleStrokeOpacity(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(circleStrokeOpacity(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getCircleStrokeOpacity()); - assertNotNull(layer.getCircleStrokeOpacity().getFunction()); - assertEquals(CompositeFunction.class, layer.getCircleStrokeOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getCircleStrokeOpacity().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getCircleStrokeOpacity().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getCircleStrokeOpacity().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getCircleStrokeOpacity().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circleStrokeOpacity( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, circleStrokeOpacity(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(circleStrokeOpacity(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getCircleStrokeOpacity()); + assertNotNull(layer.getCircleStrokeOpacity().getFunction()); + assertEquals(CompositeFunction.class, layer.getCircleStrokeOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getCircleStrokeOpacity().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getCircleStrokeOpacity().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getCircleStrokeOpacity().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getCircleStrokeOpacity().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillExtrusionLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillExtrusionLayerTest.java index fec9a6c119..66c6093537 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillExtrusionLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillExtrusionLayerTest.java @@ -3,9 +3,9 @@ package com.mapbox.mapboxsdk.testapp.style; import android.graphics.Color; -import android.support.test.espresso.Espresso; -import android.support.test.rule.ActivityTestRule; +import android.support.test.espresso.UiController; import android.support.test.runner.AndroidJUnit4; + import timber.log.Timber; import com.mapbox.mapboxsdk.maps.MapboxMap; @@ -19,20 +19,16 @@ import com.mapbox.mapboxsdk.style.functions.stops.IntervalStops; import com.mapbox.mapboxsdk.style.functions.stops.Stop; import com.mapbox.mapboxsdk.style.functions.stops.Stops; import com.mapbox.mapboxsdk.style.layers.FillExtrusionLayer; -import com.mapbox.mapboxsdk.testapp.R; -import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; -import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import static com.mapbox.mapboxsdk.style.functions.Function.*; import static com.mapbox.mapboxsdk.style.functions.stops.Stop.stop; import static com.mapbox.mapboxsdk.style.functions.stops.Stops.*; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; import static org.junit.Assert.*; import static com.mapbox.mapboxsdk.style.layers.Property.*; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; @@ -53,15 +49,21 @@ public class FillExtrusionLayerTest extends BaseActivityTest { return EspressoTestActivity.class; } - private void setupLayer(){ - if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { - Timber.i("Adding layer"); - layer = new FillExtrusionLayer("my-layer", "composite"); - layer.setSourceLayer("composite"); - mapboxMap.addLayer(layer); - // Layer reference is now stale, get new reference - layer = mapboxMap.getLayerAs("my-layer"); - } + private void setupLayer() { + Timber.i("Retrieving layer"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Timber.i("Adding layer"); + layer = new FillExtrusionLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + // Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + } + }); } @Test @@ -69,14 +71,19 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("Visibility"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Get initial - assertEquals(layer.getVisibility().getValue(), VISIBLE); + // Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); - // Set - layer.setProperties(visibility(NONE)); - assertEquals(layer.getVisibility().getValue(), NONE); + // Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + }); } @Test @@ -84,15 +91,20 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("SourceLayer"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Get initial - assertEquals(layer.getSourceLayer(), "composite"); + // Get initial + assertEquals(layer.getSourceLayer(), "composite"); - // Set - final String sourceLayer = "test"; - layer.setSourceLayer(sourceLayer); - assertEquals(layer.getSourceLayer(), sourceLayer); + // Set + final String sourceLayer = "test"; + layer.setSourceLayer(sourceLayer); + assertEquals(layer.getSourceLayer(), sourceLayer); + } + }); } @Test @@ -100,12 +112,17 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-opacityTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setFillExtrusionOpacityTransition(options); - assertEquals(layer.getFillExtrusionOpacityTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillExtrusionOpacityTransition(options); + assertEquals(layer.getFillExtrusionOpacityTransition(), options); + } + }); } @Test @@ -113,11 +130,16 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-opacity"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(fillExtrusionOpacity(0.3f)); - assertEquals((Float) layer.getFillExtrusionOpacity().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(fillExtrusionOpacity(0.3f)); + assertEquals((Float) layer.getFillExtrusionOpacity().getValue(), (Float) 0.3f); + } + }); } @Test @@ -125,26 +147,31 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillExtrusionOpacity( - zoom( - exponential( - stop(2, fillExtrusionOpacity(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillExtrusionOpacity( + zoom( + exponential( + stop(2, fillExtrusionOpacity(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getFillExtrusionOpacity()); - assertNotNull(layer.getFillExtrusionOpacity().getFunction()); - assertEquals(CameraFunction.class, layer.getFillExtrusionOpacity().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getFillExtrusionOpacity().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getFillExtrusionOpacity().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getFillExtrusionOpacity().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getFillExtrusionOpacity()); + assertNotNull(layer.getFillExtrusionOpacity().getFunction()); + assertEquals(CameraFunction.class, layer.getFillExtrusionOpacity().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getFillExtrusionOpacity().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getFillExtrusionOpacity().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getFillExtrusionOpacity().getFunction().getStops()).size()); + } + }); } @Test @@ -152,12 +179,17 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-colorTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setFillExtrusionColorTransition(options); - assertEquals(layer.getFillExtrusionColorTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillExtrusionColorTransition(options); + assertEquals(layer.getFillExtrusionColorTransition(), options); + } + }); } @Test @@ -165,11 +197,16 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(fillExtrusionColor("rgba(0, 0, 0, 1)")); - assertEquals((String) layer.getFillExtrusionColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + // Set and Get + layer.setProperties(fillExtrusionColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getFillExtrusionColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + }); } @Test @@ -177,26 +214,31 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillExtrusionColor( - zoom( - exponential( - stop(2, fillExtrusionColor("rgba(0, 0, 0, 1)")) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillExtrusionColor( + zoom( + exponential( + stop(2, fillExtrusionColor("rgba(0, 0, 0, 1)")) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getFillExtrusionColor()); - assertNotNull(layer.getFillExtrusionColor().getFunction()); - assertEquals(CameraFunction.class, layer.getFillExtrusionColor().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getFillExtrusionColor().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getFillExtrusionColor().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getFillExtrusionColor().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getFillExtrusionColor()); + assertNotNull(layer.getFillExtrusionColor().getFunction()); + assertEquals(CameraFunction.class, layer.getFillExtrusionColor().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getFillExtrusionColor().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getFillExtrusionColor().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getFillExtrusionColor().getFunction().getStops()).size()); + } + }); } @Test @@ -204,19 +246,24 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - fillExtrusionColor(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + fillExtrusionColor(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getFillExtrusionColor()); - assertNotNull(layer.getFillExtrusionColor().getFunction()); - assertEquals(SourceFunction.class, layer.getFillExtrusionColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillExtrusionColor().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getFillExtrusionColor().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getFillExtrusionColor()); + assertNotNull(layer.getFillExtrusionColor().getFunction()); + assertEquals(SourceFunction.class, layer.getFillExtrusionColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillExtrusionColor().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getFillExtrusionColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -224,26 +271,31 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillExtrusionColor( - property( - "FeaturePropertyA", - exponential( - stop(Color.RED, fillExtrusionColor(Color.RED)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillExtrusionColor( + property( + "FeaturePropertyA", + exponential( + stop(Color.RED, fillExtrusionColor(Color.RED)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getFillExtrusionColor()); - assertNotNull(layer.getFillExtrusionColor().getFunction()); - assertEquals(SourceFunction.class, layer.getFillExtrusionColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillExtrusionColor().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getFillExtrusionColor().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getFillExtrusionColor()); + assertNotNull(layer.getFillExtrusionColor().getFunction()); + assertEquals(SourceFunction.class, layer.getFillExtrusionColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillExtrusionColor().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getFillExtrusionColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -251,29 +303,35 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillExtrusionColor( - property( - "FeaturePropertyA", - categorical( - stop("valueA", fillExtrusionColor(Color.RED)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillExtrusionColor( + property( + "FeaturePropertyA", + categorical( + stop("valueA", fillExtrusionColor(Color.RED)) + ) + ).withDefaultValue(fillExtrusionColor(Color.GREEN)) ) - ).withDefaultValue(fillExtrusionColor(Color.GREEN)) - ) - ); + ); + + // Verify + assertNotNull(layer.getFillExtrusionColor()); + assertNotNull(layer.getFillExtrusionColor().getFunction()); + assertEquals(SourceFunction.class, layer.getFillExtrusionColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillExtrusionColor().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getFillExtrusionColor().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getFillExtrusionColor().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getFillExtrusionColor().getFunction()).getDefaultValue().getValue()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getFillExtrusionColor().getFunction()).getDefaultValue().getColorInt()); + } + }); - // Verify - assertNotNull(layer.getFillExtrusionColor()); - assertNotNull(layer.getFillExtrusionColor().getFunction()); - assertEquals(SourceFunction.class, layer.getFillExtrusionColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillExtrusionColor().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getFillExtrusionColor().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getFillExtrusionColor().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getFillExtrusionColor().getFunction()).getDefaultValue().getValue()); - assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getFillExtrusionColor().getFunction()).getDefaultValue().getColorInt()); } @Test @@ -281,11 +339,16 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(fillExtrusionColor(Color.RED)); - assertEquals(layer.getFillExtrusionColorAsInt(), Color.RED); + // Set and Get + layer.setProperties(fillExtrusionColor(Color.RED)); + assertEquals(layer.getFillExtrusionColorAsInt(), Color.RED); + } + }); } @Test @@ -293,12 +356,17 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-translateTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setFillExtrusionTranslateTransition(options); - assertEquals(layer.getFillExtrusionTranslateTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillExtrusionTranslateTransition(options); + assertEquals(layer.getFillExtrusionTranslateTransition(), options); + } + }); } @Test @@ -306,11 +374,16 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-translate"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(fillExtrusionTranslate(new Float[]{0f,0f})); - assertEquals((Float[]) layer.getFillExtrusionTranslate().getValue(), (Float[]) new Float[]{0f,0f}); + // Set and Get + layer.setProperties(fillExtrusionTranslate(new Float[] {0f, 0f})); + assertEquals((Float[]) layer.getFillExtrusionTranslate().getValue(), (Float[]) new Float[] {0f, 0f}); + } + }); } @Test @@ -318,26 +391,31 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-translate"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillExtrusionTranslate( - zoom( - exponential( - stop(2, fillExtrusionTranslate(new Float[]{0f,0f})) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillExtrusionTranslate( + zoom( + exponential( + stop(2, fillExtrusionTranslate(new Float[] {0f, 0f})) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getFillExtrusionTranslate()); - assertNotNull(layer.getFillExtrusionTranslate().getFunction()); - assertEquals(CameraFunction.class, layer.getFillExtrusionTranslate().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getFillExtrusionTranslate().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getFillExtrusionTranslate().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getFillExtrusionTranslate().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getFillExtrusionTranslate()); + assertNotNull(layer.getFillExtrusionTranslate().getFunction()); + assertEquals(CameraFunction.class, layer.getFillExtrusionTranslate().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getFillExtrusionTranslate().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getFillExtrusionTranslate().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getFillExtrusionTranslate().getFunction().getStops()).size()); + } + }); } @Test @@ -345,11 +423,16 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-translate-anchor"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(fillExtrusionTranslateAnchor(FILL_EXTRUSION_TRANSLATE_ANCHOR_MAP)); - assertEquals((String) layer.getFillExtrusionTranslateAnchor().getValue(), (String) FILL_EXTRUSION_TRANSLATE_ANCHOR_MAP); + // Set and Get + layer.setProperties(fillExtrusionTranslateAnchor(FILL_EXTRUSION_TRANSLATE_ANCHOR_MAP)); + assertEquals((String) layer.getFillExtrusionTranslateAnchor().getValue(), (String) FILL_EXTRUSION_TRANSLATE_ANCHOR_MAP); + } + }); } @Test @@ -357,25 +440,30 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-translate-anchor"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillExtrusionTranslateAnchor( - zoom( - interval( - stop(2, fillExtrusionTranslateAnchor(FILL_EXTRUSION_TRANSLATE_ANCHOR_MAP)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillExtrusionTranslateAnchor( + zoom( + interval( + stop(2, fillExtrusionTranslateAnchor(FILL_EXTRUSION_TRANSLATE_ANCHOR_MAP)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getFillExtrusionTranslateAnchor()); - assertNotNull(layer.getFillExtrusionTranslateAnchor().getFunction()); - assertEquals(CameraFunction.class, layer.getFillExtrusionTranslateAnchor().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getFillExtrusionTranslateAnchor().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getFillExtrusionTranslateAnchor().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getFillExtrusionTranslateAnchor()); + assertNotNull(layer.getFillExtrusionTranslateAnchor().getFunction()); + assertEquals(CameraFunction.class, layer.getFillExtrusionTranslateAnchor().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getFillExtrusionTranslateAnchor().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getFillExtrusionTranslateAnchor().getFunction().getStops()).size()); + } + }); } @Test @@ -383,12 +471,17 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-patternTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setFillExtrusionPatternTransition(options); - assertEquals(layer.getFillExtrusionPatternTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillExtrusionPatternTransition(options); + assertEquals(layer.getFillExtrusionPatternTransition(), options); + } + }); } @Test @@ -396,11 +489,16 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-pattern"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(fillExtrusionPattern("pedestrian-polygon")); - assertEquals((String) layer.getFillExtrusionPattern().getValue(), (String) "pedestrian-polygon"); + // Set and Get + layer.setProperties(fillExtrusionPattern("pedestrian-polygon")); + assertEquals((String) layer.getFillExtrusionPattern().getValue(), (String) "pedestrian-polygon"); + } + }); } @Test @@ -408,25 +506,30 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-pattern"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillExtrusionPattern( - zoom( - interval( - stop(2, fillExtrusionPattern("pedestrian-polygon")) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillExtrusionPattern( + zoom( + interval( + stop(2, fillExtrusionPattern("pedestrian-polygon")) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getFillExtrusionPattern()); - assertNotNull(layer.getFillExtrusionPattern().getFunction()); - assertEquals(CameraFunction.class, layer.getFillExtrusionPattern().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getFillExtrusionPattern().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getFillExtrusionPattern().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getFillExtrusionPattern()); + assertNotNull(layer.getFillExtrusionPattern().getFunction()); + assertEquals(CameraFunction.class, layer.getFillExtrusionPattern().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getFillExtrusionPattern().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getFillExtrusionPattern().getFunction().getStops()).size()); + } + }); } @Test @@ -434,12 +537,17 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-heightTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setFillExtrusionHeightTransition(options); - assertEquals(layer.getFillExtrusionHeightTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillExtrusionHeightTransition(options); + assertEquals(layer.getFillExtrusionHeightTransition(), options); + } + }); } @Test @@ -447,11 +555,16 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-height"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(fillExtrusionHeight(0.3f)); - assertEquals((Float) layer.getFillExtrusionHeight().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(fillExtrusionHeight(0.3f)); + assertEquals((Float) layer.getFillExtrusionHeight().getValue(), (Float) 0.3f); + } + }); } @Test @@ -459,26 +572,31 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-height"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillExtrusionHeight( - zoom( - exponential( - stop(2, fillExtrusionHeight(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillExtrusionHeight( + zoom( + exponential( + stop(2, fillExtrusionHeight(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getFillExtrusionHeight()); - assertNotNull(layer.getFillExtrusionHeight().getFunction()); - assertEquals(CameraFunction.class, layer.getFillExtrusionHeight().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getFillExtrusionHeight().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getFillExtrusionHeight().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getFillExtrusionHeight().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getFillExtrusionHeight()); + assertNotNull(layer.getFillExtrusionHeight().getFunction()); + assertEquals(CameraFunction.class, layer.getFillExtrusionHeight().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getFillExtrusionHeight().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getFillExtrusionHeight().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getFillExtrusionHeight().getFunction().getStops()).size()); + } + }); } @Test @@ -486,19 +604,24 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-height"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - fillExtrusionHeight(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + fillExtrusionHeight(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getFillExtrusionHeight()); - assertNotNull(layer.getFillExtrusionHeight().getFunction()); - assertEquals(SourceFunction.class, layer.getFillExtrusionHeight().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillExtrusionHeight().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getFillExtrusionHeight().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getFillExtrusionHeight()); + assertNotNull(layer.getFillExtrusionHeight().getFunction()); + assertEquals(SourceFunction.class, layer.getFillExtrusionHeight().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillExtrusionHeight().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getFillExtrusionHeight().getFunction().getStops().getClass()); + } + }); } @Test @@ -506,26 +629,31 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-height"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillExtrusionHeight( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, fillExtrusionHeight(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillExtrusionHeight( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, fillExtrusionHeight(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getFillExtrusionHeight()); - assertNotNull(layer.getFillExtrusionHeight().getFunction()); - assertEquals(SourceFunction.class, layer.getFillExtrusionHeight().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillExtrusionHeight().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getFillExtrusionHeight().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getFillExtrusionHeight()); + assertNotNull(layer.getFillExtrusionHeight().getFunction()); + assertEquals(SourceFunction.class, layer.getFillExtrusionHeight().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillExtrusionHeight().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getFillExtrusionHeight().getFunction().getStops().getClass()); + } + }); } @Test @@ -533,29 +661,35 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-height"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillExtrusionHeight( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, fillExtrusionHeight(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillExtrusionHeight( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, fillExtrusionHeight(0.3f)) + ) + ).withDefaultValue(fillExtrusionHeight(0.3f)) ) - ).withDefaultValue(fillExtrusionHeight(0.3f)) - ) - ); + ); + + // Verify + assertNotNull(layer.getFillExtrusionHeight()); + assertNotNull(layer.getFillExtrusionHeight().getFunction()); + assertEquals(SourceFunction.class, layer.getFillExtrusionHeight().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillExtrusionHeight().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getFillExtrusionHeight().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getFillExtrusionHeight().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getFillExtrusionHeight().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getFillExtrusionHeight().getFunction()).getDefaultValue().getValue()); + } + }); - // Verify - assertNotNull(layer.getFillExtrusionHeight()); - assertNotNull(layer.getFillExtrusionHeight().getFunction()); - assertEquals(SourceFunction.class, layer.getFillExtrusionHeight().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillExtrusionHeight().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getFillExtrusionHeight().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getFillExtrusionHeight().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getFillExtrusionHeight().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getFillExtrusionHeight().getFunction()).getDefaultValue().getValue()); } @Test @@ -563,34 +697,39 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-height"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillExtrusionHeight( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, fillExtrusionHeight(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(fillExtrusionHeight(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getFillExtrusionHeight()); - assertNotNull(layer.getFillExtrusionHeight().getFunction()); - assertEquals(CompositeFunction.class, layer.getFillExtrusionHeight().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getFillExtrusionHeight().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getFillExtrusionHeight().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getFillExtrusionHeight().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getFillExtrusionHeight().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillExtrusionHeight( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, fillExtrusionHeight(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(fillExtrusionHeight(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getFillExtrusionHeight()); + assertNotNull(layer.getFillExtrusionHeight().getFunction()); + assertEquals(CompositeFunction.class, layer.getFillExtrusionHeight().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getFillExtrusionHeight().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getFillExtrusionHeight().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getFillExtrusionHeight().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getFillExtrusionHeight().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -598,12 +737,17 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-baseTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setFillExtrusionBaseTransition(options); - assertEquals(layer.getFillExtrusionBaseTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillExtrusionBaseTransition(options); + assertEquals(layer.getFillExtrusionBaseTransition(), options); + } + }); } @Test @@ -611,11 +755,16 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-base"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(fillExtrusionBase(0.3f)); - assertEquals((Float) layer.getFillExtrusionBase().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(fillExtrusionBase(0.3f)); + assertEquals((Float) layer.getFillExtrusionBase().getValue(), (Float) 0.3f); + } + }); } @Test @@ -623,26 +772,31 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-base"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillExtrusionBase( - zoom( - exponential( - stop(2, fillExtrusionBase(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillExtrusionBase( + zoom( + exponential( + stop(2, fillExtrusionBase(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getFillExtrusionBase()); - assertNotNull(layer.getFillExtrusionBase().getFunction()); - assertEquals(CameraFunction.class, layer.getFillExtrusionBase().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getFillExtrusionBase().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getFillExtrusionBase().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getFillExtrusionBase().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getFillExtrusionBase()); + assertNotNull(layer.getFillExtrusionBase().getFunction()); + assertEquals(CameraFunction.class, layer.getFillExtrusionBase().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getFillExtrusionBase().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getFillExtrusionBase().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getFillExtrusionBase().getFunction().getStops()).size()); + } + }); } @Test @@ -650,19 +804,24 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-base"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - fillExtrusionBase(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + fillExtrusionBase(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getFillExtrusionBase()); - assertNotNull(layer.getFillExtrusionBase().getFunction()); - assertEquals(SourceFunction.class, layer.getFillExtrusionBase().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillExtrusionBase().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getFillExtrusionBase().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getFillExtrusionBase()); + assertNotNull(layer.getFillExtrusionBase().getFunction()); + assertEquals(SourceFunction.class, layer.getFillExtrusionBase().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillExtrusionBase().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getFillExtrusionBase().getFunction().getStops().getClass()); + } + }); } @Test @@ -670,26 +829,31 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-base"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillExtrusionBase( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, fillExtrusionBase(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillExtrusionBase( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, fillExtrusionBase(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getFillExtrusionBase()); - assertNotNull(layer.getFillExtrusionBase().getFunction()); - assertEquals(SourceFunction.class, layer.getFillExtrusionBase().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillExtrusionBase().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getFillExtrusionBase().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getFillExtrusionBase()); + assertNotNull(layer.getFillExtrusionBase().getFunction()); + assertEquals(SourceFunction.class, layer.getFillExtrusionBase().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillExtrusionBase().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getFillExtrusionBase().getFunction().getStops().getClass()); + } + }); } @Test @@ -697,29 +861,35 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-base"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillExtrusionBase( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, fillExtrusionBase(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillExtrusionBase( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, fillExtrusionBase(0.3f)) + ) + ).withDefaultValue(fillExtrusionBase(0.3f)) ) - ).withDefaultValue(fillExtrusionBase(0.3f)) - ) - ); + ); + + // Verify + assertNotNull(layer.getFillExtrusionBase()); + assertNotNull(layer.getFillExtrusionBase().getFunction()); + assertEquals(SourceFunction.class, layer.getFillExtrusionBase().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillExtrusionBase().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getFillExtrusionBase().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getFillExtrusionBase().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getFillExtrusionBase().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getFillExtrusionBase().getFunction()).getDefaultValue().getValue()); + } + }); - // Verify - assertNotNull(layer.getFillExtrusionBase()); - assertNotNull(layer.getFillExtrusionBase().getFunction()); - assertEquals(SourceFunction.class, layer.getFillExtrusionBase().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillExtrusionBase().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getFillExtrusionBase().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getFillExtrusionBase().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getFillExtrusionBase().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getFillExtrusionBase().getFunction()).getDefaultValue().getValue()); } @Test @@ -727,34 +897,39 @@ public class FillExtrusionLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-extrusion-base"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillExtrusionBase( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, fillExtrusionBase(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(fillExtrusionBase(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getFillExtrusionBase()); - assertNotNull(layer.getFillExtrusionBase().getFunction()); - assertEquals(CompositeFunction.class, layer.getFillExtrusionBase().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getFillExtrusionBase().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getFillExtrusionBase().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getFillExtrusionBase().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getFillExtrusionBase().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillExtrusionBase( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, fillExtrusionBase(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(fillExtrusionBase(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getFillExtrusionBase()); + assertNotNull(layer.getFillExtrusionBase().getFunction()); + assertEquals(CompositeFunction.class, layer.getFillExtrusionBase().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getFillExtrusionBase().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getFillExtrusionBase().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getFillExtrusionBase().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getFillExtrusionBase().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java index b6b6578839..939bcb6892 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java @@ -3,9 +3,9 @@ package com.mapbox.mapboxsdk.testapp.style; import android.graphics.Color; -import android.support.test.espresso.Espresso; -import android.support.test.rule.ActivityTestRule; +import android.support.test.espresso.UiController; import android.support.test.runner.AndroidJUnit4; + import timber.log.Timber; import com.mapbox.mapboxsdk.maps.MapboxMap; @@ -19,20 +19,16 @@ import com.mapbox.mapboxsdk.style.functions.stops.IntervalStops; import com.mapbox.mapboxsdk.style.functions.stops.Stop; import com.mapbox.mapboxsdk.style.functions.stops.Stops; import com.mapbox.mapboxsdk.style.layers.FillLayer; -import com.mapbox.mapboxsdk.testapp.R; -import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; -import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import static com.mapbox.mapboxsdk.style.functions.Function.*; import static com.mapbox.mapboxsdk.style.functions.stops.Stop.stop; import static com.mapbox.mapboxsdk.style.functions.stops.Stops.*; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; import static org.junit.Assert.*; import static com.mapbox.mapboxsdk.style.layers.Property.*; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; @@ -53,15 +49,21 @@ public class FillLayerTest extends BaseActivityTest { return EspressoTestActivity.class; } - private void setupLayer(){ - if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { - Timber.i("Adding layer"); - layer = new FillLayer("my-layer", "composite"); - layer.setSourceLayer("composite"); - mapboxMap.addLayer(layer); - // Layer reference is now stale, get new reference - layer = mapboxMap.getLayerAs("my-layer"); - } + private void setupLayer() { + Timber.i("Retrieving layer"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Timber.i("Adding layer"); + layer = new FillLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + // Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + } + }); } @Test @@ -69,14 +71,19 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("Visibility"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Get initial - assertEquals(layer.getVisibility().getValue(), VISIBLE); + // Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); - // Set - layer.setProperties(visibility(NONE)); - assertEquals(layer.getVisibility().getValue(), NONE); + // Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + }); } @Test @@ -84,15 +91,20 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("SourceLayer"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Get initial - assertEquals(layer.getSourceLayer(), "composite"); + // Get initial + assertEquals(layer.getSourceLayer(), "composite"); - // Set - final String sourceLayer = "test"; - layer.setSourceLayer(sourceLayer); - assertEquals(layer.getSourceLayer(), sourceLayer); + // Set + final String sourceLayer = "test"; + layer.setSourceLayer(sourceLayer); + assertEquals(layer.getSourceLayer(), sourceLayer); + } + }); } @Test @@ -100,11 +112,16 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-antialias"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(fillAntialias(true)); - assertEquals((Boolean) layer.getFillAntialias().getValue(), (Boolean) true); + // Set and Get + layer.setProperties(fillAntialias(true)); + assertEquals((Boolean) layer.getFillAntialias().getValue(), (Boolean) true); + } + }); } @Test @@ -112,25 +129,30 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-antialias"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillAntialias( - zoom( - interval( - stop(2, fillAntialias(true)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillAntialias( + zoom( + interval( + stop(2, fillAntialias(true)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getFillAntialias()); - assertNotNull(layer.getFillAntialias().getFunction()); - assertEquals(CameraFunction.class, layer.getFillAntialias().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getFillAntialias().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getFillAntialias().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getFillAntialias()); + assertNotNull(layer.getFillAntialias().getFunction()); + assertEquals(CameraFunction.class, layer.getFillAntialias().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getFillAntialias().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getFillAntialias().getFunction().getStops()).size()); + } + }); } @Test @@ -138,12 +160,17 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-opacityTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setFillOpacityTransition(options); - assertEquals(layer.getFillOpacityTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillOpacityTransition(options); + assertEquals(layer.getFillOpacityTransition(), options); + } + }); } @Test @@ -151,11 +178,16 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-opacity"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(fillOpacity(0.3f)); - assertEquals((Float) layer.getFillOpacity().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(fillOpacity(0.3f)); + assertEquals((Float) layer.getFillOpacity().getValue(), (Float) 0.3f); + } + }); } @Test @@ -163,26 +195,31 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillOpacity( - zoom( - exponential( - stop(2, fillOpacity(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillOpacity( + zoom( + exponential( + stop(2, fillOpacity(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getFillOpacity()); - assertNotNull(layer.getFillOpacity().getFunction()); - assertEquals(CameraFunction.class, layer.getFillOpacity().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getFillOpacity().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getFillOpacity().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getFillOpacity().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getFillOpacity()); + assertNotNull(layer.getFillOpacity().getFunction()); + assertEquals(CameraFunction.class, layer.getFillOpacity().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getFillOpacity().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getFillOpacity().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getFillOpacity().getFunction().getStops()).size()); + } + }); } @Test @@ -190,19 +227,24 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-opacity"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - fillOpacity(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + fillOpacity(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getFillOpacity()); - assertNotNull(layer.getFillOpacity().getFunction()); - assertEquals(SourceFunction.class, layer.getFillOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillOpacity().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getFillOpacity().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getFillOpacity()); + assertNotNull(layer.getFillOpacity().getFunction()); + assertEquals(SourceFunction.class, layer.getFillOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillOpacity().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getFillOpacity().getFunction().getStops().getClass()); + } + }); } @Test @@ -210,26 +252,31 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillOpacity( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, fillOpacity(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillOpacity( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, fillOpacity(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getFillOpacity()); - assertNotNull(layer.getFillOpacity().getFunction()); - assertEquals(SourceFunction.class, layer.getFillOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillOpacity().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getFillOpacity().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getFillOpacity()); + assertNotNull(layer.getFillOpacity().getFunction()); + assertEquals(SourceFunction.class, layer.getFillOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillOpacity().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getFillOpacity().getFunction().getStops().getClass()); + } + }); } @Test @@ -237,29 +284,35 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillOpacity( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, fillOpacity(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillOpacity( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, fillOpacity(0.3f)) + ) + ).withDefaultValue(fillOpacity(0.3f)) ) - ).withDefaultValue(fillOpacity(0.3f)) - ) - ); + ); + + // Verify + assertNotNull(layer.getFillOpacity()); + assertNotNull(layer.getFillOpacity().getFunction()); + assertEquals(SourceFunction.class, layer.getFillOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillOpacity().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getFillOpacity().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getFillOpacity().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getFillOpacity().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getFillOpacity().getFunction()).getDefaultValue().getValue()); + } + }); - // Verify - assertNotNull(layer.getFillOpacity()); - assertNotNull(layer.getFillOpacity().getFunction()); - assertEquals(SourceFunction.class, layer.getFillOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillOpacity().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getFillOpacity().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getFillOpacity().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getFillOpacity().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getFillOpacity().getFunction()).getDefaultValue().getValue()); } @Test @@ -267,34 +320,39 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillOpacity( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, fillOpacity(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(fillOpacity(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getFillOpacity()); - assertNotNull(layer.getFillOpacity().getFunction()); - assertEquals(CompositeFunction.class, layer.getFillOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getFillOpacity().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getFillOpacity().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getFillOpacity().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getFillOpacity().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillOpacity( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, fillOpacity(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(fillOpacity(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getFillOpacity()); + assertNotNull(layer.getFillOpacity().getFunction()); + assertEquals(CompositeFunction.class, layer.getFillOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getFillOpacity().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getFillOpacity().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getFillOpacity().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getFillOpacity().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -302,12 +360,17 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-colorTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setFillColorTransition(options); - assertEquals(layer.getFillColorTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillColorTransition(options); + assertEquals(layer.getFillColorTransition(), options); + } + }); } @Test @@ -315,11 +378,16 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(fillColor("rgba(0, 0, 0, 1)")); - assertEquals((String) layer.getFillColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + // Set and Get + layer.setProperties(fillColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getFillColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + }); } @Test @@ -327,26 +395,31 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillColor( - zoom( - exponential( - stop(2, fillColor("rgba(0, 0, 0, 1)")) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillColor( + zoom( + exponential( + stop(2, fillColor("rgba(0, 0, 0, 1)")) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getFillColor()); - assertNotNull(layer.getFillColor().getFunction()); - assertEquals(CameraFunction.class, layer.getFillColor().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getFillColor().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getFillColor().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getFillColor().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getFillColor()); + assertNotNull(layer.getFillColor().getFunction()); + assertEquals(CameraFunction.class, layer.getFillColor().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getFillColor().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getFillColor().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getFillColor().getFunction().getStops()).size()); + } + }); } @Test @@ -354,19 +427,24 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - fillColor(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + fillColor(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getFillColor()); - assertNotNull(layer.getFillColor().getFunction()); - assertEquals(SourceFunction.class, layer.getFillColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillColor().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getFillColor().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getFillColor()); + assertNotNull(layer.getFillColor().getFunction()); + assertEquals(SourceFunction.class, layer.getFillColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillColor().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getFillColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -374,26 +452,31 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillColor( - property( - "FeaturePropertyA", - exponential( - stop(Color.RED, fillColor(Color.RED)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillColor( + property( + "FeaturePropertyA", + exponential( + stop(Color.RED, fillColor(Color.RED)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getFillColor()); - assertNotNull(layer.getFillColor().getFunction()); - assertEquals(SourceFunction.class, layer.getFillColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillColor().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getFillColor().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getFillColor()); + assertNotNull(layer.getFillColor().getFunction()); + assertEquals(SourceFunction.class, layer.getFillColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillColor().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getFillColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -401,29 +484,35 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillColor( - property( - "FeaturePropertyA", - categorical( - stop("valueA", fillColor(Color.RED)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillColor( + property( + "FeaturePropertyA", + categorical( + stop("valueA", fillColor(Color.RED)) + ) + ).withDefaultValue(fillColor(Color.GREEN)) ) - ).withDefaultValue(fillColor(Color.GREEN)) - ) - ); + ); + + // Verify + assertNotNull(layer.getFillColor()); + assertNotNull(layer.getFillColor().getFunction()); + assertEquals(SourceFunction.class, layer.getFillColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillColor().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getFillColor().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getFillColor().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getFillColor().getFunction()).getDefaultValue().getValue()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getFillColor().getFunction()).getDefaultValue().getColorInt()); + } + }); - // Verify - assertNotNull(layer.getFillColor()); - assertNotNull(layer.getFillColor().getFunction()); - assertEquals(SourceFunction.class, layer.getFillColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillColor().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getFillColor().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getFillColor().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getFillColor().getFunction()).getDefaultValue().getValue()); - assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getFillColor().getFunction()).getDefaultValue().getColorInt()); } @Test @@ -431,11 +520,16 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(fillColor(Color.RED)); - assertEquals(layer.getFillColorAsInt(), Color.RED); + // Set and Get + layer.setProperties(fillColor(Color.RED)); + assertEquals(layer.getFillColorAsInt(), Color.RED); + } + }); } @Test @@ -443,12 +537,17 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-outline-colorTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setFillOutlineColorTransition(options); - assertEquals(layer.getFillOutlineColorTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillOutlineColorTransition(options); + assertEquals(layer.getFillOutlineColorTransition(), options); + } + }); } @Test @@ -456,11 +555,16 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-outline-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(fillOutlineColor("rgba(0, 0, 0, 1)")); - assertEquals((String) layer.getFillOutlineColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + // Set and Get + layer.setProperties(fillOutlineColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getFillOutlineColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + }); } @Test @@ -468,26 +572,31 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-outline-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillOutlineColor( - zoom( - exponential( - stop(2, fillOutlineColor("rgba(0, 0, 0, 1)")) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillOutlineColor( + zoom( + exponential( + stop(2, fillOutlineColor("rgba(0, 0, 0, 1)")) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getFillOutlineColor()); - assertNotNull(layer.getFillOutlineColor().getFunction()); - assertEquals(CameraFunction.class, layer.getFillOutlineColor().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getFillOutlineColor().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getFillOutlineColor().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getFillOutlineColor().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getFillOutlineColor()); + assertNotNull(layer.getFillOutlineColor().getFunction()); + assertEquals(CameraFunction.class, layer.getFillOutlineColor().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getFillOutlineColor().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getFillOutlineColor().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getFillOutlineColor().getFunction().getStops()).size()); + } + }); } @Test @@ -495,19 +604,24 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-outline-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - fillOutlineColor(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + fillOutlineColor(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getFillOutlineColor()); - assertNotNull(layer.getFillOutlineColor().getFunction()); - assertEquals(SourceFunction.class, layer.getFillOutlineColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillOutlineColor().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getFillOutlineColor().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getFillOutlineColor()); + assertNotNull(layer.getFillOutlineColor().getFunction()); + assertEquals(SourceFunction.class, layer.getFillOutlineColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillOutlineColor().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getFillOutlineColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -515,26 +629,31 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-outline-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillOutlineColor( - property( - "FeaturePropertyA", - exponential( - stop(Color.RED, fillOutlineColor(Color.RED)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillOutlineColor( + property( + "FeaturePropertyA", + exponential( + stop(Color.RED, fillOutlineColor(Color.RED)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getFillOutlineColor()); - assertNotNull(layer.getFillOutlineColor().getFunction()); - assertEquals(SourceFunction.class, layer.getFillOutlineColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillOutlineColor().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getFillOutlineColor().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getFillOutlineColor()); + assertNotNull(layer.getFillOutlineColor().getFunction()); + assertEquals(SourceFunction.class, layer.getFillOutlineColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillOutlineColor().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getFillOutlineColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -542,29 +661,35 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-outline-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillOutlineColor( - property( - "FeaturePropertyA", - categorical( - stop("valueA", fillOutlineColor(Color.RED)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillOutlineColor( + property( + "FeaturePropertyA", + categorical( + stop("valueA", fillOutlineColor(Color.RED)) + ) + ).withDefaultValue(fillOutlineColor(Color.GREEN)) ) - ).withDefaultValue(fillOutlineColor(Color.GREEN)) - ) - ); + ); + + // Verify + assertNotNull(layer.getFillOutlineColor()); + assertNotNull(layer.getFillOutlineColor().getFunction()); + assertEquals(SourceFunction.class, layer.getFillOutlineColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillOutlineColor().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getFillOutlineColor().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getFillOutlineColor().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getFillOutlineColor().getFunction()).getDefaultValue().getValue()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getFillOutlineColor().getFunction()).getDefaultValue().getColorInt()); + } + }); - // Verify - assertNotNull(layer.getFillOutlineColor()); - assertNotNull(layer.getFillOutlineColor().getFunction()); - assertEquals(SourceFunction.class, layer.getFillOutlineColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillOutlineColor().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getFillOutlineColor().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getFillOutlineColor().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getFillOutlineColor().getFunction()).getDefaultValue().getValue()); - assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getFillOutlineColor().getFunction()).getDefaultValue().getColorInt()); } @Test @@ -572,11 +697,16 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-outline-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(fillOutlineColor(Color.RED)); - assertEquals(layer.getFillOutlineColorAsInt(), Color.RED); + // Set and Get + layer.setProperties(fillOutlineColor(Color.RED)); + assertEquals(layer.getFillOutlineColorAsInt(), Color.RED); + } + }); } @Test @@ -584,12 +714,17 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-translateTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setFillTranslateTransition(options); - assertEquals(layer.getFillTranslateTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillTranslateTransition(options); + assertEquals(layer.getFillTranslateTransition(), options); + } + }); } @Test @@ -597,11 +732,16 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-translate"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(fillTranslate(new Float[]{0f,0f})); - assertEquals((Float[]) layer.getFillTranslate().getValue(), (Float[]) new Float[]{0f,0f}); + // Set and Get + layer.setProperties(fillTranslate(new Float[] {0f, 0f})); + assertEquals((Float[]) layer.getFillTranslate().getValue(), (Float[]) new Float[] {0f, 0f}); + } + }); } @Test @@ -609,26 +749,31 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-translate"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillTranslate( - zoom( - exponential( - stop(2, fillTranslate(new Float[]{0f,0f})) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillTranslate( + zoom( + exponential( + stop(2, fillTranslate(new Float[] {0f, 0f})) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getFillTranslate()); - assertNotNull(layer.getFillTranslate().getFunction()); - assertEquals(CameraFunction.class, layer.getFillTranslate().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getFillTranslate().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getFillTranslate().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getFillTranslate().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getFillTranslate()); + assertNotNull(layer.getFillTranslate().getFunction()); + assertEquals(CameraFunction.class, layer.getFillTranslate().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getFillTranslate().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getFillTranslate().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getFillTranslate().getFunction().getStops()).size()); + } + }); } @Test @@ -636,11 +781,16 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-translate-anchor"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(fillTranslateAnchor(FILL_TRANSLATE_ANCHOR_MAP)); - assertEquals((String) layer.getFillTranslateAnchor().getValue(), (String) FILL_TRANSLATE_ANCHOR_MAP); + // Set and Get + layer.setProperties(fillTranslateAnchor(FILL_TRANSLATE_ANCHOR_MAP)); + assertEquals((String) layer.getFillTranslateAnchor().getValue(), (String) FILL_TRANSLATE_ANCHOR_MAP); + } + }); } @Test @@ -648,25 +798,30 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-translate-anchor"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillTranslateAnchor( - zoom( - interval( - stop(2, fillTranslateAnchor(FILL_TRANSLATE_ANCHOR_MAP)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillTranslateAnchor( + zoom( + interval( + stop(2, fillTranslateAnchor(FILL_TRANSLATE_ANCHOR_MAP)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getFillTranslateAnchor()); - assertNotNull(layer.getFillTranslateAnchor().getFunction()); - assertEquals(CameraFunction.class, layer.getFillTranslateAnchor().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getFillTranslateAnchor().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getFillTranslateAnchor().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getFillTranslateAnchor()); + assertNotNull(layer.getFillTranslateAnchor().getFunction()); + assertEquals(CameraFunction.class, layer.getFillTranslateAnchor().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getFillTranslateAnchor().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getFillTranslateAnchor().getFunction().getStops()).size()); + } + }); } @Test @@ -674,12 +829,17 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-patternTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setFillPatternTransition(options); - assertEquals(layer.getFillPatternTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setFillPatternTransition(options); + assertEquals(layer.getFillPatternTransition(), options); + } + }); } @Test @@ -687,11 +847,16 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-pattern"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(fillPattern("pedestrian-polygon")); - assertEquals((String) layer.getFillPattern().getValue(), (String) "pedestrian-polygon"); + // Set and Get + layer.setProperties(fillPattern("pedestrian-polygon")); + assertEquals((String) layer.getFillPattern().getValue(), (String) "pedestrian-polygon"); + } + }); } @Test @@ -699,25 +864,30 @@ public class FillLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("fill-pattern"); - assertNotNull(layer); - - // Set - layer.setProperties( - fillPattern( - zoom( - interval( - stop(2, fillPattern("pedestrian-polygon")) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + fillPattern( + zoom( + interval( + stop(2, fillPattern("pedestrian-polygon")) + ) + ) ) - ) - ) - ); - - // Verify - assertNotNull(layer.getFillPattern()); - assertNotNull(layer.getFillPattern().getFunction()); - assertEquals(CameraFunction.class, layer.getFillPattern().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getFillPattern().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getFillPattern().getFunction().getStops()).size()); + ); + + // Verify + assertNotNull(layer.getFillPattern()); + assertNotNull(layer.getFillPattern().getFunction()); + assertEquals(CameraFunction.class, layer.getFillPattern().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getFillPattern().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getFillPattern().getFunction().getStops()).size()); + } + }); } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LightTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LightTest.java index 36833fb4ee..88da6e45be 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LightTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LightTest.java @@ -6,6 +6,7 @@ import android.support.test.espresso.ViewAction; import android.support.test.runner.AndroidJUnit4; import android.view.View; +import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.style.light.Light; import com.mapbox.mapboxsdk.style.functions.Function; import com.mapbox.mapboxsdk.style.functions.stops.IdentityStops; @@ -13,6 +14,7 @@ import com.mapbox.mapboxsdk.style.layers.FillExtrusionLayer; import com.mapbox.mapboxsdk.style.layers.TransitionOptions; import com.mapbox.mapboxsdk.style.light.Position; import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; import com.mapbox.mapboxsdk.testapp.activity.style.FillExtrusionStyleTestActivity; @@ -32,6 +34,7 @@ import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionCol import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionHeight; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionOpacity; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; @@ -43,89 +46,120 @@ public class LightTest extends BaseActivityTest { @Test public void testAnchor() { validateTestSetup(); - setupLayer(); + setupLight(); Timber.i("anchor"); - assertNotNull(light); - // Set and Get - light.setAnchor(ANCHOR_MAP); - assertEquals("Anchor should match", ANCHOR_MAP, light.getAnchor()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(light); + // Set and Get + light.setAnchor(ANCHOR_MAP); + assertEquals("Anchor should match", ANCHOR_MAP, light.getAnchor()); + } + }); } @Test public void testPositionTransition() { validateTestSetup(); - setupLayer(); + setupLight(); Timber.i("positionTransitionOptions"); - assertNotNull(light); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - light.setPositionTransition(options); - assertEquals("Transition options should match", options, light.getPositionTransition()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(light); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + light.setPositionTransition(options); + assertEquals("Transition options should match", options, light.getPositionTransition()); + } + }); } @Test public void testPosition() { validateTestSetup(); - setupLayer(); + setupLight(); Timber.i("position"); - assertNotNull(light); - - // Set and Get - Position position = new Position(1,2,3); - light.setPosition(position); - assertEquals("Position should match", position, light.getPosition()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(light); + // Set and Get + Position position = new Position(1, 2, 3); + light.setPosition(position); + assertEquals("Position should match", position, light.getPosition()); + } + }); } @Test public void testColorTransition() { validateTestSetup(); - setupLayer(); + setupLight(); Timber.i("colorTransitionOptions"); - assertNotNull(light); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - light.setColorTransition(options); - assertEquals("Transition options should match", options, light.getColorTransition()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(light); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + light.setColorTransition(options); + assertEquals("Transition options should match", options, light.getColorTransition()); + } + }); } @Test public void testColor() { validateTestSetup(); - setupLayer(); + setupLight(); Timber.i("color"); - assertNotNull(light); - // Set and Get - light.setColor("rgba(0, 0, 0, 1)"); - assertEquals("Color should match", "rgba(0, 0, 0, 1)".replaceAll("\\s+",""), light.getColor()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(light); + // Set and Get + light.setColor("rgba(0, 0, 0, 1)"); + assertEquals("Color should match", "rgba(0, 0, 0, 1)".replaceAll("\\s+", ""), light.getColor()); + } + }); } @Test public void testIntensityTransition() { validateTestSetup(); - setupLayer(); + setupLight(); Timber.i("intensityTransitionOptions"); - assertNotNull(light); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - light.setIntensityTransition(options); - assertEquals("Transition options should match", options, light.getIntensityTransition()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(light); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + light.setIntensityTransition(options); + assertEquals("Transition options should match", options, light.getIntensityTransition()); + } + }); } @Test public void testIntensity() { validateTestSetup(); - setupLayer(); + setupLight(); Timber.i("intensity"); - assertNotNull(light); - // Set and Get - light.setIntensity(0.3f); - assertEquals("Intensity should match", 0.3f, light.getIntensity()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(light); + // Set and Get + light.setIntensity(0.3f); + assertEquals("Intensity should match", 0.3f, light.getIntensity()); + } + }); } - private void setupLayer() { + private void setupLight() { onView(withId(R.id.mapView)).perform(new ViewAction() { @Override public Matcher getConstraints() { diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java index 1c23dd366b..595a2e43dc 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java @@ -3,9 +3,9 @@ package com.mapbox.mapboxsdk.testapp.style; import android.graphics.Color; -import android.support.test.espresso.Espresso; -import android.support.test.rule.ActivityTestRule; +import android.support.test.espresso.UiController; import android.support.test.runner.AndroidJUnit4; + import timber.log.Timber; import com.mapbox.mapboxsdk.maps.MapboxMap; @@ -19,20 +19,16 @@ import com.mapbox.mapboxsdk.style.functions.stops.IntervalStops; import com.mapbox.mapboxsdk.style.functions.stops.Stop; import com.mapbox.mapboxsdk.style.functions.stops.Stops; import com.mapbox.mapboxsdk.style.layers.LineLayer; -import com.mapbox.mapboxsdk.testapp.R; -import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; -import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import static com.mapbox.mapboxsdk.style.functions.Function.*; import static com.mapbox.mapboxsdk.style.functions.stops.Stop.stop; import static com.mapbox.mapboxsdk.style.functions.stops.Stops.*; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; import static org.junit.Assert.*; import static com.mapbox.mapboxsdk.style.layers.Property.*; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; @@ -53,15 +49,21 @@ public class LineLayerTest extends BaseActivityTest { return EspressoTestActivity.class; } - private void setupLayer(){ - if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { - Timber.i("Adding layer"); - layer = new LineLayer("my-layer", "composite"); - layer.setSourceLayer("composite"); - mapboxMap.addLayer(layer); - // Layer reference is now stale, get new reference - layer = mapboxMap.getLayerAs("my-layer"); - } + private void setupLayer() { + Timber.i("Retrieving layer"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Timber.i("Adding layer"); + layer = new LineLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + // Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + } + }); } @Test @@ -69,14 +71,19 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("Visibility"); - assertNotNull(layer); - - // Get initial - assertEquals(layer.getVisibility().getValue(), VISIBLE); - - // Set - layer.setProperties(visibility(NONE)); - assertEquals(layer.getVisibility().getValue(), NONE); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + // Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + }); } @Test @@ -84,15 +91,20 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("SourceLayer"); - assertNotNull(layer); - - // Get initial - assertEquals(layer.getSourceLayer(), "composite"); - - // Set - final String sourceLayer = "test"; - layer.setSourceLayer(sourceLayer); - assertEquals(layer.getSourceLayer(), sourceLayer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Get initial + assertEquals(layer.getSourceLayer(), "composite"); + + // Set + final String sourceLayer = "test"; + layer.setSourceLayer(sourceLayer); + assertEquals(layer.getSourceLayer(), sourceLayer); + } + }); } @Test @@ -100,11 +112,16 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-cap"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(lineCap(LINE_CAP_BUTT)); - assertEquals((String) layer.getLineCap().getValue(), (String) LINE_CAP_BUTT); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(lineCap(LINE_CAP_BUTT)); + assertEquals((String) layer.getLineCap().getValue(), (String) LINE_CAP_BUTT); + } + }); } @Test @@ -112,25 +129,30 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-cap"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineCap( - zoom( - interval( - stop(2, lineCap(LINE_CAP_BUTT)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineCap( + zoom( + interval( + stop(2, lineCap(LINE_CAP_BUTT)) + ) + ) ) - ) - ) - ); - - // Verify - assertNotNull(layer.getLineCap()); - assertNotNull(layer.getLineCap().getFunction()); - assertEquals(CameraFunction.class, layer.getLineCap().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getLineCap().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getLineCap().getFunction().getStops()).size()); + ); + + // Verify + assertNotNull(layer.getLineCap()); + assertNotNull(layer.getLineCap().getFunction()); + assertEquals(CameraFunction.class, layer.getLineCap().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getLineCap().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getLineCap().getFunction().getStops()).size()); + } + }); } @Test @@ -138,11 +160,16 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-join"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(lineJoin(LINE_JOIN_BEVEL)); - assertEquals((String) layer.getLineJoin().getValue(), (String) LINE_JOIN_BEVEL); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(lineJoin(LINE_JOIN_BEVEL)); + assertEquals((String) layer.getLineJoin().getValue(), (String) LINE_JOIN_BEVEL); + } + }); } @Test @@ -150,25 +177,30 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-join"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineJoin( - zoom( - interval( - stop(2, lineJoin(LINE_JOIN_BEVEL)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineJoin( + zoom( + interval( + stop(2, lineJoin(LINE_JOIN_BEVEL)) + ) + ) ) - ) - ) - ); - - // Verify - assertNotNull(layer.getLineJoin()); - assertNotNull(layer.getLineJoin().getFunction()); - assertEquals(CameraFunction.class, layer.getLineJoin().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getLineJoin().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getLineJoin().getFunction().getStops()).size()); + ); + + // Verify + assertNotNull(layer.getLineJoin()); + assertNotNull(layer.getLineJoin().getFunction()); + assertEquals(CameraFunction.class, layer.getLineJoin().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getLineJoin().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getLineJoin().getFunction().getStops()).size()); + } + }); } @Test @@ -176,11 +208,16 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-miter-limit"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(lineMiterLimit(0.3f)); - assertEquals((Float) layer.getLineMiterLimit().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(lineMiterLimit(0.3f)); + assertEquals((Float) layer.getLineMiterLimit().getValue(), (Float) 0.3f); + } + }); } @Test @@ -188,26 +225,31 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-miter-limit"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineMiterLimit( - zoom( - exponential( - stop(2, lineMiterLimit(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getLineMiterLimit()); - assertNotNull(layer.getLineMiterLimit().getFunction()); - assertEquals(CameraFunction.class, layer.getLineMiterLimit().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineMiterLimit().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getLineMiterLimit().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getLineMiterLimit().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineMiterLimit( + zoom( + exponential( + stop(2, lineMiterLimit(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getLineMiterLimit()); + assertNotNull(layer.getLineMiterLimit().getFunction()); + assertEquals(CameraFunction.class, layer.getLineMiterLimit().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getLineMiterLimit().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getLineMiterLimit().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getLineMiterLimit().getFunction().getStops()).size()); + } + }); } @Test @@ -215,11 +257,16 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-round-limit"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(lineRoundLimit(0.3f)); - assertEquals((Float) layer.getLineRoundLimit().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(lineRoundLimit(0.3f)); + assertEquals((Float) layer.getLineRoundLimit().getValue(), (Float) 0.3f); + } + }); } @Test @@ -227,26 +274,31 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-round-limit"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineRoundLimit( - zoom( - exponential( - stop(2, lineRoundLimit(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getLineRoundLimit()); - assertNotNull(layer.getLineRoundLimit().getFunction()); - assertEquals(CameraFunction.class, layer.getLineRoundLimit().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineRoundLimit().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getLineRoundLimit().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getLineRoundLimit().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineRoundLimit( + zoom( + exponential( + stop(2, lineRoundLimit(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getLineRoundLimit()); + assertNotNull(layer.getLineRoundLimit().getFunction()); + assertEquals(CameraFunction.class, layer.getLineRoundLimit().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getLineRoundLimit().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getLineRoundLimit().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getLineRoundLimit().getFunction().getStops()).size()); + } + }); } @Test @@ -254,12 +306,17 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-opacityTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setLineOpacityTransition(options); - assertEquals(layer.getLineOpacityTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setLineOpacityTransition(options); + assertEquals(layer.getLineOpacityTransition(), options); + } + }); } @Test @@ -267,11 +324,16 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-opacity"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(lineOpacity(0.3f)); - assertEquals((Float) layer.getLineOpacity().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(lineOpacity(0.3f)); + assertEquals((Float) layer.getLineOpacity().getValue(), (Float) 0.3f); + } + }); } @Test @@ -279,26 +341,31 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineOpacity( - zoom( - exponential( - stop(2, lineOpacity(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getLineOpacity()); - assertNotNull(layer.getLineOpacity().getFunction()); - assertEquals(CameraFunction.class, layer.getLineOpacity().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineOpacity().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getLineOpacity().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getLineOpacity().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineOpacity( + zoom( + exponential( + stop(2, lineOpacity(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getLineOpacity()); + assertNotNull(layer.getLineOpacity().getFunction()); + assertEquals(CameraFunction.class, layer.getLineOpacity().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getLineOpacity().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getLineOpacity().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getLineOpacity().getFunction().getStops()).size()); + } + }); } @Test @@ -306,19 +373,24 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineOpacity(property("FeaturePropertyA", Stops.identity())) - ); - - // Verify - assertNotNull(layer.getLineOpacity()); - assertNotNull(layer.getLineOpacity().getFunction()); - assertEquals(SourceFunction.class, layer.getLineOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineOpacity().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getLineOpacity().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineOpacity(property("FeaturePropertyA", Stops.identity())) + ); + + // Verify + assertNotNull(layer.getLineOpacity()); + assertNotNull(layer.getLineOpacity().getFunction()); + assertEquals(SourceFunction.class, layer.getLineOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineOpacity().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getLineOpacity().getFunction().getStops().getClass()); + } + }); } @Test @@ -326,26 +398,31 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineOpacity( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, lineOpacity(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getLineOpacity()); - assertNotNull(layer.getLineOpacity().getFunction()); - assertEquals(SourceFunction.class, layer.getLineOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineOpacity().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getLineOpacity().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineOpacity( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, lineOpacity(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getLineOpacity()); + assertNotNull(layer.getLineOpacity().getFunction()); + assertEquals(SourceFunction.class, layer.getLineOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineOpacity().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getLineOpacity().getFunction().getStops().getClass()); + } + }); } @Test @@ -353,29 +430,35 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineOpacity( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, lineOpacity(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineOpacity( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, lineOpacity(0.3f)) + ) + ).withDefaultValue(lineOpacity(0.3f)) ) - ).withDefaultValue(lineOpacity(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getLineOpacity()); - assertNotNull(layer.getLineOpacity().getFunction()); - assertEquals(SourceFunction.class, layer.getLineOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineOpacity().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getLineOpacity().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getLineOpacity().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getLineOpacity().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getLineOpacity().getFunction()).getDefaultValue().getValue()); + ); + + // Verify + assertNotNull(layer.getLineOpacity()); + assertNotNull(layer.getLineOpacity().getFunction()); + assertEquals(SourceFunction.class, layer.getLineOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineOpacity().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getLineOpacity().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getLineOpacity().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getLineOpacity().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getLineOpacity().getFunction()).getDefaultValue().getValue()); + } + }); + } @Test @@ -383,34 +466,39 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineOpacity( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, lineOpacity(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(lineOpacity(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getLineOpacity()); - assertNotNull(layer.getLineOpacity().getFunction()); - assertEquals(CompositeFunction.class, layer.getLineOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getLineOpacity().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getLineOpacity().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getLineOpacity().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getLineOpacity().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineOpacity( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, lineOpacity(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(lineOpacity(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getLineOpacity()); + assertNotNull(layer.getLineOpacity().getFunction()); + assertEquals(CompositeFunction.class, layer.getLineOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getLineOpacity().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getLineOpacity().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getLineOpacity().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getLineOpacity().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -418,12 +506,17 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-colorTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setLineColorTransition(options); - assertEquals(layer.getLineColorTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setLineColorTransition(options); + assertEquals(layer.getLineColorTransition(), options); + } + }); } @Test @@ -431,11 +524,16 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-color"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(lineColor("rgba(0, 0, 0, 1)")); - assertEquals((String) layer.getLineColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(lineColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getLineColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + }); } @Test @@ -443,26 +541,31 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineColor( - zoom( - exponential( - stop(2, lineColor("rgba(0, 0, 0, 1)")) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getLineColor()); - assertNotNull(layer.getLineColor().getFunction()); - assertEquals(CameraFunction.class, layer.getLineColor().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineColor().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getLineColor().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getLineColor().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineColor( + zoom( + exponential( + stop(2, lineColor("rgba(0, 0, 0, 1)")) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getLineColor()); + assertNotNull(layer.getLineColor().getFunction()); + assertEquals(CameraFunction.class, layer.getLineColor().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getLineColor().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getLineColor().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getLineColor().getFunction().getStops()).size()); + } + }); } @Test @@ -470,19 +573,24 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineColor(property("FeaturePropertyA", Stops.identity())) - ); - - // Verify - assertNotNull(layer.getLineColor()); - assertNotNull(layer.getLineColor().getFunction()); - assertEquals(SourceFunction.class, layer.getLineColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineColor().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getLineColor().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineColor(property("FeaturePropertyA", Stops.identity())) + ); + + // Verify + assertNotNull(layer.getLineColor()); + assertNotNull(layer.getLineColor().getFunction()); + assertEquals(SourceFunction.class, layer.getLineColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineColor().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getLineColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -490,26 +598,31 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineColor( - property( - "FeaturePropertyA", - exponential( - stop(Color.RED, lineColor(Color.RED)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getLineColor()); - assertNotNull(layer.getLineColor().getFunction()); - assertEquals(SourceFunction.class, layer.getLineColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineColor().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getLineColor().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineColor( + property( + "FeaturePropertyA", + exponential( + stop(Color.RED, lineColor(Color.RED)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getLineColor()); + assertNotNull(layer.getLineColor().getFunction()); + assertEquals(SourceFunction.class, layer.getLineColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineColor().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getLineColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -517,29 +630,35 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineColor( - property( - "FeaturePropertyA", - categorical( - stop("valueA", lineColor(Color.RED)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineColor( + property( + "FeaturePropertyA", + categorical( + stop("valueA", lineColor(Color.RED)) + ) + ).withDefaultValue(lineColor(Color.GREEN)) ) - ).withDefaultValue(lineColor(Color.GREEN)) - ) - ); - - // Verify - assertNotNull(layer.getLineColor()); - assertNotNull(layer.getLineColor().getFunction()); - assertEquals(SourceFunction.class, layer.getLineColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineColor().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getLineColor().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getLineColor().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getLineColor().getFunction()).getDefaultValue().getValue()); - assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getLineColor().getFunction()).getDefaultValue().getColorInt()); + ); + + // Verify + assertNotNull(layer.getLineColor()); + assertNotNull(layer.getLineColor().getFunction()); + assertEquals(SourceFunction.class, layer.getLineColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineColor().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getLineColor().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getLineColor().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getLineColor().getFunction()).getDefaultValue().getValue()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getLineColor().getFunction()).getDefaultValue().getColorInt()); + } + }); + } @Test @@ -547,11 +666,16 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-color"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(lineColor(Color.RED)); - assertEquals(layer.getLineColorAsInt(), Color.RED); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(lineColor(Color.RED)); + assertEquals(layer.getLineColorAsInt(), Color.RED); + } + }); } @Test @@ -559,12 +683,17 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-translateTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setLineTranslateTransition(options); - assertEquals(layer.getLineTranslateTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setLineTranslateTransition(options); + assertEquals(layer.getLineTranslateTransition(), options); + } + }); } @Test @@ -572,11 +701,16 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-translate"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(lineTranslate(new Float[]{0f,0f})); - assertEquals((Float[]) layer.getLineTranslate().getValue(), (Float[]) new Float[]{0f,0f}); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(lineTranslate(new Float[] {0f, 0f})); + assertEquals((Float[]) layer.getLineTranslate().getValue(), (Float[]) new Float[] {0f, 0f}); + } + }); } @Test @@ -584,26 +718,31 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-translate"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineTranslate( - zoom( - exponential( - stop(2, lineTranslate(new Float[]{0f,0f})) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getLineTranslate()); - assertNotNull(layer.getLineTranslate().getFunction()); - assertEquals(CameraFunction.class, layer.getLineTranslate().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineTranslate().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getLineTranslate().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getLineTranslate().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineTranslate( + zoom( + exponential( + stop(2, lineTranslate(new Float[] {0f, 0f})) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getLineTranslate()); + assertNotNull(layer.getLineTranslate().getFunction()); + assertEquals(CameraFunction.class, layer.getLineTranslate().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getLineTranslate().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getLineTranslate().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getLineTranslate().getFunction().getStops()).size()); + } + }); } @Test @@ -611,11 +750,16 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-translate-anchor"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(lineTranslateAnchor(LINE_TRANSLATE_ANCHOR_MAP)); - assertEquals((String) layer.getLineTranslateAnchor().getValue(), (String) LINE_TRANSLATE_ANCHOR_MAP); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(lineTranslateAnchor(LINE_TRANSLATE_ANCHOR_MAP)); + assertEquals((String) layer.getLineTranslateAnchor().getValue(), (String) LINE_TRANSLATE_ANCHOR_MAP); + } + }); } @Test @@ -623,25 +767,30 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-translate-anchor"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineTranslateAnchor( - zoom( - interval( - stop(2, lineTranslateAnchor(LINE_TRANSLATE_ANCHOR_MAP)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineTranslateAnchor( + zoom( + interval( + stop(2, lineTranslateAnchor(LINE_TRANSLATE_ANCHOR_MAP)) + ) + ) ) - ) - ) - ); - - // Verify - assertNotNull(layer.getLineTranslateAnchor()); - assertNotNull(layer.getLineTranslateAnchor().getFunction()); - assertEquals(CameraFunction.class, layer.getLineTranslateAnchor().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getLineTranslateAnchor().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getLineTranslateAnchor().getFunction().getStops()).size()); + ); + + // Verify + assertNotNull(layer.getLineTranslateAnchor()); + assertNotNull(layer.getLineTranslateAnchor().getFunction()); + assertEquals(CameraFunction.class, layer.getLineTranslateAnchor().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getLineTranslateAnchor().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getLineTranslateAnchor().getFunction().getStops()).size()); + } + }); } @Test @@ -649,12 +798,17 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-widthTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setLineWidthTransition(options); - assertEquals(layer.getLineWidthTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setLineWidthTransition(options); + assertEquals(layer.getLineWidthTransition(), options); + } + }); } @Test @@ -662,11 +816,16 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-width"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(lineWidth(0.3f)); - assertEquals((Float) layer.getLineWidth().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(lineWidth(0.3f)); + assertEquals((Float) layer.getLineWidth().getValue(), (Float) 0.3f); + } + }); } @Test @@ -674,26 +833,31 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineWidth( - zoom( - exponential( - stop(2, lineWidth(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getLineWidth()); - assertNotNull(layer.getLineWidth().getFunction()); - assertEquals(CameraFunction.class, layer.getLineWidth().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineWidth().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineWidth( + zoom( + exponential( + stop(2, lineWidth(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getLineWidth()); + assertNotNull(layer.getLineWidth().getFunction()); + assertEquals(CameraFunction.class, layer.getLineWidth().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getLineWidth().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).size()); + } + }); } @Test @@ -701,12 +865,17 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-gap-widthTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setLineGapWidthTransition(options); - assertEquals(layer.getLineGapWidthTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setLineGapWidthTransition(options); + assertEquals(layer.getLineGapWidthTransition(), options); + } + }); } @Test @@ -714,11 +883,16 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-gap-width"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(lineGapWidth(0.3f)); - assertEquals((Float) layer.getLineGapWidth().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(lineGapWidth(0.3f)); + assertEquals((Float) layer.getLineGapWidth().getValue(), (Float) 0.3f); + } + }); } @Test @@ -726,26 +900,31 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-gap-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineGapWidth( - zoom( - exponential( - stop(2, lineGapWidth(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getLineGapWidth()); - assertNotNull(layer.getLineGapWidth().getFunction()); - assertEquals(CameraFunction.class, layer.getLineGapWidth().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineGapWidth().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getLineGapWidth().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getLineGapWidth().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineGapWidth( + zoom( + exponential( + stop(2, lineGapWidth(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getLineGapWidth()); + assertNotNull(layer.getLineGapWidth().getFunction()); + assertEquals(CameraFunction.class, layer.getLineGapWidth().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getLineGapWidth().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getLineGapWidth().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getLineGapWidth().getFunction().getStops()).size()); + } + }); } @Test @@ -753,19 +932,24 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-gap-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineGapWidth(property("FeaturePropertyA", Stops.identity())) - ); - - // Verify - assertNotNull(layer.getLineGapWidth()); - assertNotNull(layer.getLineGapWidth().getFunction()); - assertEquals(SourceFunction.class, layer.getLineGapWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineGapWidth().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getLineGapWidth().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineGapWidth(property("FeaturePropertyA", Stops.identity())) + ); + + // Verify + assertNotNull(layer.getLineGapWidth()); + assertNotNull(layer.getLineGapWidth().getFunction()); + assertEquals(SourceFunction.class, layer.getLineGapWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineGapWidth().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getLineGapWidth().getFunction().getStops().getClass()); + } + }); } @Test @@ -773,26 +957,31 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-gap-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineGapWidth( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, lineGapWidth(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getLineGapWidth()); - assertNotNull(layer.getLineGapWidth().getFunction()); - assertEquals(SourceFunction.class, layer.getLineGapWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineGapWidth().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getLineGapWidth().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineGapWidth( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, lineGapWidth(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getLineGapWidth()); + assertNotNull(layer.getLineGapWidth().getFunction()); + assertEquals(SourceFunction.class, layer.getLineGapWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineGapWidth().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getLineGapWidth().getFunction().getStops().getClass()); + } + }); } @Test @@ -800,29 +989,35 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-gap-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineGapWidth( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, lineGapWidth(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineGapWidth( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, lineGapWidth(0.3f)) + ) + ).withDefaultValue(lineGapWidth(0.3f)) ) - ).withDefaultValue(lineGapWidth(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getLineGapWidth()); - assertNotNull(layer.getLineGapWidth().getFunction()); - assertEquals(SourceFunction.class, layer.getLineGapWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineGapWidth().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getLineGapWidth().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getLineGapWidth().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getLineGapWidth().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getLineGapWidth().getFunction()).getDefaultValue().getValue()); + ); + + // Verify + assertNotNull(layer.getLineGapWidth()); + assertNotNull(layer.getLineGapWidth().getFunction()); + assertEquals(SourceFunction.class, layer.getLineGapWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineGapWidth().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getLineGapWidth().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getLineGapWidth().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getLineGapWidth().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getLineGapWidth().getFunction()).getDefaultValue().getValue()); + } + }); + } @Test @@ -830,34 +1025,39 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-gap-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineGapWidth( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, lineGapWidth(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(lineGapWidth(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getLineGapWidth()); - assertNotNull(layer.getLineGapWidth().getFunction()); - assertEquals(CompositeFunction.class, layer.getLineGapWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getLineGapWidth().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getLineGapWidth().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getLineGapWidth().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getLineGapWidth().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineGapWidth( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, lineGapWidth(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(lineGapWidth(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getLineGapWidth()); + assertNotNull(layer.getLineGapWidth().getFunction()); + assertEquals(CompositeFunction.class, layer.getLineGapWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getLineGapWidth().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getLineGapWidth().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getLineGapWidth().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getLineGapWidth().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -865,12 +1065,17 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-offsetTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setLineOffsetTransition(options); - assertEquals(layer.getLineOffsetTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setLineOffsetTransition(options); + assertEquals(layer.getLineOffsetTransition(), options); + } + }); } @Test @@ -878,11 +1083,16 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-offset"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(lineOffset(0.3f)); - assertEquals((Float) layer.getLineOffset().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(lineOffset(0.3f)); + assertEquals((Float) layer.getLineOffset().getValue(), (Float) 0.3f); + } + }); } @Test @@ -890,26 +1100,31 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-offset"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineOffset( - zoom( - exponential( - stop(2, lineOffset(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getLineOffset()); - assertNotNull(layer.getLineOffset().getFunction()); - assertEquals(CameraFunction.class, layer.getLineOffset().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineOffset().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineOffset( + zoom( + exponential( + stop(2, lineOffset(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getLineOffset()); + assertNotNull(layer.getLineOffset().getFunction()); + assertEquals(CameraFunction.class, layer.getLineOffset().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getLineOffset().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).size()); + } + }); } @Test @@ -917,19 +1132,24 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-offset"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineOffset(property("FeaturePropertyA", Stops.identity())) - ); - - // Verify - assertNotNull(layer.getLineOffset()); - assertNotNull(layer.getLineOffset().getFunction()); - assertEquals(SourceFunction.class, layer.getLineOffset().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineOffset().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getLineOffset().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineOffset(property("FeaturePropertyA", Stops.identity())) + ); + + // Verify + assertNotNull(layer.getLineOffset()); + assertNotNull(layer.getLineOffset().getFunction()); + assertEquals(SourceFunction.class, layer.getLineOffset().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineOffset().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getLineOffset().getFunction().getStops().getClass()); + } + }); } @Test @@ -937,26 +1157,31 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-offset"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineOffset( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, lineOffset(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getLineOffset()); - assertNotNull(layer.getLineOffset().getFunction()); - assertEquals(SourceFunction.class, layer.getLineOffset().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineOffset().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getLineOffset().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineOffset( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, lineOffset(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getLineOffset()); + assertNotNull(layer.getLineOffset().getFunction()); + assertEquals(SourceFunction.class, layer.getLineOffset().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineOffset().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getLineOffset().getFunction().getStops().getClass()); + } + }); } @Test @@ -964,29 +1189,35 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-offset"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineOffset( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, lineOffset(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineOffset( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, lineOffset(0.3f)) + ) + ).withDefaultValue(lineOffset(0.3f)) ) - ).withDefaultValue(lineOffset(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getLineOffset()); - assertNotNull(layer.getLineOffset().getFunction()); - assertEquals(SourceFunction.class, layer.getLineOffset().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineOffset().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getLineOffset().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getLineOffset().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getLineOffset().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getLineOffset().getFunction()).getDefaultValue().getValue()); + ); + + // Verify + assertNotNull(layer.getLineOffset()); + assertNotNull(layer.getLineOffset().getFunction()); + assertEquals(SourceFunction.class, layer.getLineOffset().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineOffset().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getLineOffset().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getLineOffset().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getLineOffset().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getLineOffset().getFunction()).getDefaultValue().getValue()); + } + }); + } @Test @@ -994,34 +1225,39 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-offset"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineOffset( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, lineOffset(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(lineOffset(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getLineOffset()); - assertNotNull(layer.getLineOffset().getFunction()); - assertEquals(CompositeFunction.class, layer.getLineOffset().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getLineOffset().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getLineOffset().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getLineOffset().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineOffset( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, lineOffset(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(lineOffset(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getLineOffset()); + assertNotNull(layer.getLineOffset().getFunction()); + assertEquals(CompositeFunction.class, layer.getLineOffset().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getLineOffset().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getLineOffset().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getLineOffset().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getLineOffset().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -1029,12 +1265,17 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-blurTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setLineBlurTransition(options); - assertEquals(layer.getLineBlurTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setLineBlurTransition(options); + assertEquals(layer.getLineBlurTransition(), options); + } + }); } @Test @@ -1042,11 +1283,16 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-blur"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(lineBlur(0.3f)); - assertEquals((Float) layer.getLineBlur().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(lineBlur(0.3f)); + assertEquals((Float) layer.getLineBlur().getValue(), (Float) 0.3f); + } + }); } @Test @@ -1054,26 +1300,31 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-blur"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineBlur( - zoom( - exponential( - stop(2, lineBlur(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getLineBlur()); - assertNotNull(layer.getLineBlur().getFunction()); - assertEquals(CameraFunction.class, layer.getLineBlur().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getLineBlur().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getLineBlur().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getLineBlur().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineBlur( + zoom( + exponential( + stop(2, lineBlur(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getLineBlur()); + assertNotNull(layer.getLineBlur().getFunction()); + assertEquals(CameraFunction.class, layer.getLineBlur().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getLineBlur().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getLineBlur().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getLineBlur().getFunction().getStops()).size()); + } + }); } @Test @@ -1081,19 +1332,24 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-blur"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineBlur(property("FeaturePropertyA", Stops.identity())) - ); - - // Verify - assertNotNull(layer.getLineBlur()); - assertNotNull(layer.getLineBlur().getFunction()); - assertEquals(SourceFunction.class, layer.getLineBlur().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineBlur().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getLineBlur().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineBlur(property("FeaturePropertyA", Stops.identity())) + ); + + // Verify + assertNotNull(layer.getLineBlur()); + assertNotNull(layer.getLineBlur().getFunction()); + assertEquals(SourceFunction.class, layer.getLineBlur().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineBlur().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getLineBlur().getFunction().getStops().getClass()); + } + }); } @Test @@ -1101,26 +1357,31 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-blur"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineBlur( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, lineBlur(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getLineBlur()); - assertNotNull(layer.getLineBlur().getFunction()); - assertEquals(SourceFunction.class, layer.getLineBlur().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineBlur().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getLineBlur().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineBlur( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, lineBlur(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getLineBlur()); + assertNotNull(layer.getLineBlur().getFunction()); + assertEquals(SourceFunction.class, layer.getLineBlur().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineBlur().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getLineBlur().getFunction().getStops().getClass()); + } + }); } @Test @@ -1128,29 +1389,35 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-blur"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineBlur( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, lineBlur(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineBlur( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, lineBlur(0.3f)) + ) + ).withDefaultValue(lineBlur(0.3f)) ) - ).withDefaultValue(lineBlur(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getLineBlur()); - assertNotNull(layer.getLineBlur().getFunction()); - assertEquals(SourceFunction.class, layer.getLineBlur().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineBlur().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getLineBlur().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getLineBlur().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getLineBlur().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getLineBlur().getFunction()).getDefaultValue().getValue()); + ); + + // Verify + assertNotNull(layer.getLineBlur()); + assertNotNull(layer.getLineBlur().getFunction()); + assertEquals(SourceFunction.class, layer.getLineBlur().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineBlur().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getLineBlur().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getLineBlur().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getLineBlur().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getLineBlur().getFunction()).getDefaultValue().getValue()); + } + }); + } @Test @@ -1158,34 +1425,39 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-blur"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineBlur( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, lineBlur(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(lineBlur(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getLineBlur()); - assertNotNull(layer.getLineBlur().getFunction()); - assertEquals(CompositeFunction.class, layer.getLineBlur().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getLineBlur().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getLineBlur().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getLineBlur().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getLineBlur().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineBlur( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, lineBlur(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(lineBlur(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getLineBlur()); + assertNotNull(layer.getLineBlur().getFunction()); + assertEquals(CompositeFunction.class, layer.getLineBlur().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getLineBlur().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getLineBlur().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getLineBlur().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getLineBlur().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -1193,12 +1465,17 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-dasharrayTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setLineDasharrayTransition(options); - assertEquals(layer.getLineDasharrayTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setLineDasharrayTransition(options); + assertEquals(layer.getLineDasharrayTransition(), options); + } + }); } @Test @@ -1206,11 +1483,16 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-dasharray"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(lineDasharray(new Float[]{})); - assertEquals((Float[]) layer.getLineDasharray().getValue(), (Float[]) new Float[]{}); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(lineDasharray(new Float[] {})); + assertEquals((Float[]) layer.getLineDasharray().getValue(), (Float[]) new Float[] {}); + } + }); } @Test @@ -1218,25 +1500,30 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-dasharray"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineDasharray( - zoom( - interval( - stop(2, lineDasharray(new Float[]{})) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineDasharray( + zoom( + interval( + stop(2, lineDasharray(new Float[] {})) + ) + ) ) - ) - ) - ); - - // Verify - assertNotNull(layer.getLineDasharray()); - assertNotNull(layer.getLineDasharray().getFunction()); - assertEquals(CameraFunction.class, layer.getLineDasharray().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getLineDasharray().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getLineDasharray().getFunction().getStops()).size()); + ); + + // Verify + assertNotNull(layer.getLineDasharray()); + assertNotNull(layer.getLineDasharray().getFunction()); + assertEquals(CameraFunction.class, layer.getLineDasharray().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getLineDasharray().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getLineDasharray().getFunction().getStops()).size()); + } + }); } @Test @@ -1244,12 +1531,17 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-patternTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setLinePatternTransition(options); - assertEquals(layer.getLinePatternTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setLinePatternTransition(options); + assertEquals(layer.getLinePatternTransition(), options); + } + }); } @Test @@ -1257,11 +1549,16 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-pattern"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(linePattern("pedestrian-polygon")); - assertEquals((String) layer.getLinePattern().getValue(), (String) "pedestrian-polygon"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(linePattern("pedestrian-polygon")); + assertEquals((String) layer.getLinePattern().getValue(), (String) "pedestrian-polygon"); + } + }); } @Test @@ -1269,25 +1566,30 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-pattern"); - assertNotNull(layer); - - // Set - layer.setProperties( - linePattern( - zoom( - interval( - stop(2, linePattern("pedestrian-polygon")) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + linePattern( + zoom( + interval( + stop(2, linePattern("pedestrian-polygon")) + ) + ) ) - ) - ) - ); - - // Verify - assertNotNull(layer.getLinePattern()); - assertNotNull(layer.getLinePattern().getFunction()); - assertEquals(CameraFunction.class, layer.getLinePattern().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getLinePattern().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getLinePattern().getFunction().getStops()).size()); + ); + + // Verify + assertNotNull(layer.getLinePattern()); + assertNotNull(layer.getLinePattern().getFunction()); + assertEquals(CameraFunction.class, layer.getLinePattern().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getLinePattern().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getLinePattern().getFunction().getStops()).size()); + } + }); } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerTest.java index 2a0d3401fb..020effe331 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerTest.java @@ -3,9 +3,9 @@ package com.mapbox.mapboxsdk.testapp.style; import android.graphics.Color; -import android.support.test.espresso.Espresso; -import android.support.test.rule.ActivityTestRule; +import android.support.test.espresso.UiController; import android.support.test.runner.AndroidJUnit4; + import timber.log.Timber; import com.mapbox.mapboxsdk.maps.MapboxMap; @@ -19,20 +19,16 @@ import com.mapbox.mapboxsdk.style.functions.stops.IntervalStops; import com.mapbox.mapboxsdk.style.functions.stops.Stop; import com.mapbox.mapboxsdk.style.functions.stops.Stops; import com.mapbox.mapboxsdk.style.layers.RasterLayer; -import com.mapbox.mapboxsdk.testapp.R; -import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; -import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import static com.mapbox.mapboxsdk.style.functions.Function.*; import static com.mapbox.mapboxsdk.style.functions.stops.Stop.stop; import static com.mapbox.mapboxsdk.style.functions.stops.Stops.*; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; import static org.junit.Assert.*; import static com.mapbox.mapboxsdk.style.layers.Property.*; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; @@ -53,15 +49,21 @@ public class RasterLayerTest extends BaseActivityTest { return EspressoTestActivity.class; } - private void setupLayer(){ - if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { - Timber.i("Adding layer"); - layer = new RasterLayer("my-layer", "composite"); - layer.setSourceLayer("composite"); - mapboxMap.addLayer(layer); - // Layer reference is now stale, get new reference - layer = mapboxMap.getLayerAs("my-layer"); - } + private void setupLayer() { + Timber.i("Retrieving layer"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Timber.i("Adding layer"); + layer = new RasterLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + // Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + } + }); } @Test @@ -69,14 +71,19 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("Visibility"); - assertNotNull(layer); - - // Get initial - assertEquals(layer.getVisibility().getValue(), VISIBLE); - - // Set - layer.setProperties(visibility(NONE)); - assertEquals(layer.getVisibility().getValue(), NONE); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + // Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + }); } @Test @@ -84,12 +91,17 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-opacityTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setRasterOpacityTransition(options); - assertEquals(layer.getRasterOpacityTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setRasterOpacityTransition(options); + assertEquals(layer.getRasterOpacityTransition(), options); + } + }); } @Test @@ -97,11 +109,16 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-opacity"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(rasterOpacity(0.3f)); - assertEquals((Float) layer.getRasterOpacity().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(rasterOpacity(0.3f)); + assertEquals((Float) layer.getRasterOpacity().getValue(), (Float) 0.3f); + } + }); } @Test @@ -109,26 +126,31 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - rasterOpacity( - zoom( - exponential( - stop(2, rasterOpacity(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getRasterOpacity()); - assertNotNull(layer.getRasterOpacity().getFunction()); - assertEquals(CameraFunction.class, layer.getRasterOpacity().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getRasterOpacity().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getRasterOpacity().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getRasterOpacity().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + rasterOpacity( + zoom( + exponential( + stop(2, rasterOpacity(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getRasterOpacity()); + assertNotNull(layer.getRasterOpacity().getFunction()); + assertEquals(CameraFunction.class, layer.getRasterOpacity().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getRasterOpacity().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getRasterOpacity().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getRasterOpacity().getFunction().getStops()).size()); + } + }); } @Test @@ -136,12 +158,17 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-hue-rotateTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setRasterHueRotateTransition(options); - assertEquals(layer.getRasterHueRotateTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setRasterHueRotateTransition(options); + assertEquals(layer.getRasterHueRotateTransition(), options); + } + }); } @Test @@ -149,11 +176,16 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-hue-rotate"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(rasterHueRotate(0.3f)); - assertEquals((Float) layer.getRasterHueRotate().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(rasterHueRotate(0.3f)); + assertEquals((Float) layer.getRasterHueRotate().getValue(), (Float) 0.3f); + } + }); } @Test @@ -161,26 +193,31 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-hue-rotate"); - assertNotNull(layer); - - // Set - layer.setProperties( - rasterHueRotate( - zoom( - exponential( - stop(2, rasterHueRotate(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getRasterHueRotate()); - assertNotNull(layer.getRasterHueRotate().getFunction()); - assertEquals(CameraFunction.class, layer.getRasterHueRotate().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getRasterHueRotate().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getRasterHueRotate().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getRasterHueRotate().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + rasterHueRotate( + zoom( + exponential( + stop(2, rasterHueRotate(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getRasterHueRotate()); + assertNotNull(layer.getRasterHueRotate().getFunction()); + assertEquals(CameraFunction.class, layer.getRasterHueRotate().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getRasterHueRotate().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getRasterHueRotate().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getRasterHueRotate().getFunction().getStops()).size()); + } + }); } @Test @@ -188,12 +225,17 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-brightness-minTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setRasterBrightnessMinTransition(options); - assertEquals(layer.getRasterBrightnessMinTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setRasterBrightnessMinTransition(options); + assertEquals(layer.getRasterBrightnessMinTransition(), options); + } + }); } @Test @@ -201,11 +243,16 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-brightness-min"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(rasterBrightnessMin(0.3f)); - assertEquals((Float) layer.getRasterBrightnessMin().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(rasterBrightnessMin(0.3f)); + assertEquals((Float) layer.getRasterBrightnessMin().getValue(), (Float) 0.3f); + } + }); } @Test @@ -213,26 +260,31 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-brightness-min"); - assertNotNull(layer); - - // Set - layer.setProperties( - rasterBrightnessMin( - zoom( - exponential( - stop(2, rasterBrightnessMin(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getRasterBrightnessMin()); - assertNotNull(layer.getRasterBrightnessMin().getFunction()); - assertEquals(CameraFunction.class, layer.getRasterBrightnessMin().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getRasterBrightnessMin().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getRasterBrightnessMin().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getRasterBrightnessMin().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + rasterBrightnessMin( + zoom( + exponential( + stop(2, rasterBrightnessMin(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getRasterBrightnessMin()); + assertNotNull(layer.getRasterBrightnessMin().getFunction()); + assertEquals(CameraFunction.class, layer.getRasterBrightnessMin().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getRasterBrightnessMin().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getRasterBrightnessMin().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getRasterBrightnessMin().getFunction().getStops()).size()); + } + }); } @Test @@ -240,12 +292,17 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-brightness-maxTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setRasterBrightnessMaxTransition(options); - assertEquals(layer.getRasterBrightnessMaxTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setRasterBrightnessMaxTransition(options); + assertEquals(layer.getRasterBrightnessMaxTransition(), options); + } + }); } @Test @@ -253,11 +310,16 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-brightness-max"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(rasterBrightnessMax(0.3f)); - assertEquals((Float) layer.getRasterBrightnessMax().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(rasterBrightnessMax(0.3f)); + assertEquals((Float) layer.getRasterBrightnessMax().getValue(), (Float) 0.3f); + } + }); } @Test @@ -265,26 +327,31 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-brightness-max"); - assertNotNull(layer); - - // Set - layer.setProperties( - rasterBrightnessMax( - zoom( - exponential( - stop(2, rasterBrightnessMax(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getRasterBrightnessMax()); - assertNotNull(layer.getRasterBrightnessMax().getFunction()); - assertEquals(CameraFunction.class, layer.getRasterBrightnessMax().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getRasterBrightnessMax().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getRasterBrightnessMax().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getRasterBrightnessMax().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + rasterBrightnessMax( + zoom( + exponential( + stop(2, rasterBrightnessMax(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getRasterBrightnessMax()); + assertNotNull(layer.getRasterBrightnessMax().getFunction()); + assertEquals(CameraFunction.class, layer.getRasterBrightnessMax().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getRasterBrightnessMax().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getRasterBrightnessMax().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getRasterBrightnessMax().getFunction().getStops()).size()); + } + }); } @Test @@ -292,12 +359,17 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-saturationTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setRasterSaturationTransition(options); - assertEquals(layer.getRasterSaturationTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setRasterSaturationTransition(options); + assertEquals(layer.getRasterSaturationTransition(), options); + } + }); } @Test @@ -305,11 +377,16 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-saturation"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(rasterSaturation(0.3f)); - assertEquals((Float) layer.getRasterSaturation().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(rasterSaturation(0.3f)); + assertEquals((Float) layer.getRasterSaturation().getValue(), (Float) 0.3f); + } + }); } @Test @@ -317,26 +394,31 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-saturation"); - assertNotNull(layer); - - // Set - layer.setProperties( - rasterSaturation( - zoom( - exponential( - stop(2, rasterSaturation(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getRasterSaturation()); - assertNotNull(layer.getRasterSaturation().getFunction()); - assertEquals(CameraFunction.class, layer.getRasterSaturation().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getRasterSaturation().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getRasterSaturation().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getRasterSaturation().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + rasterSaturation( + zoom( + exponential( + stop(2, rasterSaturation(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getRasterSaturation()); + assertNotNull(layer.getRasterSaturation().getFunction()); + assertEquals(CameraFunction.class, layer.getRasterSaturation().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getRasterSaturation().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getRasterSaturation().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getRasterSaturation().getFunction().getStops()).size()); + } + }); } @Test @@ -344,12 +426,17 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-contrastTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setRasterContrastTransition(options); - assertEquals(layer.getRasterContrastTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setRasterContrastTransition(options); + assertEquals(layer.getRasterContrastTransition(), options); + } + }); } @Test @@ -357,11 +444,16 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-contrast"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(rasterContrast(0.3f)); - assertEquals((Float) layer.getRasterContrast().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(rasterContrast(0.3f)); + assertEquals((Float) layer.getRasterContrast().getValue(), (Float) 0.3f); + } + }); } @Test @@ -369,26 +461,31 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-contrast"); - assertNotNull(layer); - - // Set - layer.setProperties( - rasterContrast( - zoom( - exponential( - stop(2, rasterContrast(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getRasterContrast()); - assertNotNull(layer.getRasterContrast().getFunction()); - assertEquals(CameraFunction.class, layer.getRasterContrast().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getRasterContrast().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getRasterContrast().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getRasterContrast().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + rasterContrast( + zoom( + exponential( + stop(2, rasterContrast(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getRasterContrast()); + assertNotNull(layer.getRasterContrast().getFunction()); + assertEquals(CameraFunction.class, layer.getRasterContrast().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getRasterContrast().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getRasterContrast().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getRasterContrast().getFunction().getStops()).size()); + } + }); } @Test @@ -396,12 +493,17 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-fade-durationTransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setRasterFadeDurationTransition(options); - assertEquals(layer.getRasterFadeDurationTransition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setRasterFadeDurationTransition(options); + assertEquals(layer.getRasterFadeDurationTransition(), options); + } + }); } @Test @@ -409,11 +511,16 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-fade-duration"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(rasterFadeDuration(0.3f)); - assertEquals((Float) layer.getRasterFadeDuration().getValue(), (Float) 0.3f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(rasterFadeDuration(0.3f)); + assertEquals((Float) layer.getRasterFadeDuration().getValue(), (Float) 0.3f); + } + }); } @Test @@ -421,26 +528,31 @@ public class RasterLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("raster-fade-duration"); - assertNotNull(layer); - - // Set - layer.setProperties( - rasterFadeDuration( - zoom( - exponential( - stop(2, rasterFadeDuration(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getRasterFadeDuration()); - assertNotNull(layer.getRasterFadeDuration().getFunction()); - assertEquals(CameraFunction.class, layer.getRasterFadeDuration().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getRasterFadeDuration().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getRasterFadeDuration().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getRasterFadeDuration().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + rasterFadeDuration( + zoom( + exponential( + stop(2, rasterFadeDuration(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getRasterFadeDuration()); + assertNotNull(layer.getRasterFadeDuration().getFunction()); + assertEquals(CameraFunction.class, layer.getRasterFadeDuration().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getRasterFadeDuration().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getRasterFadeDuration().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getRasterFadeDuration().getFunction().getStops()).size()); + } + }); } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleBackgroundLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleBackgroundLayerTest.java deleted file mode 100644 index c95c959644..0000000000 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleBackgroundLayerTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.mapbox.mapboxsdk.testapp.style; - -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; -import android.test.ActivityInstrumentationTestCase2; - -import timber.log.Timber; - -import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; -import com.mapbox.mapboxsdk.style.layers.BackgroundLayer; -import com.mapbox.mapboxsdk.style.layers.Property; -import com.mapbox.mapboxsdk.style.layers.PropertyFactory; -import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Basic smoke tests for BackgroundLayer - */ -@RunWith(AndroidJUnit4.class) -public class RuntimeStyleBackgroundLayerTest - extends ActivityInstrumentationTestCase2 { - - public RuntimeStyleBackgroundLayerTest() { - super(RuntimeStyleTestActivity.class); - } - - @Before - public void setUp() throws Exception { - super.setUp(); - injectInstrumentation(InstrumentationRegistry.getInstrumentation()); - } - - @Test - public void testSetVisibility() { - getActivity().mapView.getMapAsync(new OnMapReadyCallback() { - @Override - public void onMapReady(MapboxMap mapboxMap) { - Timber.i("visibility"); - BackgroundLayer layer = mapboxMap.getLayerAs("background"); - assertNotNull(layer); - - // Get initial - assertEquals(layer.getVisibility().getValue(), Property.VISIBLE); - - // Set - layer.setProperties(PropertyFactory.visibility(Property.NONE)); - assertEquals(layer.getVisibility().getValue(), Property.NONE); - } - }); - } - - @After - public void tearDown() throws Exception { - super.tearDown(); - } -} 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 a37615aadc..bf8bcb9f66 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 @@ -8,6 +8,7 @@ import android.support.test.espresso.ViewAction; import android.support.test.runner.AndroidJUnit4; import android.view.View; +import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.style.layers.CannotAddLayerException; import com.mapbox.mapboxsdk.style.layers.CircleLayer; import com.mapbox.mapboxsdk.style.layers.FillLayer; @@ -21,6 +22,7 @@ import com.mapbox.mapboxsdk.style.sources.RasterSource; 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.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; @@ -40,6 +42,7 @@ 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; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -189,39 +192,89 @@ public class RuntimeStyleTests extends BaseActivityTest { @Test public void testAddRemoveSource() { validateTestSetup(); - mapboxMap.addSource(new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2")); - mapboxMap.removeSource("my-source"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + mapboxMap.addSource(new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2")); + mapboxMap.removeSource("my-source"); + + // Add initial source + mapboxMap.addSource(new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2")); + + // Remove + Source mySource = mapboxMap.removeSource("my-source"); + assertNotNull(mySource); + assertNull(mapboxMap.getLayer("my-source")); + + // Add + Source source = new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2"); + mapboxMap.addSource(source); + + // Remove, preserving the reference + mapboxMap.removeSource(source); + + // Re-add the reference... + mapboxMap.addSource(source); + + // Ensure it's there + Assert.assertNotNull(mapboxMap.getSource(source.getId())); + + // Test adding a duplicate source + try { + Source source2 = new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2"); + mapboxMap.addSource(source2); + fail("Should not have been allowed to add a source with a duplicate id"); + } catch (CannotAddSourceException cannotAddSourceException) { + // OK + } + } + }); - onView(withId(R.id.mapView)).perform(new AddRemoveSourceAction()); } @Test public void testVectorSourceUrlGetter() { validateTestSetup(); - - VectorSource source = new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2"); - mapboxMap.addSource(source); - assertEquals("mapbox://mapbox.mapbox-terrain-v2", source.getUrl()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + VectorSource source = new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2"); + mapboxMap.addSource(source); + assertEquals("mapbox://mapbox.mapbox-terrain-v2", source.getUrl()); + } + }); } @Test public void testRasterSourceUrlGetter() { validateTestSetup(); - - RasterSource source = new RasterSource("my-source", "mapbox://mapbox.mapbox-terrain-v2"); - mapboxMap.addSource(source); - assertEquals("mapbox://mapbox.mapbox-terrain-v2", source.getUrl()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + RasterSource source = new RasterSource("my-source", "mapbox://mapbox.mapbox-terrain-v2"); + mapboxMap.addSource(source); + assertEquals("mapbox://mapbox.mapbox-terrain-v2", source.getUrl()); + } + }); } @Test public void testGeoJsonSourceUrlGetter() throws MalformedURLException { validateTestSetup(); - - GeoJsonSource source = new GeoJsonSource("my-source"); - mapboxMap.addSource(source); - assertNull(source.getUrl()); - source.setUrl(new URL("http://mapbox.com/my-file.json")); - assertEquals("http://mapbox.com/my-file.json", source.getUrl()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + GeoJsonSource source = new GeoJsonSource("my-source"); + mapboxMap.addSource(source); + assertNull(source.getUrl()); + try { + source.setUrl(new URL("http://mapbox.com/my-file.json")); + } catch (MalformedURLException exception) { + fail(); + } + assertEquals("http://mapbox.com/my-file.json", source.getUrl()); + } + }); } @Test @@ -304,42 +357,6 @@ public class RuntimeStyleTests extends BaseActivityTest { } } - private class AddRemoveSourceAction extends BaseViewAction { - - @Override - public void perform(UiController uiController, View view) { - // Add initial source - mapboxMap.addSource(new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2")); - - // Remove - Source mySource = mapboxMap.removeSource("my-source"); - assertNotNull(mySource); - assertNull(mapboxMap.getLayer("my-source")); - - // Add - Source source = new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2"); - mapboxMap.addSource(source); - - // Remove, preserving the reference - mapboxMap.removeSource(source); - - // Re-add the reference... - mapboxMap.addSource(source); - - // Ensure it's there - Assert.assertNotNull(mapboxMap.getSource(source.getId())); - - // Test adding a duplicate source - try { - Source source2 = new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2"); - mapboxMap.addSource(source2); - fail("Should not have been allowed to add a source with a duplicate id"); - } catch (CannotAddSourceException cannotAddSourceException) { - // OK - } - } - } - @After public void unregisterIntentServiceIdlingResource() { Espresso.unregisterIdlingResources(idlingResource); 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 737a66713a..b0854f4a47 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 @@ -3,9 +3,9 @@ package com.mapbox.mapboxsdk.testapp.style; import android.graphics.Color; -import android.support.test.espresso.Espresso; -import android.support.test.rule.ActivityTestRule; +import android.support.test.espresso.UiController; import android.support.test.runner.AndroidJUnit4; + import timber.log.Timber; import com.mapbox.mapboxsdk.maps.MapboxMap; @@ -19,20 +19,16 @@ import com.mapbox.mapboxsdk.style.functions.stops.IntervalStops; import com.mapbox.mapboxsdk.style.functions.stops.Stop; import com.mapbox.mapboxsdk.style.functions.stops.Stops; import com.mapbox.mapboxsdk.style.layers.SymbolLayer; -import com.mapbox.mapboxsdk.testapp.R; -import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; -import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import static com.mapbox.mapboxsdk.style.functions.Function.*; import static com.mapbox.mapboxsdk.style.functions.stops.Stop.stop; import static com.mapbox.mapboxsdk.style.functions.stops.Stops.*; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; import static org.junit.Assert.*; import static com.mapbox.mapboxsdk.style.layers.Property.*; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; @@ -53,15 +49,21 @@ public class SymbolLayerTest extends BaseActivityTest { return EspressoTestActivity.class; } - private void setupLayer(){ - if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { - Timber.i("Adding layer"); - layer = new SymbolLayer("my-layer", "composite"); - layer.setSourceLayer("composite"); - mapboxMap.addLayer(layer); - // Layer reference is now stale, get new reference - layer = mapboxMap.getLayerAs("my-layer"); - } + private void setupLayer() { + Timber.i("Retrieving layer"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Timber.i("Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + // Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + } + }); } @Test @@ -69,14 +71,19 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("Visibility"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Get initial - assertEquals(layer.getVisibility().getValue(), VISIBLE); + // Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); - // Set - layer.setProperties(visibility(NONE)); - assertEquals(layer.getVisibility().getValue(), NONE); + // Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + }); } @Test @@ -84,15 +91,20 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("SourceLayer"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Get initial - assertEquals(layer.getSourceLayer(), "composite"); + // Get initial + assertEquals(layer.getSourceLayer(), "composite"); - // Set - final String sourceLayer = "test"; - layer.setSourceLayer(sourceLayer); - assertEquals(layer.getSourceLayer(), sourceLayer); + // Set + final String sourceLayer = "test"; + layer.setSourceLayer(sourceLayer); + assertEquals(layer.getSourceLayer(), sourceLayer); + } + }); } @Test @@ -100,11 +112,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("symbol-placement"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(symbolPlacement(SYMBOL_PLACEMENT_POINT)); - assertEquals((String) layer.getSymbolPlacement().getValue(), (String) SYMBOL_PLACEMENT_POINT); + // Set and Get + layer.setProperties(symbolPlacement(SYMBOL_PLACEMENT_POINT)); + assertEquals((String) layer.getSymbolPlacement().getValue(), (String) SYMBOL_PLACEMENT_POINT); + } + }); } @Test @@ -112,25 +129,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("symbol-placement"); - assertNotNull(layer); - - // Set - layer.setProperties( - symbolPlacement( - zoom( - interval( - stop(2, symbolPlacement(SYMBOL_PLACEMENT_POINT)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + symbolPlacement( + zoom( + interval( + stop(2, symbolPlacement(SYMBOL_PLACEMENT_POINT)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getSymbolPlacement()); - assertNotNull(layer.getSymbolPlacement().getFunction()); - assertEquals(CameraFunction.class, layer.getSymbolPlacement().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getSymbolPlacement().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getSymbolPlacement().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getSymbolPlacement()); + assertNotNull(layer.getSymbolPlacement().getFunction()); + assertEquals(CameraFunction.class, layer.getSymbolPlacement().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getSymbolPlacement().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getSymbolPlacement().getFunction().getStops()).size()); + } + }); } @Test @@ -138,11 +160,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("symbol-spacing"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(symbolSpacing(0.3f)); - assertEquals((Float) layer.getSymbolSpacing().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(symbolSpacing(0.3f)); + assertEquals((Float) layer.getSymbolSpacing().getValue(), (Float) 0.3f); + } + }); } @Test @@ -150,26 +177,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("symbol-spacing"); - assertNotNull(layer); - - // Set - layer.setProperties( - symbolSpacing( - zoom( - exponential( - stop(2, symbolSpacing(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + symbolSpacing( + zoom( + exponential( + stop(2, symbolSpacing(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getSymbolSpacing()); - assertNotNull(layer.getSymbolSpacing().getFunction()); - assertEquals(CameraFunction.class, layer.getSymbolSpacing().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getSymbolSpacing().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getSymbolSpacing().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getSymbolSpacing().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getSymbolSpacing()); + assertNotNull(layer.getSymbolSpacing().getFunction()); + assertEquals(CameraFunction.class, layer.getSymbolSpacing().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getSymbolSpacing().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getSymbolSpacing().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getSymbolSpacing().getFunction().getStops()).size()); + } + }); } @Test @@ -177,11 +209,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("symbol-avoid-edges"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(symbolAvoidEdges(true)); - assertEquals((Boolean) layer.getSymbolAvoidEdges().getValue(), (Boolean) true); + // Set and Get + layer.setProperties(symbolAvoidEdges(true)); + assertEquals((Boolean) layer.getSymbolAvoidEdges().getValue(), (Boolean) true); + } + }); } @Test @@ -189,25 +226,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("symbol-avoid-edges"); - assertNotNull(layer); - - // Set - layer.setProperties( - symbolAvoidEdges( - zoom( - interval( - stop(2, symbolAvoidEdges(true)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + symbolAvoidEdges( + zoom( + interval( + stop(2, symbolAvoidEdges(true)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getSymbolAvoidEdges()); - assertNotNull(layer.getSymbolAvoidEdges().getFunction()); - assertEquals(CameraFunction.class, layer.getSymbolAvoidEdges().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getSymbolAvoidEdges().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getSymbolAvoidEdges().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getSymbolAvoidEdges()); + assertNotNull(layer.getSymbolAvoidEdges().getFunction()); + assertEquals(CameraFunction.class, layer.getSymbolAvoidEdges().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getSymbolAvoidEdges().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getSymbolAvoidEdges().getFunction().getStops()).size()); + } + }); } @Test @@ -215,11 +257,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-allow-overlap"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconAllowOverlap(true)); - assertEquals((Boolean) layer.getIconAllowOverlap().getValue(), (Boolean) true); + // Set and Get + layer.setProperties(iconAllowOverlap(true)); + assertEquals((Boolean) layer.getIconAllowOverlap().getValue(), (Boolean) true); + } + }); } @Test @@ -227,25 +274,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-allow-overlap"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconAllowOverlap( - zoom( - interval( - stop(2, iconAllowOverlap(true)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconAllowOverlap( + zoom( + interval( + stop(2, iconAllowOverlap(true)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getIconAllowOverlap()); - assertNotNull(layer.getIconAllowOverlap().getFunction()); - assertEquals(CameraFunction.class, layer.getIconAllowOverlap().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getIconAllowOverlap().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getIconAllowOverlap().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getIconAllowOverlap()); + assertNotNull(layer.getIconAllowOverlap().getFunction()); + assertEquals(CameraFunction.class, layer.getIconAllowOverlap().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getIconAllowOverlap().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getIconAllowOverlap().getFunction().getStops()).size()); + } + }); } @Test @@ -253,11 +305,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-ignore-placement"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconIgnorePlacement(true)); - assertEquals((Boolean) layer.getIconIgnorePlacement().getValue(), (Boolean) true); + // Set and Get + layer.setProperties(iconIgnorePlacement(true)); + assertEquals((Boolean) layer.getIconIgnorePlacement().getValue(), (Boolean) true); + } + }); } @Test @@ -265,25 +322,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-ignore-placement"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconIgnorePlacement( - zoom( - interval( - stop(2, iconIgnorePlacement(true)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconIgnorePlacement( + zoom( + interval( + stop(2, iconIgnorePlacement(true)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getIconIgnorePlacement()); - assertNotNull(layer.getIconIgnorePlacement().getFunction()); - assertEquals(CameraFunction.class, layer.getIconIgnorePlacement().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getIconIgnorePlacement().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getIconIgnorePlacement().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getIconIgnorePlacement()); + assertNotNull(layer.getIconIgnorePlacement().getFunction()); + assertEquals(CameraFunction.class, layer.getIconIgnorePlacement().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getIconIgnorePlacement().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getIconIgnorePlacement().getFunction().getStops()).size()); + } + }); } @Test @@ -291,11 +353,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-optional"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconOptional(true)); - assertEquals((Boolean) layer.getIconOptional().getValue(), (Boolean) true); + // Set and Get + layer.setProperties(iconOptional(true)); + assertEquals((Boolean) layer.getIconOptional().getValue(), (Boolean) true); + } + }); } @Test @@ -303,25 +370,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-optional"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconOptional( - zoom( - interval( - stop(2, iconOptional(true)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconOptional( + zoom( + interval( + stop(2, iconOptional(true)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getIconOptional()); - assertNotNull(layer.getIconOptional().getFunction()); - assertEquals(CameraFunction.class, layer.getIconOptional().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getIconOptional().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getIconOptional().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getIconOptional()); + assertNotNull(layer.getIconOptional().getFunction()); + assertEquals(CameraFunction.class, layer.getIconOptional().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getIconOptional().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getIconOptional().getFunction().getStops()).size()); + } + }); } @Test @@ -329,11 +401,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-rotation-alignment"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconRotationAlignment(ICON_ROTATION_ALIGNMENT_MAP)); - assertEquals((String) layer.getIconRotationAlignment().getValue(), (String) ICON_ROTATION_ALIGNMENT_MAP); + // Set and Get + layer.setProperties(iconRotationAlignment(ICON_ROTATION_ALIGNMENT_MAP)); + assertEquals((String) layer.getIconRotationAlignment().getValue(), (String) ICON_ROTATION_ALIGNMENT_MAP); + } + }); } @Test @@ -341,25 +418,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-rotation-alignment"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconRotationAlignment( - zoom( - interval( - stop(2, iconRotationAlignment(ICON_ROTATION_ALIGNMENT_MAP)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconRotationAlignment( + zoom( + interval( + stop(2, iconRotationAlignment(ICON_ROTATION_ALIGNMENT_MAP)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getIconRotationAlignment()); - assertNotNull(layer.getIconRotationAlignment().getFunction()); - assertEquals(CameraFunction.class, layer.getIconRotationAlignment().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getIconRotationAlignment().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getIconRotationAlignment().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getIconRotationAlignment()); + assertNotNull(layer.getIconRotationAlignment().getFunction()); + assertEquals(CameraFunction.class, layer.getIconRotationAlignment().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getIconRotationAlignment().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getIconRotationAlignment().getFunction().getStops()).size()); + } + }); } @Test @@ -367,11 +449,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-size"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconSize(0.3f)); - assertEquals((Float) layer.getIconSize().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(iconSize(0.3f)); + assertEquals((Float) layer.getIconSize().getValue(), (Float) 0.3f); + } + }); } @Test @@ -379,26 +466,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-size"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconSize( - zoom( - exponential( - stop(2, iconSize(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconSize( + zoom( + exponential( + stop(2, iconSize(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getIconSize()); - assertNotNull(layer.getIconSize().getFunction()); - assertEquals(CameraFunction.class, layer.getIconSize().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getIconSize().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getIconSize().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getIconSize().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getIconSize()); + assertNotNull(layer.getIconSize().getFunction()); + assertEquals(CameraFunction.class, layer.getIconSize().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getIconSize().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getIconSize().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getIconSize().getFunction().getStops()).size()); + } + }); } @Test @@ -406,19 +498,24 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-size"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - iconSize(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + iconSize(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getIconSize()); - assertNotNull(layer.getIconSize().getFunction()); - assertEquals(SourceFunction.class, layer.getIconSize().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconSize().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getIconSize().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getIconSize()); + assertNotNull(layer.getIconSize().getFunction()); + assertEquals(SourceFunction.class, layer.getIconSize().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconSize().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getIconSize().getFunction().getStops().getClass()); + } + }); } @Test @@ -426,26 +523,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-size"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconSize( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, iconSize(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconSize( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, iconSize(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getIconSize()); - assertNotNull(layer.getIconSize().getFunction()); - assertEquals(SourceFunction.class, layer.getIconSize().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconSize().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getIconSize().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getIconSize()); + assertNotNull(layer.getIconSize().getFunction()); + assertEquals(SourceFunction.class, layer.getIconSize().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconSize().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getIconSize().getFunction().getStops().getClass()); + } + }); } @Test @@ -453,29 +555,35 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-size"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconSize( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, iconSize(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconSize( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, iconSize(0.3f)) + ) + ).withDefaultValue(iconSize(0.3f)) ) - ).withDefaultValue(iconSize(0.3f)) - ) - ); + ); + + // Verify + assertNotNull(layer.getIconSize()); + assertNotNull(layer.getIconSize().getFunction()); + assertEquals(SourceFunction.class, layer.getIconSize().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconSize().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getIconSize().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getIconSize().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getIconSize().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getIconSize().getFunction()).getDefaultValue().getValue()); + } + }); - // Verify - assertNotNull(layer.getIconSize()); - assertNotNull(layer.getIconSize().getFunction()); - assertEquals(SourceFunction.class, layer.getIconSize().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconSize().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getIconSize().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getIconSize().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getIconSize().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getIconSize().getFunction()).getDefaultValue().getValue()); } @Test @@ -483,34 +591,39 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-size"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconSize( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, iconSize(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(iconSize(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getIconSize()); - assertNotNull(layer.getIconSize().getFunction()); - assertEquals(CompositeFunction.class, layer.getIconSize().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getIconSize().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getIconSize().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getIconSize().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getIconSize().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconSize( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, iconSize(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(iconSize(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getIconSize()); + assertNotNull(layer.getIconSize().getFunction()); + assertEquals(CompositeFunction.class, layer.getIconSize().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getIconSize().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getIconSize().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getIconSize().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getIconSize().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -518,11 +631,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-text-fit"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconTextFit(ICON_TEXT_FIT_NONE)); - assertEquals((String) layer.getIconTextFit().getValue(), (String) ICON_TEXT_FIT_NONE); + // Set and Get + layer.setProperties(iconTextFit(ICON_TEXT_FIT_NONE)); + assertEquals((String) layer.getIconTextFit().getValue(), (String) ICON_TEXT_FIT_NONE); + } + }); } @Test @@ -530,25 +648,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-text-fit"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconTextFit( - zoom( - interval( - stop(2, iconTextFit(ICON_TEXT_FIT_NONE)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconTextFit( + zoom( + interval( + stop(2, iconTextFit(ICON_TEXT_FIT_NONE)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getIconTextFit()); - assertNotNull(layer.getIconTextFit().getFunction()); - assertEquals(CameraFunction.class, layer.getIconTextFit().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getIconTextFit().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getIconTextFit().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getIconTextFit()); + assertNotNull(layer.getIconTextFit().getFunction()); + assertEquals(CameraFunction.class, layer.getIconTextFit().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getIconTextFit().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getIconTextFit().getFunction().getStops()).size()); + } + }); } @Test @@ -556,11 +679,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-text-fit-padding"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconTextFitPadding(new Float[]{0f,0f,0f,0f})); - assertEquals((Float[]) layer.getIconTextFitPadding().getValue(), (Float[]) new Float[]{0f,0f,0f,0f}); + // Set and Get + layer.setProperties(iconTextFitPadding(new Float[] {0f, 0f, 0f, 0f})); + assertEquals((Float[]) layer.getIconTextFitPadding().getValue(), (Float[]) new Float[] {0f, 0f, 0f, 0f}); + } + }); } @Test @@ -568,26 +696,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-text-fit-padding"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconTextFitPadding( - zoom( - exponential( - stop(2, iconTextFitPadding(new Float[]{0f,0f,0f,0f})) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconTextFitPadding( + zoom( + exponential( + stop(2, iconTextFitPadding(new Float[] {0f, 0f, 0f, 0f})) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getIconTextFitPadding()); - assertNotNull(layer.getIconTextFitPadding().getFunction()); - assertEquals(CameraFunction.class, layer.getIconTextFitPadding().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getIconTextFitPadding().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getIconTextFitPadding().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getIconTextFitPadding().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getIconTextFitPadding()); + assertNotNull(layer.getIconTextFitPadding().getFunction()); + assertEquals(CameraFunction.class, layer.getIconTextFitPadding().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getIconTextFitPadding().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getIconTextFitPadding().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getIconTextFitPadding().getFunction().getStops()).size()); + } + }); } @Test @@ -595,11 +728,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-image"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconImage("undefined")); - assertEquals((String) layer.getIconImage().getValue(), (String) "undefined"); + // Set and Get + layer.setProperties(iconImage("undefined")); + assertEquals((String) layer.getIconImage().getValue(), (String) "undefined"); + } + }); } @Test @@ -607,25 +745,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-image"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconImage( - zoom( - interval( - stop(2, iconImage("undefined")) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconImage( + zoom( + interval( + stop(2, iconImage("undefined")) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getIconImage()); - assertNotNull(layer.getIconImage().getFunction()); - assertEquals(CameraFunction.class, layer.getIconImage().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getIconImage().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getIconImage().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getIconImage()); + assertNotNull(layer.getIconImage().getFunction()); + assertEquals(CameraFunction.class, layer.getIconImage().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getIconImage().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getIconImage().getFunction().getStops()).size()); + } + }); } @Test @@ -633,19 +776,24 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-image"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - iconImage(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + iconImage(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getIconImage()); - assertNotNull(layer.getIconImage().getFunction()); - assertEquals(SourceFunction.class, layer.getIconImage().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconImage().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getIconImage().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getIconImage()); + assertNotNull(layer.getIconImage().getFunction()); + assertEquals(SourceFunction.class, layer.getIconImage().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconImage().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getIconImage().getFunction().getStops().getClass()); + } + }); } @Test @@ -653,26 +801,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-image"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconImage( - property( - "FeaturePropertyA", - interval( - stop(1, iconImage("undefined")) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconImage( + property( + "FeaturePropertyA", + interval( + stop(1, iconImage("undefined")) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getIconImage()); - assertNotNull(layer.getIconImage().getFunction()); - assertEquals(SourceFunction.class, layer.getIconImage().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconImage().getFunction()).getProperty()); - assertEquals(IntervalStops.class, layer.getIconImage().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getIconImage()); + assertNotNull(layer.getIconImage().getFunction()); + assertEquals(SourceFunction.class, layer.getIconImage().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconImage().getFunction()).getProperty()); + assertEquals(IntervalStops.class, layer.getIconImage().getFunction().getStops().getClass()); + } + }); } @Test @@ -680,11 +833,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-rotate"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconRotate(0.3f)); - assertEquals((Float) layer.getIconRotate().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(iconRotate(0.3f)); + assertEquals((Float) layer.getIconRotate().getValue(), (Float) 0.3f); + } + }); } @Test @@ -692,26 +850,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-rotate"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconRotate( - zoom( - exponential( - stop(2, iconRotate(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconRotate( + zoom( + exponential( + stop(2, iconRotate(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getIconRotate()); - assertNotNull(layer.getIconRotate().getFunction()); - assertEquals(CameraFunction.class, layer.getIconRotate().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getIconRotate().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getIconRotate().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getIconRotate().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getIconRotate()); + assertNotNull(layer.getIconRotate().getFunction()); + assertEquals(CameraFunction.class, layer.getIconRotate().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getIconRotate().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getIconRotate().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getIconRotate().getFunction().getStops()).size()); + } + }); } @Test @@ -719,19 +882,24 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-rotate"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - iconRotate(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + iconRotate(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getIconRotate()); - assertNotNull(layer.getIconRotate().getFunction()); - assertEquals(SourceFunction.class, layer.getIconRotate().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconRotate().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getIconRotate().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getIconRotate()); + assertNotNull(layer.getIconRotate().getFunction()); + assertEquals(SourceFunction.class, layer.getIconRotate().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconRotate().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getIconRotate().getFunction().getStops().getClass()); + } + }); } @Test @@ -739,26 +907,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-rotate"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconRotate( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, iconRotate(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconRotate( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, iconRotate(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getIconRotate()); - assertNotNull(layer.getIconRotate().getFunction()); - assertEquals(SourceFunction.class, layer.getIconRotate().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconRotate().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getIconRotate().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getIconRotate()); + assertNotNull(layer.getIconRotate().getFunction()); + assertEquals(SourceFunction.class, layer.getIconRotate().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconRotate().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getIconRotate().getFunction().getStops().getClass()); + } + }); } @Test @@ -766,29 +939,35 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-rotate"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconRotate( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, iconRotate(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconRotate( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, iconRotate(0.3f)) + ) + ).withDefaultValue(iconRotate(0.3f)) ) - ).withDefaultValue(iconRotate(0.3f)) - ) - ); + ); + + // Verify + assertNotNull(layer.getIconRotate()); + assertNotNull(layer.getIconRotate().getFunction()); + assertEquals(SourceFunction.class, layer.getIconRotate().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconRotate().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getIconRotate().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getIconRotate().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getIconRotate().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getIconRotate().getFunction()).getDefaultValue().getValue()); + } + }); - // Verify - assertNotNull(layer.getIconRotate()); - assertNotNull(layer.getIconRotate().getFunction()); - assertEquals(SourceFunction.class, layer.getIconRotate().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconRotate().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getIconRotate().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getIconRotate().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getIconRotate().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getIconRotate().getFunction()).getDefaultValue().getValue()); } @Test @@ -796,34 +975,39 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-rotate"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconRotate( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, iconRotate(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(iconRotate(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getIconRotate()); - assertNotNull(layer.getIconRotate().getFunction()); - assertEquals(CompositeFunction.class, layer.getIconRotate().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getIconRotate().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getIconRotate().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getIconRotate().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getIconRotate().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconRotate( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, iconRotate(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(iconRotate(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getIconRotate()); + assertNotNull(layer.getIconRotate().getFunction()); + assertEquals(CompositeFunction.class, layer.getIconRotate().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getIconRotate().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getIconRotate().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getIconRotate().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getIconRotate().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -831,11 +1015,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-padding"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconPadding(0.3f)); - assertEquals((Float) layer.getIconPadding().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(iconPadding(0.3f)); + assertEquals((Float) layer.getIconPadding().getValue(), (Float) 0.3f); + } + }); } @Test @@ -843,26 +1032,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-padding"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconPadding( - zoom( - exponential( - stop(2, iconPadding(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconPadding( + zoom( + exponential( + stop(2, iconPadding(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getIconPadding()); - assertNotNull(layer.getIconPadding().getFunction()); - assertEquals(CameraFunction.class, layer.getIconPadding().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getIconPadding().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getIconPadding().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getIconPadding().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getIconPadding()); + assertNotNull(layer.getIconPadding().getFunction()); + assertEquals(CameraFunction.class, layer.getIconPadding().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getIconPadding().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getIconPadding().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getIconPadding().getFunction().getStops()).size()); + } + }); } @Test @@ -870,11 +1064,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-keep-upright"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconKeepUpright(true)); - assertEquals((Boolean) layer.getIconKeepUpright().getValue(), (Boolean) true); + // Set and Get + layer.setProperties(iconKeepUpright(true)); + assertEquals((Boolean) layer.getIconKeepUpright().getValue(), (Boolean) true); + } + }); } @Test @@ -882,25 +1081,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-keep-upright"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconKeepUpright( - zoom( - interval( - stop(2, iconKeepUpright(true)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconKeepUpright( + zoom( + interval( + stop(2, iconKeepUpright(true)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getIconKeepUpright()); - assertNotNull(layer.getIconKeepUpright().getFunction()); - assertEquals(CameraFunction.class, layer.getIconKeepUpright().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getIconKeepUpright().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getIconKeepUpright().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getIconKeepUpright()); + assertNotNull(layer.getIconKeepUpright().getFunction()); + assertEquals(CameraFunction.class, layer.getIconKeepUpright().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getIconKeepUpright().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getIconKeepUpright().getFunction().getStops()).size()); + } + }); } @Test @@ -908,11 +1112,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-offset"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconOffset(new Float[]{0f,0f})); - assertEquals((Float[]) layer.getIconOffset().getValue(), (Float[]) new Float[]{0f,0f}); + // Set and Get + layer.setProperties(iconOffset(new Float[] {0f, 0f})); + assertEquals((Float[]) layer.getIconOffset().getValue(), (Float[]) new Float[] {0f, 0f}); + } + }); } @Test @@ -920,26 +1129,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-offset"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconOffset( - zoom( - exponential( - stop(2, iconOffset(new Float[]{0f,0f})) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconOffset( + zoom( + exponential( + stop(2, iconOffset(new Float[] {0f, 0f})) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getIconOffset()); - assertNotNull(layer.getIconOffset().getFunction()); - assertEquals(CameraFunction.class, layer.getIconOffset().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getIconOffset().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getIconOffset().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getIconOffset().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getIconOffset()); + assertNotNull(layer.getIconOffset().getFunction()); + assertEquals(CameraFunction.class, layer.getIconOffset().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getIconOffset().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getIconOffset().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getIconOffset().getFunction().getStops()).size()); + } + }); } @Test @@ -947,19 +1161,24 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-offset"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - iconOffset(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + iconOffset(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getIconOffset()); - assertNotNull(layer.getIconOffset().getFunction()); - assertEquals(SourceFunction.class, layer.getIconOffset().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconOffset().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getIconOffset().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getIconOffset()); + assertNotNull(layer.getIconOffset().getFunction()); + assertEquals(SourceFunction.class, layer.getIconOffset().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconOffset().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getIconOffset().getFunction().getStops().getClass()); + } + }); } @Test @@ -967,26 +1186,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-offset"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconOffset( - property( - "FeaturePropertyA", - interval( - stop(1, iconOffset(new Float[]{0f,0f})) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconOffset( + property( + "FeaturePropertyA", + interval( + stop(1, iconOffset(new Float[] {0f, 0f})) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getIconOffset()); - assertNotNull(layer.getIconOffset().getFunction()); - assertEquals(SourceFunction.class, layer.getIconOffset().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconOffset().getFunction()).getProperty()); - assertEquals(IntervalStops.class, layer.getIconOffset().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getIconOffset()); + assertNotNull(layer.getIconOffset().getFunction()); + assertEquals(SourceFunction.class, layer.getIconOffset().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconOffset().getFunction()).getProperty()); + assertEquals(IntervalStops.class, layer.getIconOffset().getFunction().getStops().getClass()); + } + }); } @Test @@ -994,11 +1218,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-pitch-alignment"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textPitchAlignment(TEXT_PITCH_ALIGNMENT_MAP)); - assertEquals((String) layer.getTextPitchAlignment().getValue(), (String) TEXT_PITCH_ALIGNMENT_MAP); + // Set and Get + layer.setProperties(textPitchAlignment(TEXT_PITCH_ALIGNMENT_MAP)); + assertEquals((String) layer.getTextPitchAlignment().getValue(), (String) TEXT_PITCH_ALIGNMENT_MAP); + } + }); } @Test @@ -1006,25 +1235,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-pitch-alignment"); - assertNotNull(layer); - - // Set - layer.setProperties( - textPitchAlignment( - zoom( - interval( - stop(2, textPitchAlignment(TEXT_PITCH_ALIGNMENT_MAP)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textPitchAlignment( + zoom( + interval( + stop(2, textPitchAlignment(TEXT_PITCH_ALIGNMENT_MAP)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getTextPitchAlignment()); - assertNotNull(layer.getTextPitchAlignment().getFunction()); - assertEquals(CameraFunction.class, layer.getTextPitchAlignment().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getTextPitchAlignment().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getTextPitchAlignment().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextPitchAlignment()); + assertNotNull(layer.getTextPitchAlignment().getFunction()); + assertEquals(CameraFunction.class, layer.getTextPitchAlignment().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getTextPitchAlignment().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getTextPitchAlignment().getFunction().getStops()).size()); + } + }); } @Test @@ -1032,11 +1266,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-rotation-alignment"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textRotationAlignment(TEXT_ROTATION_ALIGNMENT_MAP)); - assertEquals((String) layer.getTextRotationAlignment().getValue(), (String) TEXT_ROTATION_ALIGNMENT_MAP); + // Set and Get + layer.setProperties(textRotationAlignment(TEXT_ROTATION_ALIGNMENT_MAP)); + assertEquals((String) layer.getTextRotationAlignment().getValue(), (String) TEXT_ROTATION_ALIGNMENT_MAP); + } + }); } @Test @@ -1044,25 +1283,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-rotation-alignment"); - assertNotNull(layer); - - // Set - layer.setProperties( - textRotationAlignment( - zoom( - interval( - stop(2, textRotationAlignment(TEXT_ROTATION_ALIGNMENT_MAP)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textRotationAlignment( + zoom( + interval( + stop(2, textRotationAlignment(TEXT_ROTATION_ALIGNMENT_MAP)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getTextRotationAlignment()); - assertNotNull(layer.getTextRotationAlignment().getFunction()); - assertEquals(CameraFunction.class, layer.getTextRotationAlignment().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getTextRotationAlignment().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getTextRotationAlignment().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextRotationAlignment()); + assertNotNull(layer.getTextRotationAlignment().getFunction()); + assertEquals(CameraFunction.class, layer.getTextRotationAlignment().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getTextRotationAlignment().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getTextRotationAlignment().getFunction().getStops()).size()); + } + }); } @Test @@ -1070,11 +1314,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-field"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textField("")); - assertEquals((String) layer.getTextField().getValue(), (String) ""); + // Set and Get + layer.setProperties(textField("")); + assertEquals((String) layer.getTextField().getValue(), (String) ""); + } + }); } @Test @@ -1082,25 +1331,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-field"); - assertNotNull(layer); - - // Set - layer.setProperties( - textField( - zoom( - interval( - stop(2, textField("")) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textField( + zoom( + interval( + stop(2, textField("")) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getTextField()); - assertNotNull(layer.getTextField().getFunction()); - assertEquals(CameraFunction.class, layer.getTextField().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getTextField().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getTextField().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextField()); + assertNotNull(layer.getTextField().getFunction()); + assertEquals(CameraFunction.class, layer.getTextField().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getTextField().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getTextField().getFunction().getStops()).size()); + } + }); } @Test @@ -1108,19 +1362,24 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-field"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - textField(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + textField(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getTextField()); - assertNotNull(layer.getTextField().getFunction()); - assertEquals(SourceFunction.class, layer.getTextField().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextField().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getTextField().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextField()); + assertNotNull(layer.getTextField().getFunction()); + assertEquals(SourceFunction.class, layer.getTextField().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextField().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getTextField().getFunction().getStops().getClass()); + } + }); } @Test @@ -1128,26 +1387,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-field"); - assertNotNull(layer); - - // Set - layer.setProperties( - textField( - property( - "FeaturePropertyA", - interval( - stop(1, textField("")) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textField( + property( + "FeaturePropertyA", + interval( + stop(1, textField("")) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getTextField()); - assertNotNull(layer.getTextField().getFunction()); - assertEquals(SourceFunction.class, layer.getTextField().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextField().getFunction()).getProperty()); - assertEquals(IntervalStops.class, layer.getTextField().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextField()); + assertNotNull(layer.getTextField().getFunction()); + assertEquals(SourceFunction.class, layer.getTextField().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextField().getFunction()).getProperty()); + assertEquals(IntervalStops.class, layer.getTextField().getFunction().getStops().getClass()); + } + }); } @Test @@ -1155,11 +1419,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-font"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textFont(new String[]{"Open Sans Regular", "Arial Unicode MS Regular"})); - assertEquals((String[]) layer.getTextFont().getValue(), (String[]) new String[]{"Open Sans Regular", "Arial Unicode MS Regular"}); + // Set and Get + layer.setProperties(textFont(new String[]{"Open Sans Regular", "Arial Unicode MS Regular"})); + assertEquals((String[]) layer.getTextFont().getValue(), (String[]) new String[]{"Open Sans Regular", "Arial Unicode MS Regular"}); + } + }); } @Test @@ -1167,25 +1436,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-font"); - assertNotNull(layer); - - // Set - layer.setProperties( - textFont( - zoom( - interval( - stop(2, textFont(new String[]{"Open Sans Regular", "Arial Unicode MS Regular"})) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textFont( + zoom( + interval( + stop(2, textFont(new String[]{"Open Sans Regular", "Arial Unicode MS Regular"})) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getTextFont()); - assertNotNull(layer.getTextFont().getFunction()); - assertEquals(CameraFunction.class, layer.getTextFont().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getTextFont().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getTextFont().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextFont()); + assertNotNull(layer.getTextFont().getFunction()); + assertEquals(CameraFunction.class, layer.getTextFont().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getTextFont().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getTextFont().getFunction().getStops()).size()); + } + }); } @Test @@ -1193,11 +1467,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-size"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textSize(0.3f)); - assertEquals((Float) layer.getTextSize().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(textSize(0.3f)); + assertEquals((Float) layer.getTextSize().getValue(), (Float) 0.3f); + } + }); } @Test @@ -1205,26 +1484,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-size"); - assertNotNull(layer); - - // Set - layer.setProperties( - textSize( - zoom( - exponential( - stop(2, textSize(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textSize( + zoom( + exponential( + stop(2, textSize(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextSize()); - assertNotNull(layer.getTextSize().getFunction()); - assertEquals(CameraFunction.class, layer.getTextSize().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getTextSize().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getTextSize().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getTextSize().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextSize()); + assertNotNull(layer.getTextSize().getFunction()); + assertEquals(CameraFunction.class, layer.getTextSize().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getTextSize().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getTextSize().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getTextSize().getFunction().getStops()).size()); + } + }); } @Test @@ -1232,19 +1516,24 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-size"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - textSize(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + textSize(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getTextSize()); - assertNotNull(layer.getTextSize().getFunction()); - assertEquals(SourceFunction.class, layer.getTextSize().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextSize().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getTextSize().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextSize()); + assertNotNull(layer.getTextSize().getFunction()); + assertEquals(SourceFunction.class, layer.getTextSize().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextSize().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getTextSize().getFunction().getStops().getClass()); + } + }); } @Test @@ -1252,26 +1541,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-size"); - assertNotNull(layer); - - // Set - layer.setProperties( - textSize( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, textSize(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textSize( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, textSize(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextSize()); - assertNotNull(layer.getTextSize().getFunction()); - assertEquals(SourceFunction.class, layer.getTextSize().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextSize().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getTextSize().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextSize()); + assertNotNull(layer.getTextSize().getFunction()); + assertEquals(SourceFunction.class, layer.getTextSize().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextSize().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getTextSize().getFunction().getStops().getClass()); + } + }); } @Test @@ -1279,29 +1573,35 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-size"); - assertNotNull(layer); - - // Set - layer.setProperties( - textSize( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, textSize(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textSize( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, textSize(0.3f)) + ) + ).withDefaultValue(textSize(0.3f)) ) - ).withDefaultValue(textSize(0.3f)) - ) - ); + ); + + // Verify + assertNotNull(layer.getTextSize()); + assertNotNull(layer.getTextSize().getFunction()); + assertEquals(SourceFunction.class, layer.getTextSize().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextSize().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getTextSize().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getTextSize().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getTextSize().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getTextSize().getFunction()).getDefaultValue().getValue()); + } + }); - // Verify - assertNotNull(layer.getTextSize()); - assertNotNull(layer.getTextSize().getFunction()); - assertEquals(SourceFunction.class, layer.getTextSize().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextSize().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getTextSize().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getTextSize().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getTextSize().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getTextSize().getFunction()).getDefaultValue().getValue()); } @Test @@ -1309,34 +1609,39 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-size"); - assertNotNull(layer); - - // Set - layer.setProperties( - textSize( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, textSize(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(textSize(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getTextSize()); - assertNotNull(layer.getTextSize().getFunction()); - assertEquals(CompositeFunction.class, layer.getTextSize().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getTextSize().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getTextSize().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getTextSize().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getTextSize().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textSize( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, textSize(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(textSize(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getTextSize()); + assertNotNull(layer.getTextSize().getFunction()); + assertEquals(CompositeFunction.class, layer.getTextSize().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getTextSize().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getTextSize().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getTextSize().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getTextSize().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -1344,11 +1649,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-max-width"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textMaxWidth(0.3f)); - assertEquals((Float) layer.getTextMaxWidth().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(textMaxWidth(0.3f)); + assertEquals((Float) layer.getTextMaxWidth().getValue(), (Float) 0.3f); + } + }); } @Test @@ -1356,26 +1666,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-max-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - textMaxWidth( - zoom( - exponential( - stop(2, textMaxWidth(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textMaxWidth( + zoom( + exponential( + stop(2, textMaxWidth(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextMaxWidth()); - assertNotNull(layer.getTextMaxWidth().getFunction()); - assertEquals(CameraFunction.class, layer.getTextMaxWidth().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getTextMaxWidth().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getTextMaxWidth().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getTextMaxWidth().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextMaxWidth()); + assertNotNull(layer.getTextMaxWidth().getFunction()); + assertEquals(CameraFunction.class, layer.getTextMaxWidth().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getTextMaxWidth().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getTextMaxWidth().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getTextMaxWidth().getFunction().getStops()).size()); + } + }); } @Test @@ -1383,11 +1698,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-line-height"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textLineHeight(0.3f)); - assertEquals((Float) layer.getTextLineHeight().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(textLineHeight(0.3f)); + assertEquals((Float) layer.getTextLineHeight().getValue(), (Float) 0.3f); + } + }); } @Test @@ -1395,26 +1715,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-line-height"); - assertNotNull(layer); - - // Set - layer.setProperties( - textLineHeight( - zoom( - exponential( - stop(2, textLineHeight(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textLineHeight( + zoom( + exponential( + stop(2, textLineHeight(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextLineHeight()); - assertNotNull(layer.getTextLineHeight().getFunction()); - assertEquals(CameraFunction.class, layer.getTextLineHeight().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getTextLineHeight().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getTextLineHeight().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getTextLineHeight().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextLineHeight()); + assertNotNull(layer.getTextLineHeight().getFunction()); + assertEquals(CameraFunction.class, layer.getTextLineHeight().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getTextLineHeight().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getTextLineHeight().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getTextLineHeight().getFunction().getStops()).size()); + } + }); } @Test @@ -1422,11 +1747,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-letter-spacing"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textLetterSpacing(0.3f)); - assertEquals((Float) layer.getTextLetterSpacing().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(textLetterSpacing(0.3f)); + assertEquals((Float) layer.getTextLetterSpacing().getValue(), (Float) 0.3f); + } + }); } @Test @@ -1434,26 +1764,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-letter-spacing"); - assertNotNull(layer); - - // Set - layer.setProperties( - textLetterSpacing( - zoom( - exponential( - stop(2, textLetterSpacing(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textLetterSpacing( + zoom( + exponential( + stop(2, textLetterSpacing(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextLetterSpacing()); - assertNotNull(layer.getTextLetterSpacing().getFunction()); - assertEquals(CameraFunction.class, layer.getTextLetterSpacing().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getTextLetterSpacing().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getTextLetterSpacing().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getTextLetterSpacing().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextLetterSpacing()); + assertNotNull(layer.getTextLetterSpacing().getFunction()); + assertEquals(CameraFunction.class, layer.getTextLetterSpacing().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getTextLetterSpacing().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getTextLetterSpacing().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getTextLetterSpacing().getFunction().getStops()).size()); + } + }); } @Test @@ -1461,11 +1796,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-justify"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textJustify(TEXT_JUSTIFY_LEFT)); - assertEquals((String) layer.getTextJustify().getValue(), (String) TEXT_JUSTIFY_LEFT); + // Set and Get + layer.setProperties(textJustify(TEXT_JUSTIFY_LEFT)); + assertEquals((String) layer.getTextJustify().getValue(), (String) TEXT_JUSTIFY_LEFT); + } + }); } @Test @@ -1473,25 +1813,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-justify"); - assertNotNull(layer); - - // Set - layer.setProperties( - textJustify( - zoom( - interval( - stop(2, textJustify(TEXT_JUSTIFY_LEFT)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textJustify( + zoom( + interval( + stop(2, textJustify(TEXT_JUSTIFY_LEFT)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getTextJustify()); - assertNotNull(layer.getTextJustify().getFunction()); - assertEquals(CameraFunction.class, layer.getTextJustify().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getTextJustify().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getTextJustify().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextJustify()); + assertNotNull(layer.getTextJustify().getFunction()); + assertEquals(CameraFunction.class, layer.getTextJustify().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getTextJustify().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getTextJustify().getFunction().getStops()).size()); + } + }); } @Test @@ -1499,11 +1844,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-anchor"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textAnchor(TEXT_ANCHOR_CENTER)); - assertEquals((String) layer.getTextAnchor().getValue(), (String) TEXT_ANCHOR_CENTER); + // Set and Get + layer.setProperties(textAnchor(TEXT_ANCHOR_CENTER)); + assertEquals((String) layer.getTextAnchor().getValue(), (String) TEXT_ANCHOR_CENTER); + } + }); } @Test @@ -1511,25 +1861,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-anchor"); - assertNotNull(layer); - - // Set - layer.setProperties( - textAnchor( - zoom( - interval( - stop(2, textAnchor(TEXT_ANCHOR_CENTER)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textAnchor( + zoom( + interval( + stop(2, textAnchor(TEXT_ANCHOR_CENTER)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getTextAnchor()); - assertNotNull(layer.getTextAnchor().getFunction()); - assertEquals(CameraFunction.class, layer.getTextAnchor().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getTextAnchor().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getTextAnchor().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextAnchor()); + assertNotNull(layer.getTextAnchor().getFunction()); + assertEquals(CameraFunction.class, layer.getTextAnchor().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getTextAnchor().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getTextAnchor().getFunction().getStops()).size()); + } + }); } @Test @@ -1537,11 +1892,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-max-angle"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textMaxAngle(0.3f)); - assertEquals((Float) layer.getTextMaxAngle().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(textMaxAngle(0.3f)); + assertEquals((Float) layer.getTextMaxAngle().getValue(), (Float) 0.3f); + } + }); } @Test @@ -1549,26 +1909,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-max-angle"); - assertNotNull(layer); - - // Set - layer.setProperties( - textMaxAngle( - zoom( - exponential( - stop(2, textMaxAngle(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textMaxAngle( + zoom( + exponential( + stop(2, textMaxAngle(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextMaxAngle()); - assertNotNull(layer.getTextMaxAngle().getFunction()); - assertEquals(CameraFunction.class, layer.getTextMaxAngle().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getTextMaxAngle().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getTextMaxAngle().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getTextMaxAngle().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextMaxAngle()); + assertNotNull(layer.getTextMaxAngle().getFunction()); + assertEquals(CameraFunction.class, layer.getTextMaxAngle().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getTextMaxAngle().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getTextMaxAngle().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getTextMaxAngle().getFunction().getStops()).size()); + } + }); } @Test @@ -1576,11 +1941,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-rotate"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textRotate(0.3f)); - assertEquals((Float) layer.getTextRotate().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(textRotate(0.3f)); + assertEquals((Float) layer.getTextRotate().getValue(), (Float) 0.3f); + } + }); } @Test @@ -1588,26 +1958,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-rotate"); - assertNotNull(layer); - - // Set - layer.setProperties( - textRotate( - zoom( - exponential( - stop(2, textRotate(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textRotate( + zoom( + exponential( + stop(2, textRotate(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextRotate()); - assertNotNull(layer.getTextRotate().getFunction()); - assertEquals(CameraFunction.class, layer.getTextRotate().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getTextRotate().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getTextRotate().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getTextRotate().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextRotate()); + assertNotNull(layer.getTextRotate().getFunction()); + assertEquals(CameraFunction.class, layer.getTextRotate().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getTextRotate().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getTextRotate().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getTextRotate().getFunction().getStops()).size()); + } + }); } @Test @@ -1615,19 +1990,24 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-rotate"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - textRotate(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + textRotate(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getTextRotate()); - assertNotNull(layer.getTextRotate().getFunction()); - assertEquals(SourceFunction.class, layer.getTextRotate().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextRotate().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getTextRotate().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextRotate()); + assertNotNull(layer.getTextRotate().getFunction()); + assertEquals(SourceFunction.class, layer.getTextRotate().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextRotate().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getTextRotate().getFunction().getStops().getClass()); + } + }); } @Test @@ -1635,26 +2015,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-rotate"); - assertNotNull(layer); - - // Set - layer.setProperties( - textRotate( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, textRotate(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textRotate( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, textRotate(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextRotate()); - assertNotNull(layer.getTextRotate().getFunction()); - assertEquals(SourceFunction.class, layer.getTextRotate().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextRotate().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getTextRotate().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextRotate()); + assertNotNull(layer.getTextRotate().getFunction()); + assertEquals(SourceFunction.class, layer.getTextRotate().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextRotate().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getTextRotate().getFunction().getStops().getClass()); + } + }); } @Test @@ -1662,29 +2047,35 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-rotate"); - assertNotNull(layer); - - // Set - layer.setProperties( - textRotate( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, textRotate(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textRotate( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, textRotate(0.3f)) + ) + ).withDefaultValue(textRotate(0.3f)) ) - ).withDefaultValue(textRotate(0.3f)) - ) - ); + ); + + // Verify + assertNotNull(layer.getTextRotate()); + assertNotNull(layer.getTextRotate().getFunction()); + assertEquals(SourceFunction.class, layer.getTextRotate().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextRotate().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getTextRotate().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getTextRotate().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getTextRotate().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getTextRotate().getFunction()).getDefaultValue().getValue()); + } + }); - // Verify - assertNotNull(layer.getTextRotate()); - assertNotNull(layer.getTextRotate().getFunction()); - assertEquals(SourceFunction.class, layer.getTextRotate().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextRotate().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getTextRotate().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getTextRotate().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getTextRotate().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getTextRotate().getFunction()).getDefaultValue().getValue()); } @Test @@ -1692,34 +2083,39 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-rotate"); - assertNotNull(layer); - - // Set - layer.setProperties( - textRotate( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, textRotate(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(textRotate(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getTextRotate()); - assertNotNull(layer.getTextRotate().getFunction()); - assertEquals(CompositeFunction.class, layer.getTextRotate().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getTextRotate().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getTextRotate().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getTextRotate().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getTextRotate().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textRotate( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, textRotate(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(textRotate(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getTextRotate()); + assertNotNull(layer.getTextRotate().getFunction()); + assertEquals(CompositeFunction.class, layer.getTextRotate().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getTextRotate().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getTextRotate().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getTextRotate().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getTextRotate().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -1727,11 +2123,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-padding"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textPadding(0.3f)); - assertEquals((Float) layer.getTextPadding().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(textPadding(0.3f)); + assertEquals((Float) layer.getTextPadding().getValue(), (Float) 0.3f); + } + }); } @Test @@ -1739,26 +2140,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-padding"); - assertNotNull(layer); - - // Set - layer.setProperties( - textPadding( - zoom( - exponential( - stop(2, textPadding(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textPadding( + zoom( + exponential( + stop(2, textPadding(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextPadding()); - assertNotNull(layer.getTextPadding().getFunction()); - assertEquals(CameraFunction.class, layer.getTextPadding().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getTextPadding().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getTextPadding().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getTextPadding().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextPadding()); + assertNotNull(layer.getTextPadding().getFunction()); + assertEquals(CameraFunction.class, layer.getTextPadding().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getTextPadding().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getTextPadding().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getTextPadding().getFunction().getStops()).size()); + } + }); } @Test @@ -1766,11 +2172,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-keep-upright"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textKeepUpright(true)); - assertEquals((Boolean) layer.getTextKeepUpright().getValue(), (Boolean) true); + // Set and Get + layer.setProperties(textKeepUpright(true)); + assertEquals((Boolean) layer.getTextKeepUpright().getValue(), (Boolean) true); + } + }); } @Test @@ -1778,25 +2189,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-keep-upright"); - assertNotNull(layer); - - // Set - layer.setProperties( - textKeepUpright( - zoom( - interval( - stop(2, textKeepUpright(true)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textKeepUpright( + zoom( + interval( + stop(2, textKeepUpright(true)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getTextKeepUpright()); - assertNotNull(layer.getTextKeepUpright().getFunction()); - assertEquals(CameraFunction.class, layer.getTextKeepUpright().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getTextKeepUpright().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getTextKeepUpright().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextKeepUpright()); + assertNotNull(layer.getTextKeepUpright().getFunction()); + assertEquals(CameraFunction.class, layer.getTextKeepUpright().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getTextKeepUpright().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getTextKeepUpright().getFunction().getStops()).size()); + } + }); } @Test @@ -1804,11 +2220,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-transform"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textTransform(TEXT_TRANSFORM_NONE)); - assertEquals((String) layer.getTextTransform().getValue(), (String) TEXT_TRANSFORM_NONE); + // Set and Get + layer.setProperties(textTransform(TEXT_TRANSFORM_NONE)); + assertEquals((String) layer.getTextTransform().getValue(), (String) TEXT_TRANSFORM_NONE); + } + }); } @Test @@ -1816,25 +2237,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-transform"); - assertNotNull(layer); - - // Set - layer.setProperties( - textTransform( - zoom( - interval( - stop(2, textTransform(TEXT_TRANSFORM_NONE)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textTransform( + zoom( + interval( + stop(2, textTransform(TEXT_TRANSFORM_NONE)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getTextTransform()); - assertNotNull(layer.getTextTransform().getFunction()); - assertEquals(CameraFunction.class, layer.getTextTransform().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getTextTransform().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getTextTransform().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextTransform()); + assertNotNull(layer.getTextTransform().getFunction()); + assertEquals(CameraFunction.class, layer.getTextTransform().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getTextTransform().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getTextTransform().getFunction().getStops()).size()); + } + }); } @Test @@ -1842,19 +2268,24 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-transform"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - textTransform(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + textTransform(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getTextTransform()); - assertNotNull(layer.getTextTransform().getFunction()); - assertEquals(SourceFunction.class, layer.getTextTransform().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextTransform().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getTextTransform().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextTransform()); + assertNotNull(layer.getTextTransform().getFunction()); + assertEquals(SourceFunction.class, layer.getTextTransform().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextTransform().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getTextTransform().getFunction().getStops().getClass()); + } + }); } @Test @@ -1862,26 +2293,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-transform"); - assertNotNull(layer); - - // Set - layer.setProperties( - textTransform( - property( - "FeaturePropertyA", - interval( - stop(1, textTransform(TEXT_TRANSFORM_NONE)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textTransform( + property( + "FeaturePropertyA", + interval( + stop(1, textTransform(TEXT_TRANSFORM_NONE)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getTextTransform()); - assertNotNull(layer.getTextTransform().getFunction()); - assertEquals(SourceFunction.class, layer.getTextTransform().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextTransform().getFunction()).getProperty()); - assertEquals(IntervalStops.class, layer.getTextTransform().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextTransform()); + assertNotNull(layer.getTextTransform().getFunction()); + assertEquals(SourceFunction.class, layer.getTextTransform().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextTransform().getFunction()).getProperty()); + assertEquals(IntervalStops.class, layer.getTextTransform().getFunction().getStops().getClass()); + } + }); } @Test @@ -1889,11 +2325,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-offset"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textOffset(new Float[]{0f,0f})); - assertEquals((Float[]) layer.getTextOffset().getValue(), (Float[]) new Float[]{0f,0f}); + // Set and Get + layer.setProperties(textOffset(new Float[] {0f, 0f})); + assertEquals((Float[]) layer.getTextOffset().getValue(), (Float[]) new Float[] {0f, 0f}); + } + }); } @Test @@ -1901,26 +2342,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-offset"); - assertNotNull(layer); - - // Set - layer.setProperties( - textOffset( - zoom( - exponential( - stop(2, textOffset(new Float[]{0f,0f})) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textOffset( + zoom( + exponential( + stop(2, textOffset(new Float[] {0f, 0f})) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextOffset()); - assertNotNull(layer.getTextOffset().getFunction()); - assertEquals(CameraFunction.class, layer.getTextOffset().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getTextOffset().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getTextOffset().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getTextOffset().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextOffset()); + assertNotNull(layer.getTextOffset().getFunction()); + assertEquals(CameraFunction.class, layer.getTextOffset().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getTextOffset().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getTextOffset().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getTextOffset().getFunction().getStops()).size()); + } + }); } @Test @@ -1928,19 +2374,24 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-offset"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - textOffset(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + textOffset(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getTextOffset()); - assertNotNull(layer.getTextOffset().getFunction()); - assertEquals(SourceFunction.class, layer.getTextOffset().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextOffset().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getTextOffset().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextOffset()); + assertNotNull(layer.getTextOffset().getFunction()); + assertEquals(SourceFunction.class, layer.getTextOffset().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextOffset().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getTextOffset().getFunction().getStops().getClass()); + } + }); } @Test @@ -1948,26 +2399,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-offset"); - assertNotNull(layer); - - // Set - layer.setProperties( - textOffset( - property( - "FeaturePropertyA", - interval( - stop(1, textOffset(new Float[]{0f,0f})) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textOffset( + property( + "FeaturePropertyA", + interval( + stop(1, textOffset(new Float[] {0f, 0f})) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getTextOffset()); - assertNotNull(layer.getTextOffset().getFunction()); - assertEquals(SourceFunction.class, layer.getTextOffset().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextOffset().getFunction()).getProperty()); - assertEquals(IntervalStops.class, layer.getTextOffset().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextOffset()); + assertNotNull(layer.getTextOffset().getFunction()); + assertEquals(SourceFunction.class, layer.getTextOffset().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextOffset().getFunction()).getProperty()); + assertEquals(IntervalStops.class, layer.getTextOffset().getFunction().getStops().getClass()); + } + }); } @Test @@ -1975,11 +2431,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-allow-overlap"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textAllowOverlap(true)); - assertEquals((Boolean) layer.getTextAllowOverlap().getValue(), (Boolean) true); + // Set and Get + layer.setProperties(textAllowOverlap(true)); + assertEquals((Boolean) layer.getTextAllowOverlap().getValue(), (Boolean) true); + } + }); } @Test @@ -1987,25 +2448,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-allow-overlap"); - assertNotNull(layer); - - // Set - layer.setProperties( - textAllowOverlap( - zoom( - interval( - stop(2, textAllowOverlap(true)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textAllowOverlap( + zoom( + interval( + stop(2, textAllowOverlap(true)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getTextAllowOverlap()); - assertNotNull(layer.getTextAllowOverlap().getFunction()); - assertEquals(CameraFunction.class, layer.getTextAllowOverlap().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getTextAllowOverlap().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getTextAllowOverlap().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextAllowOverlap()); + assertNotNull(layer.getTextAllowOverlap().getFunction()); + assertEquals(CameraFunction.class, layer.getTextAllowOverlap().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getTextAllowOverlap().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getTextAllowOverlap().getFunction().getStops()).size()); + } + }); } @Test @@ -2013,11 +2479,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-ignore-placement"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textIgnorePlacement(true)); - assertEquals((Boolean) layer.getTextIgnorePlacement().getValue(), (Boolean) true); + // Set and Get + layer.setProperties(textIgnorePlacement(true)); + assertEquals((Boolean) layer.getTextIgnorePlacement().getValue(), (Boolean) true); + } + }); } @Test @@ -2025,25 +2496,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-ignore-placement"); - assertNotNull(layer); - - // Set - layer.setProperties( - textIgnorePlacement( - zoom( - interval( - stop(2, textIgnorePlacement(true)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textIgnorePlacement( + zoom( + interval( + stop(2, textIgnorePlacement(true)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getTextIgnorePlacement()); - assertNotNull(layer.getTextIgnorePlacement().getFunction()); - assertEquals(CameraFunction.class, layer.getTextIgnorePlacement().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getTextIgnorePlacement().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getTextIgnorePlacement().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextIgnorePlacement()); + assertNotNull(layer.getTextIgnorePlacement().getFunction()); + assertEquals(CameraFunction.class, layer.getTextIgnorePlacement().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getTextIgnorePlacement().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getTextIgnorePlacement().getFunction().getStops()).size()); + } + }); } @Test @@ -2051,11 +2527,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-optional"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textOptional(true)); - assertEquals((Boolean) layer.getTextOptional().getValue(), (Boolean) true); + // Set and Get + layer.setProperties(textOptional(true)); + assertEquals((Boolean) layer.getTextOptional().getValue(), (Boolean) true); + } + }); } @Test @@ -2063,25 +2544,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-optional"); - assertNotNull(layer); - - // Set - layer.setProperties( - textOptional( - zoom( - interval( - stop(2, textOptional(true)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textOptional( + zoom( + interval( + stop(2, textOptional(true)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getTextOptional()); - assertNotNull(layer.getTextOptional().getFunction()); - assertEquals(CameraFunction.class, layer.getTextOptional().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getTextOptional().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getTextOptional().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextOptional()); + assertNotNull(layer.getTextOptional().getFunction()); + assertEquals(CameraFunction.class, layer.getTextOptional().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getTextOptional().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getTextOptional().getFunction().getStops()).size()); + } + }); } @Test @@ -2089,12 +2575,17 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-opacityTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setIconOpacityTransition(options); - assertEquals(layer.getIconOpacityTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setIconOpacityTransition(options); + assertEquals(layer.getIconOpacityTransition(), options); + } + }); } @Test @@ -2102,11 +2593,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-opacity"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconOpacity(0.3f)); - assertEquals((Float) layer.getIconOpacity().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(iconOpacity(0.3f)); + assertEquals((Float) layer.getIconOpacity().getValue(), (Float) 0.3f); + } + }); } @Test @@ -2114,26 +2610,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconOpacity( - zoom( - exponential( - stop(2, iconOpacity(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconOpacity( + zoom( + exponential( + stop(2, iconOpacity(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getIconOpacity()); - assertNotNull(layer.getIconOpacity().getFunction()); - assertEquals(CameraFunction.class, layer.getIconOpacity().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getIconOpacity().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getIconOpacity().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getIconOpacity().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getIconOpacity()); + assertNotNull(layer.getIconOpacity().getFunction()); + assertEquals(CameraFunction.class, layer.getIconOpacity().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getIconOpacity().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getIconOpacity().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getIconOpacity().getFunction().getStops()).size()); + } + }); } @Test @@ -2141,19 +2642,24 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-opacity"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - iconOpacity(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + iconOpacity(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getIconOpacity()); - assertNotNull(layer.getIconOpacity().getFunction()); - assertEquals(SourceFunction.class, layer.getIconOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconOpacity().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getIconOpacity().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getIconOpacity()); + assertNotNull(layer.getIconOpacity().getFunction()); + assertEquals(SourceFunction.class, layer.getIconOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconOpacity().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getIconOpacity().getFunction().getStops().getClass()); + } + }); } @Test @@ -2161,26 +2667,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconOpacity( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, iconOpacity(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconOpacity( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, iconOpacity(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getIconOpacity()); - assertNotNull(layer.getIconOpacity().getFunction()); - assertEquals(SourceFunction.class, layer.getIconOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconOpacity().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getIconOpacity().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getIconOpacity()); + assertNotNull(layer.getIconOpacity().getFunction()); + assertEquals(SourceFunction.class, layer.getIconOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconOpacity().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getIconOpacity().getFunction().getStops().getClass()); + } + }); } @Test @@ -2188,29 +2699,35 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconOpacity( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, iconOpacity(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconOpacity( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, iconOpacity(0.3f)) + ) + ).withDefaultValue(iconOpacity(0.3f)) ) - ).withDefaultValue(iconOpacity(0.3f)) - ) - ); + ); + + // Verify + assertNotNull(layer.getIconOpacity()); + assertNotNull(layer.getIconOpacity().getFunction()); + assertEquals(SourceFunction.class, layer.getIconOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconOpacity().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getIconOpacity().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getIconOpacity().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getIconOpacity().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getIconOpacity().getFunction()).getDefaultValue().getValue()); + } + }); - // Verify - assertNotNull(layer.getIconOpacity()); - assertNotNull(layer.getIconOpacity().getFunction()); - assertEquals(SourceFunction.class, layer.getIconOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconOpacity().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getIconOpacity().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getIconOpacity().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getIconOpacity().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getIconOpacity().getFunction()).getDefaultValue().getValue()); } @Test @@ -2218,34 +2735,39 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconOpacity( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, iconOpacity(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(iconOpacity(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getIconOpacity()); - assertNotNull(layer.getIconOpacity().getFunction()); - assertEquals(CompositeFunction.class, layer.getIconOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getIconOpacity().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getIconOpacity().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getIconOpacity().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getIconOpacity().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconOpacity( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, iconOpacity(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(iconOpacity(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getIconOpacity()); + assertNotNull(layer.getIconOpacity().getFunction()); + assertEquals(CompositeFunction.class, layer.getIconOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getIconOpacity().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getIconOpacity().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getIconOpacity().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getIconOpacity().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -2253,12 +2775,17 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-colorTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setIconColorTransition(options); - assertEquals(layer.getIconColorTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setIconColorTransition(options); + assertEquals(layer.getIconColorTransition(), options); + } + }); } @Test @@ -2266,11 +2793,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconColor("rgba(0, 0, 0, 1)")); - assertEquals((String) layer.getIconColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + // Set and Get + layer.setProperties(iconColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getIconColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + }); } @Test @@ -2278,26 +2810,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconColor( - zoom( - exponential( - stop(2, iconColor("rgba(0, 0, 0, 1)")) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconColor( + zoom( + exponential( + stop(2, iconColor("rgba(0, 0, 0, 1)")) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getIconColor()); - assertNotNull(layer.getIconColor().getFunction()); - assertEquals(CameraFunction.class, layer.getIconColor().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getIconColor().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getIconColor().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getIconColor().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getIconColor()); + assertNotNull(layer.getIconColor().getFunction()); + assertEquals(CameraFunction.class, layer.getIconColor().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getIconColor().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getIconColor().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getIconColor().getFunction().getStops()).size()); + } + }); } @Test @@ -2305,19 +2842,24 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - iconColor(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + iconColor(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getIconColor()); - assertNotNull(layer.getIconColor().getFunction()); - assertEquals(SourceFunction.class, layer.getIconColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconColor().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getIconColor().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getIconColor()); + assertNotNull(layer.getIconColor().getFunction()); + assertEquals(SourceFunction.class, layer.getIconColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconColor().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getIconColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -2325,26 +2867,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconColor( - property( - "FeaturePropertyA", - exponential( - stop(Color.RED, iconColor(Color.RED)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconColor( + property( + "FeaturePropertyA", + exponential( + stop(Color.RED, iconColor(Color.RED)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getIconColor()); - assertNotNull(layer.getIconColor().getFunction()); - assertEquals(SourceFunction.class, layer.getIconColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconColor().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getIconColor().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getIconColor()); + assertNotNull(layer.getIconColor().getFunction()); + assertEquals(SourceFunction.class, layer.getIconColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconColor().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getIconColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -2352,29 +2899,35 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconColor( - property( - "FeaturePropertyA", - categorical( - stop("valueA", iconColor(Color.RED)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconColor( + property( + "FeaturePropertyA", + categorical( + stop("valueA", iconColor(Color.RED)) + ) + ).withDefaultValue(iconColor(Color.GREEN)) ) - ).withDefaultValue(iconColor(Color.GREEN)) - ) - ); + ); + + // Verify + assertNotNull(layer.getIconColor()); + assertNotNull(layer.getIconColor().getFunction()); + assertEquals(SourceFunction.class, layer.getIconColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconColor().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getIconColor().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getIconColor().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getIconColor().getFunction()).getDefaultValue().getValue()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getIconColor().getFunction()).getDefaultValue().getColorInt()); + } + }); - // Verify - assertNotNull(layer.getIconColor()); - assertNotNull(layer.getIconColor().getFunction()); - assertEquals(SourceFunction.class, layer.getIconColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconColor().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getIconColor().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getIconColor().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getIconColor().getFunction()).getDefaultValue().getValue()); - assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getIconColor().getFunction()).getDefaultValue().getColorInt()); } @Test @@ -2382,11 +2935,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconColor(Color.RED)); - assertEquals(layer.getIconColorAsInt(), Color.RED); + // Set and Get + layer.setProperties(iconColor(Color.RED)); + assertEquals(layer.getIconColorAsInt(), Color.RED); + } + }); } @Test @@ -2394,12 +2952,17 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-colorTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setIconHaloColorTransition(options); - assertEquals(layer.getIconHaloColorTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setIconHaloColorTransition(options); + assertEquals(layer.getIconHaloColorTransition(), options); + } + }); } @Test @@ -2407,11 +2970,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconHaloColor("rgba(0, 0, 0, 1)")); - assertEquals((String) layer.getIconHaloColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + // Set and Get + layer.setProperties(iconHaloColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getIconHaloColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + }); } @Test @@ -2419,26 +2987,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconHaloColor( - zoom( - exponential( - stop(2, iconHaloColor("rgba(0, 0, 0, 1)")) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconHaloColor( + zoom( + exponential( + stop(2, iconHaloColor("rgba(0, 0, 0, 1)")) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getIconHaloColor()); - assertNotNull(layer.getIconHaloColor().getFunction()); - assertEquals(CameraFunction.class, layer.getIconHaloColor().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getIconHaloColor().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getIconHaloColor().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getIconHaloColor().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getIconHaloColor()); + assertNotNull(layer.getIconHaloColor().getFunction()); + assertEquals(CameraFunction.class, layer.getIconHaloColor().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getIconHaloColor().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getIconHaloColor().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getIconHaloColor().getFunction().getStops()).size()); + } + }); } @Test @@ -2446,19 +3019,24 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - iconHaloColor(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + iconHaloColor(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getIconHaloColor()); - assertNotNull(layer.getIconHaloColor().getFunction()); - assertEquals(SourceFunction.class, layer.getIconHaloColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloColor().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getIconHaloColor().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getIconHaloColor()); + assertNotNull(layer.getIconHaloColor().getFunction()); + assertEquals(SourceFunction.class, layer.getIconHaloColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloColor().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getIconHaloColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -2466,26 +3044,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconHaloColor( - property( - "FeaturePropertyA", - exponential( - stop(Color.RED, iconHaloColor(Color.RED)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconHaloColor( + property( + "FeaturePropertyA", + exponential( + stop(Color.RED, iconHaloColor(Color.RED)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getIconHaloColor()); - assertNotNull(layer.getIconHaloColor().getFunction()); - assertEquals(SourceFunction.class, layer.getIconHaloColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloColor().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getIconHaloColor().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getIconHaloColor()); + assertNotNull(layer.getIconHaloColor().getFunction()); + assertEquals(SourceFunction.class, layer.getIconHaloColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloColor().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getIconHaloColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -2493,29 +3076,35 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconHaloColor( - property( - "FeaturePropertyA", - categorical( - stop("valueA", iconHaloColor(Color.RED)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconHaloColor( + property( + "FeaturePropertyA", + categorical( + stop("valueA", iconHaloColor(Color.RED)) + ) + ).withDefaultValue(iconHaloColor(Color.GREEN)) ) - ).withDefaultValue(iconHaloColor(Color.GREEN)) - ) - ); + ); + + // Verify + assertNotNull(layer.getIconHaloColor()); + assertNotNull(layer.getIconHaloColor().getFunction()); + assertEquals(SourceFunction.class, layer.getIconHaloColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloColor().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getIconHaloColor().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getIconHaloColor().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getIconHaloColor().getFunction()).getDefaultValue().getValue()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getIconHaloColor().getFunction()).getDefaultValue().getColorInt()); + } + }); - // Verify - assertNotNull(layer.getIconHaloColor()); - assertNotNull(layer.getIconHaloColor().getFunction()); - assertEquals(SourceFunction.class, layer.getIconHaloColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloColor().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getIconHaloColor().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getIconHaloColor().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getIconHaloColor().getFunction()).getDefaultValue().getValue()); - assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getIconHaloColor().getFunction()).getDefaultValue().getColorInt()); } @Test @@ -2523,11 +3112,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconHaloColor(Color.RED)); - assertEquals(layer.getIconHaloColorAsInt(), Color.RED); + // Set and Get + layer.setProperties(iconHaloColor(Color.RED)); + assertEquals(layer.getIconHaloColorAsInt(), Color.RED); + } + }); } @Test @@ -2535,12 +3129,17 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-widthTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setIconHaloWidthTransition(options); - assertEquals(layer.getIconHaloWidthTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setIconHaloWidthTransition(options); + assertEquals(layer.getIconHaloWidthTransition(), options); + } + }); } @Test @@ -2548,11 +3147,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-width"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconHaloWidth(0.3f)); - assertEquals((Float) layer.getIconHaloWidth().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(iconHaloWidth(0.3f)); + assertEquals((Float) layer.getIconHaloWidth().getValue(), (Float) 0.3f); + } + }); } @Test @@ -2560,26 +3164,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconHaloWidth( - zoom( - exponential( - stop(2, iconHaloWidth(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconHaloWidth( + zoom( + exponential( + stop(2, iconHaloWidth(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getIconHaloWidth()); - assertNotNull(layer.getIconHaloWidth().getFunction()); - assertEquals(CameraFunction.class, layer.getIconHaloWidth().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getIconHaloWidth().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getIconHaloWidth().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getIconHaloWidth().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getIconHaloWidth()); + assertNotNull(layer.getIconHaloWidth().getFunction()); + assertEquals(CameraFunction.class, layer.getIconHaloWidth().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getIconHaloWidth().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getIconHaloWidth().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getIconHaloWidth().getFunction().getStops()).size()); + } + }); } @Test @@ -2587,19 +3196,24 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-width"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - iconHaloWidth(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + iconHaloWidth(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getIconHaloWidth()); - assertNotNull(layer.getIconHaloWidth().getFunction()); - assertEquals(SourceFunction.class, layer.getIconHaloWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloWidth().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getIconHaloWidth().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getIconHaloWidth()); + assertNotNull(layer.getIconHaloWidth().getFunction()); + assertEquals(SourceFunction.class, layer.getIconHaloWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloWidth().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getIconHaloWidth().getFunction().getStops().getClass()); + } + }); } @Test @@ -2607,26 +3221,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconHaloWidth( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, iconHaloWidth(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconHaloWidth( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, iconHaloWidth(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getIconHaloWidth()); - assertNotNull(layer.getIconHaloWidth().getFunction()); - assertEquals(SourceFunction.class, layer.getIconHaloWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloWidth().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getIconHaloWidth().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getIconHaloWidth()); + assertNotNull(layer.getIconHaloWidth().getFunction()); + assertEquals(SourceFunction.class, layer.getIconHaloWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloWidth().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getIconHaloWidth().getFunction().getStops().getClass()); + } + }); } @Test @@ -2634,29 +3253,35 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconHaloWidth( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, iconHaloWidth(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconHaloWidth( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, iconHaloWidth(0.3f)) + ) + ).withDefaultValue(iconHaloWidth(0.3f)) ) - ).withDefaultValue(iconHaloWidth(0.3f)) - ) - ); + ); + + // Verify + assertNotNull(layer.getIconHaloWidth()); + assertNotNull(layer.getIconHaloWidth().getFunction()); + assertEquals(SourceFunction.class, layer.getIconHaloWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloWidth().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getIconHaloWidth().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getIconHaloWidth().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getIconHaloWidth().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getIconHaloWidth().getFunction()).getDefaultValue().getValue()); + } + }); - // Verify - assertNotNull(layer.getIconHaloWidth()); - assertNotNull(layer.getIconHaloWidth().getFunction()); - assertEquals(SourceFunction.class, layer.getIconHaloWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloWidth().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getIconHaloWidth().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getIconHaloWidth().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getIconHaloWidth().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getIconHaloWidth().getFunction()).getDefaultValue().getValue()); } @Test @@ -2664,34 +3289,39 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconHaloWidth( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, iconHaloWidth(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(iconHaloWidth(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getIconHaloWidth()); - assertNotNull(layer.getIconHaloWidth().getFunction()); - assertEquals(CompositeFunction.class, layer.getIconHaloWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getIconHaloWidth().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getIconHaloWidth().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getIconHaloWidth().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getIconHaloWidth().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconHaloWidth( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, iconHaloWidth(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(iconHaloWidth(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getIconHaloWidth()); + assertNotNull(layer.getIconHaloWidth().getFunction()); + assertEquals(CompositeFunction.class, layer.getIconHaloWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getIconHaloWidth().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getIconHaloWidth().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getIconHaloWidth().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getIconHaloWidth().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -2699,12 +3329,17 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-blurTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setIconHaloBlurTransition(options); - assertEquals(layer.getIconHaloBlurTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setIconHaloBlurTransition(options); + assertEquals(layer.getIconHaloBlurTransition(), options); + } + }); } @Test @@ -2712,11 +3347,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-blur"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconHaloBlur(0.3f)); - assertEquals((Float) layer.getIconHaloBlur().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(iconHaloBlur(0.3f)); + assertEquals((Float) layer.getIconHaloBlur().getValue(), (Float) 0.3f); + } + }); } @Test @@ -2724,26 +3364,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-blur"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconHaloBlur( - zoom( - exponential( - stop(2, iconHaloBlur(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconHaloBlur( + zoom( + exponential( + stop(2, iconHaloBlur(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getIconHaloBlur()); - assertNotNull(layer.getIconHaloBlur().getFunction()); - assertEquals(CameraFunction.class, layer.getIconHaloBlur().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getIconHaloBlur().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getIconHaloBlur().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getIconHaloBlur().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getIconHaloBlur()); + assertNotNull(layer.getIconHaloBlur().getFunction()); + assertEquals(CameraFunction.class, layer.getIconHaloBlur().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getIconHaloBlur().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getIconHaloBlur().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getIconHaloBlur().getFunction().getStops()).size()); + } + }); } @Test @@ -2751,19 +3396,24 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-blur"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - iconHaloBlur(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + iconHaloBlur(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getIconHaloBlur()); - assertNotNull(layer.getIconHaloBlur().getFunction()); - assertEquals(SourceFunction.class, layer.getIconHaloBlur().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloBlur().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getIconHaloBlur().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getIconHaloBlur()); + assertNotNull(layer.getIconHaloBlur().getFunction()); + assertEquals(SourceFunction.class, layer.getIconHaloBlur().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloBlur().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getIconHaloBlur().getFunction().getStops().getClass()); + } + }); } @Test @@ -2771,26 +3421,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-blur"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconHaloBlur( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, iconHaloBlur(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconHaloBlur( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, iconHaloBlur(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getIconHaloBlur()); - assertNotNull(layer.getIconHaloBlur().getFunction()); - assertEquals(SourceFunction.class, layer.getIconHaloBlur().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloBlur().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getIconHaloBlur().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getIconHaloBlur()); + assertNotNull(layer.getIconHaloBlur().getFunction()); + assertEquals(SourceFunction.class, layer.getIconHaloBlur().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloBlur().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getIconHaloBlur().getFunction().getStops().getClass()); + } + }); } @Test @@ -2798,29 +3453,35 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-blur"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconHaloBlur( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, iconHaloBlur(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconHaloBlur( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, iconHaloBlur(0.3f)) + ) + ).withDefaultValue(iconHaloBlur(0.3f)) ) - ).withDefaultValue(iconHaloBlur(0.3f)) - ) - ); + ); + + // Verify + assertNotNull(layer.getIconHaloBlur()); + assertNotNull(layer.getIconHaloBlur().getFunction()); + assertEquals(SourceFunction.class, layer.getIconHaloBlur().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloBlur().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getIconHaloBlur().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getIconHaloBlur().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getIconHaloBlur().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getIconHaloBlur().getFunction()).getDefaultValue().getValue()); + } + }); - // Verify - assertNotNull(layer.getIconHaloBlur()); - assertNotNull(layer.getIconHaloBlur().getFunction()); - assertEquals(SourceFunction.class, layer.getIconHaloBlur().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloBlur().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getIconHaloBlur().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getIconHaloBlur().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getIconHaloBlur().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getIconHaloBlur().getFunction()).getDefaultValue().getValue()); } @Test @@ -2828,34 +3489,39 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-halo-blur"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconHaloBlur( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, iconHaloBlur(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(iconHaloBlur(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getIconHaloBlur()); - assertNotNull(layer.getIconHaloBlur().getFunction()); - assertEquals(CompositeFunction.class, layer.getIconHaloBlur().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getIconHaloBlur().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getIconHaloBlur().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getIconHaloBlur().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getIconHaloBlur().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconHaloBlur( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, iconHaloBlur(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(iconHaloBlur(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getIconHaloBlur()); + assertNotNull(layer.getIconHaloBlur().getFunction()); + assertEquals(CompositeFunction.class, layer.getIconHaloBlur().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getIconHaloBlur().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getIconHaloBlur().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getIconHaloBlur().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getIconHaloBlur().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -2863,12 +3529,17 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-translateTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setIconTranslateTransition(options); - assertEquals(layer.getIconTranslateTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setIconTranslateTransition(options); + assertEquals(layer.getIconTranslateTransition(), options); + } + }); } @Test @@ -2876,11 +3547,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-translate"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconTranslate(new Float[]{0f,0f})); - assertEquals((Float[]) layer.getIconTranslate().getValue(), (Float[]) new Float[]{0f,0f}); + // Set and Get + layer.setProperties(iconTranslate(new Float[] {0f, 0f})); + assertEquals((Float[]) layer.getIconTranslate().getValue(), (Float[]) new Float[] {0f, 0f}); + } + }); } @Test @@ -2888,26 +3564,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-translate"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconTranslate( - zoom( - exponential( - stop(2, iconTranslate(new Float[]{0f,0f})) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconTranslate( + zoom( + exponential( + stop(2, iconTranslate(new Float[] {0f, 0f})) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getIconTranslate()); - assertNotNull(layer.getIconTranslate().getFunction()); - assertEquals(CameraFunction.class, layer.getIconTranslate().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getIconTranslate().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getIconTranslate().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getIconTranslate().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getIconTranslate()); + assertNotNull(layer.getIconTranslate().getFunction()); + assertEquals(CameraFunction.class, layer.getIconTranslate().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getIconTranslate().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getIconTranslate().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getIconTranslate().getFunction().getStops()).size()); + } + }); } @Test @@ -2915,11 +3596,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-translate-anchor"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(iconTranslateAnchor(ICON_TRANSLATE_ANCHOR_MAP)); - assertEquals((String) layer.getIconTranslateAnchor().getValue(), (String) ICON_TRANSLATE_ANCHOR_MAP); + // Set and Get + layer.setProperties(iconTranslateAnchor(ICON_TRANSLATE_ANCHOR_MAP)); + assertEquals((String) layer.getIconTranslateAnchor().getValue(), (String) ICON_TRANSLATE_ANCHOR_MAP); + } + }); } @Test @@ -2927,25 +3613,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("icon-translate-anchor"); - assertNotNull(layer); - - // Set - layer.setProperties( - iconTranslateAnchor( - zoom( - interval( - stop(2, iconTranslateAnchor(ICON_TRANSLATE_ANCHOR_MAP)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconTranslateAnchor( + zoom( + interval( + stop(2, iconTranslateAnchor(ICON_TRANSLATE_ANCHOR_MAP)) + ) + ) ) - ) - ) - ); + ); - // Verify - assertNotNull(layer.getIconTranslateAnchor()); - assertNotNull(layer.getIconTranslateAnchor().getFunction()); - assertEquals(CameraFunction.class, layer.getIconTranslateAnchor().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getIconTranslateAnchor().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getIconTranslateAnchor().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getIconTranslateAnchor()); + assertNotNull(layer.getIconTranslateAnchor().getFunction()); + assertEquals(CameraFunction.class, layer.getIconTranslateAnchor().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getIconTranslateAnchor().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getIconTranslateAnchor().getFunction().getStops()).size()); + } + }); } @Test @@ -2953,12 +3644,17 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-opacityTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setTextOpacityTransition(options); - assertEquals(layer.getTextOpacityTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setTextOpacityTransition(options); + assertEquals(layer.getTextOpacityTransition(), options); + } + }); } @Test @@ -2966,11 +3662,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-opacity"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textOpacity(0.3f)); - assertEquals((Float) layer.getTextOpacity().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(textOpacity(0.3f)); + assertEquals((Float) layer.getTextOpacity().getValue(), (Float) 0.3f); + } + }); } @Test @@ -2978,26 +3679,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - textOpacity( - zoom( - exponential( - stop(2, textOpacity(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textOpacity( + zoom( + exponential( + stop(2, textOpacity(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextOpacity()); - assertNotNull(layer.getTextOpacity().getFunction()); - assertEquals(CameraFunction.class, layer.getTextOpacity().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getTextOpacity().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getTextOpacity().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getTextOpacity().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextOpacity()); + assertNotNull(layer.getTextOpacity().getFunction()); + assertEquals(CameraFunction.class, layer.getTextOpacity().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getTextOpacity().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getTextOpacity().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getTextOpacity().getFunction().getStops()).size()); + } + }); } @Test @@ -3005,19 +3711,24 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-opacity"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - textOpacity(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + textOpacity(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getTextOpacity()); - assertNotNull(layer.getTextOpacity().getFunction()); - assertEquals(SourceFunction.class, layer.getTextOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextOpacity().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getTextOpacity().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextOpacity()); + assertNotNull(layer.getTextOpacity().getFunction()); + assertEquals(SourceFunction.class, layer.getTextOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextOpacity().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getTextOpacity().getFunction().getStops().getClass()); + } + }); } @Test @@ -3025,26 +3736,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - textOpacity( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, textOpacity(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textOpacity( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, textOpacity(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextOpacity()); - assertNotNull(layer.getTextOpacity().getFunction()); - assertEquals(SourceFunction.class, layer.getTextOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextOpacity().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getTextOpacity().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextOpacity()); + assertNotNull(layer.getTextOpacity().getFunction()); + assertEquals(SourceFunction.class, layer.getTextOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextOpacity().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getTextOpacity().getFunction().getStops().getClass()); + } + }); } @Test @@ -3052,29 +3768,35 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - textOpacity( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, textOpacity(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textOpacity( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, textOpacity(0.3f)) + ) + ).withDefaultValue(textOpacity(0.3f)) ) - ).withDefaultValue(textOpacity(0.3f)) - ) - ); + ); + + // Verify + assertNotNull(layer.getTextOpacity()); + assertNotNull(layer.getTextOpacity().getFunction()); + assertEquals(SourceFunction.class, layer.getTextOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextOpacity().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getTextOpacity().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getTextOpacity().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getTextOpacity().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getTextOpacity().getFunction()).getDefaultValue().getValue()); + } + }); - // Verify - assertNotNull(layer.getTextOpacity()); - assertNotNull(layer.getTextOpacity().getFunction()); - assertEquals(SourceFunction.class, layer.getTextOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextOpacity().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getTextOpacity().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getTextOpacity().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getTextOpacity().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getTextOpacity().getFunction()).getDefaultValue().getValue()); } @Test @@ -3082,34 +3804,39 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-opacity"); - assertNotNull(layer); - - // Set - layer.setProperties( - textOpacity( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, textOpacity(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(textOpacity(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getTextOpacity()); - assertNotNull(layer.getTextOpacity().getFunction()); - assertEquals(CompositeFunction.class, layer.getTextOpacity().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getTextOpacity().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getTextOpacity().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getTextOpacity().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getTextOpacity().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textOpacity( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, textOpacity(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(textOpacity(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getTextOpacity()); + assertNotNull(layer.getTextOpacity().getFunction()); + assertEquals(CompositeFunction.class, layer.getTextOpacity().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getTextOpacity().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getTextOpacity().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getTextOpacity().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getTextOpacity().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -3117,12 +3844,17 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-colorTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setTextColorTransition(options); - assertEquals(layer.getTextColorTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setTextColorTransition(options); + assertEquals(layer.getTextColorTransition(), options); + } + }); } @Test @@ -3130,11 +3862,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textColor("rgba(0, 0, 0, 1)")); - assertEquals((String) layer.getTextColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + // Set and Get + layer.setProperties(textColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getTextColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + }); } @Test @@ -3142,26 +3879,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - textColor( - zoom( - exponential( - stop(2, textColor("rgba(0, 0, 0, 1)")) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textColor( + zoom( + exponential( + stop(2, textColor("rgba(0, 0, 0, 1)")) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextColor()); - assertNotNull(layer.getTextColor().getFunction()); - assertEquals(CameraFunction.class, layer.getTextColor().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getTextColor().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getTextColor().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getTextColor().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextColor()); + assertNotNull(layer.getTextColor().getFunction()); + assertEquals(CameraFunction.class, layer.getTextColor().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getTextColor().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getTextColor().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getTextColor().getFunction().getStops()).size()); + } + }); } @Test @@ -3169,19 +3911,24 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - textColor(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + textColor(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getTextColor()); - assertNotNull(layer.getTextColor().getFunction()); - assertEquals(SourceFunction.class, layer.getTextColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextColor().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getTextColor().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextColor()); + assertNotNull(layer.getTextColor().getFunction()); + assertEquals(SourceFunction.class, layer.getTextColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextColor().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getTextColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -3189,26 +3936,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - textColor( - property( - "FeaturePropertyA", - exponential( - stop(Color.RED, textColor(Color.RED)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textColor( + property( + "FeaturePropertyA", + exponential( + stop(Color.RED, textColor(Color.RED)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextColor()); - assertNotNull(layer.getTextColor().getFunction()); - assertEquals(SourceFunction.class, layer.getTextColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextColor().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getTextColor().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextColor()); + assertNotNull(layer.getTextColor().getFunction()); + assertEquals(SourceFunction.class, layer.getTextColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextColor().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getTextColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -3216,29 +3968,35 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - textColor( - property( - "FeaturePropertyA", - categorical( - stop("valueA", textColor(Color.RED)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textColor( + property( + "FeaturePropertyA", + categorical( + stop("valueA", textColor(Color.RED)) + ) + ).withDefaultValue(textColor(Color.GREEN)) ) - ).withDefaultValue(textColor(Color.GREEN)) - ) - ); + ); + + // Verify + assertNotNull(layer.getTextColor()); + assertNotNull(layer.getTextColor().getFunction()); + assertEquals(SourceFunction.class, layer.getTextColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextColor().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getTextColor().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getTextColor().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getTextColor().getFunction()).getDefaultValue().getValue()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getTextColor().getFunction()).getDefaultValue().getColorInt()); + } + }); - // Verify - assertNotNull(layer.getTextColor()); - assertNotNull(layer.getTextColor().getFunction()); - assertEquals(SourceFunction.class, layer.getTextColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextColor().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getTextColor().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getTextColor().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getTextColor().getFunction()).getDefaultValue().getValue()); - assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getTextColor().getFunction()).getDefaultValue().getColorInt()); } @Test @@ -3246,11 +4004,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textColor(Color.RED)); - assertEquals(layer.getTextColorAsInt(), Color.RED); + // Set and Get + layer.setProperties(textColor(Color.RED)); + assertEquals(layer.getTextColorAsInt(), Color.RED); + } + }); } @Test @@ -3258,12 +4021,17 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-colorTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setTextHaloColorTransition(options); - assertEquals(layer.getTextHaloColorTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setTextHaloColorTransition(options); + assertEquals(layer.getTextHaloColorTransition(), options); + } + }); } @Test @@ -3271,11 +4039,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textHaloColor("rgba(0, 0, 0, 1)")); - assertEquals((String) layer.getTextHaloColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + // Set and Get + layer.setProperties(textHaloColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getTextHaloColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + }); } @Test @@ -3283,26 +4056,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - textHaloColor( - zoom( - exponential( - stop(2, textHaloColor("rgba(0, 0, 0, 1)")) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textHaloColor( + zoom( + exponential( + stop(2, textHaloColor("rgba(0, 0, 0, 1)")) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextHaloColor()); - assertNotNull(layer.getTextHaloColor().getFunction()); - assertEquals(CameraFunction.class, layer.getTextHaloColor().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getTextHaloColor().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getTextHaloColor().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getTextHaloColor().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextHaloColor()); + assertNotNull(layer.getTextHaloColor().getFunction()); + assertEquals(CameraFunction.class, layer.getTextHaloColor().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getTextHaloColor().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getTextHaloColor().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getTextHaloColor().getFunction().getStops()).size()); + } + }); } @Test @@ -3310,19 +4088,24 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - textHaloColor(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + textHaloColor(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getTextHaloColor()); - assertNotNull(layer.getTextHaloColor().getFunction()); - assertEquals(SourceFunction.class, layer.getTextHaloColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloColor().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getTextHaloColor().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextHaloColor()); + assertNotNull(layer.getTextHaloColor().getFunction()); + assertEquals(SourceFunction.class, layer.getTextHaloColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloColor().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getTextHaloColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -3330,26 +4113,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - textHaloColor( - property( - "FeaturePropertyA", - exponential( - stop(Color.RED, textHaloColor(Color.RED)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textHaloColor( + property( + "FeaturePropertyA", + exponential( + stop(Color.RED, textHaloColor(Color.RED)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextHaloColor()); - assertNotNull(layer.getTextHaloColor().getFunction()); - assertEquals(SourceFunction.class, layer.getTextHaloColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloColor().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getTextHaloColor().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextHaloColor()); + assertNotNull(layer.getTextHaloColor().getFunction()); + assertEquals(SourceFunction.class, layer.getTextHaloColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloColor().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getTextHaloColor().getFunction().getStops().getClass()); + } + }); } @Test @@ -3357,29 +4145,35 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-color"); - assertNotNull(layer); - - // Set - layer.setProperties( - textHaloColor( - property( - "FeaturePropertyA", - categorical( - stop("valueA", textHaloColor(Color.RED)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textHaloColor( + property( + "FeaturePropertyA", + categorical( + stop("valueA", textHaloColor(Color.RED)) + ) + ).withDefaultValue(textHaloColor(Color.GREEN)) ) - ).withDefaultValue(textHaloColor(Color.GREEN)) - ) - ); + ); + + // Verify + assertNotNull(layer.getTextHaloColor()); + assertNotNull(layer.getTextHaloColor().getFunction()); + assertEquals(SourceFunction.class, layer.getTextHaloColor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloColor().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getTextHaloColor().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getTextHaloColor().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getTextHaloColor().getFunction()).getDefaultValue().getValue()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getTextHaloColor().getFunction()).getDefaultValue().getColorInt()); + } + }); - // Verify - assertNotNull(layer.getTextHaloColor()); - assertNotNull(layer.getTextHaloColor().getFunction()); - assertEquals(SourceFunction.class, layer.getTextHaloColor().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloColor().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getTextHaloColor().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getTextHaloColor().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getTextHaloColor().getFunction()).getDefaultValue().getValue()); - assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getTextHaloColor().getFunction()).getDefaultValue().getColorInt()); } @Test @@ -3387,11 +4181,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-color"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textHaloColor(Color.RED)); - assertEquals(layer.getTextHaloColorAsInt(), Color.RED); + // Set and Get + layer.setProperties(textHaloColor(Color.RED)); + assertEquals(layer.getTextHaloColorAsInt(), Color.RED); + } + }); } @Test @@ -3399,12 +4198,17 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-widthTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setTextHaloWidthTransition(options); - assertEquals(layer.getTextHaloWidthTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setTextHaloWidthTransition(options); + assertEquals(layer.getTextHaloWidthTransition(), options); + } + }); } @Test @@ -3412,11 +4216,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-width"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textHaloWidth(0.3f)); - assertEquals((Float) layer.getTextHaloWidth().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(textHaloWidth(0.3f)); + assertEquals((Float) layer.getTextHaloWidth().getValue(), (Float) 0.3f); + } + }); } @Test @@ -3424,26 +4233,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - textHaloWidth( - zoom( - exponential( - stop(2, textHaloWidth(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textHaloWidth( + zoom( + exponential( + stop(2, textHaloWidth(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextHaloWidth()); - assertNotNull(layer.getTextHaloWidth().getFunction()); - assertEquals(CameraFunction.class, layer.getTextHaloWidth().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getTextHaloWidth().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getTextHaloWidth().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getTextHaloWidth().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextHaloWidth()); + assertNotNull(layer.getTextHaloWidth().getFunction()); + assertEquals(CameraFunction.class, layer.getTextHaloWidth().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getTextHaloWidth().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getTextHaloWidth().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getTextHaloWidth().getFunction().getStops()).size()); + } + }); } @Test @@ -3451,19 +4265,24 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-width"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - textHaloWidth(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + textHaloWidth(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getTextHaloWidth()); - assertNotNull(layer.getTextHaloWidth().getFunction()); - assertEquals(SourceFunction.class, layer.getTextHaloWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloWidth().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getTextHaloWidth().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextHaloWidth()); + assertNotNull(layer.getTextHaloWidth().getFunction()); + assertEquals(SourceFunction.class, layer.getTextHaloWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloWidth().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getTextHaloWidth().getFunction().getStops().getClass()); + } + }); } @Test @@ -3471,26 +4290,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - textHaloWidth( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, textHaloWidth(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textHaloWidth( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, textHaloWidth(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextHaloWidth()); - assertNotNull(layer.getTextHaloWidth().getFunction()); - assertEquals(SourceFunction.class, layer.getTextHaloWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloWidth().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getTextHaloWidth().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextHaloWidth()); + assertNotNull(layer.getTextHaloWidth().getFunction()); + assertEquals(SourceFunction.class, layer.getTextHaloWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloWidth().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getTextHaloWidth().getFunction().getStops().getClass()); + } + }); } @Test @@ -3498,29 +4322,35 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - textHaloWidth( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, textHaloWidth(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textHaloWidth( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, textHaloWidth(0.3f)) + ) + ).withDefaultValue(textHaloWidth(0.3f)) ) - ).withDefaultValue(textHaloWidth(0.3f)) - ) - ); + ); + + // Verify + assertNotNull(layer.getTextHaloWidth()); + assertNotNull(layer.getTextHaloWidth().getFunction()); + assertEquals(SourceFunction.class, layer.getTextHaloWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloWidth().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getTextHaloWidth().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getTextHaloWidth().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getTextHaloWidth().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getTextHaloWidth().getFunction()).getDefaultValue().getValue()); + } + }); - // Verify - assertNotNull(layer.getTextHaloWidth()); - assertNotNull(layer.getTextHaloWidth().getFunction()); - assertEquals(SourceFunction.class, layer.getTextHaloWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloWidth().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getTextHaloWidth().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getTextHaloWidth().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getTextHaloWidth().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getTextHaloWidth().getFunction()).getDefaultValue().getValue()); } @Test @@ -3528,34 +4358,39 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - textHaloWidth( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, textHaloWidth(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(textHaloWidth(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getTextHaloWidth()); - assertNotNull(layer.getTextHaloWidth().getFunction()); - assertEquals(CompositeFunction.class, layer.getTextHaloWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getTextHaloWidth().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getTextHaloWidth().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getTextHaloWidth().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getTextHaloWidth().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textHaloWidth( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, textHaloWidth(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(textHaloWidth(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getTextHaloWidth()); + assertNotNull(layer.getTextHaloWidth().getFunction()); + assertEquals(CompositeFunction.class, layer.getTextHaloWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getTextHaloWidth().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getTextHaloWidth().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getTextHaloWidth().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getTextHaloWidth().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -3563,12 +4398,17 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-blurTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setTextHaloBlurTransition(options); - assertEquals(layer.getTextHaloBlurTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setTextHaloBlurTransition(options); + assertEquals(layer.getTextHaloBlurTransition(), options); + } + }); } @Test @@ -3576,11 +4416,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-blur"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textHaloBlur(0.3f)); - assertEquals((Float) layer.getTextHaloBlur().getValue(), (Float) 0.3f); + // Set and Get + layer.setProperties(textHaloBlur(0.3f)); + assertEquals((Float) layer.getTextHaloBlur().getValue(), (Float) 0.3f); + } + }); } @Test @@ -3588,26 +4433,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-blur"); - assertNotNull(layer); - - // Set - layer.setProperties( - textHaloBlur( - zoom( - exponential( - stop(2, textHaloBlur(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textHaloBlur( + zoom( + exponential( + stop(2, textHaloBlur(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextHaloBlur()); - assertNotNull(layer.getTextHaloBlur().getFunction()); - assertEquals(CameraFunction.class, layer.getTextHaloBlur().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getTextHaloBlur().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getTextHaloBlur().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getTextHaloBlur().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextHaloBlur()); + assertNotNull(layer.getTextHaloBlur().getFunction()); + assertEquals(CameraFunction.class, layer.getTextHaloBlur().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getTextHaloBlur().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getTextHaloBlur().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getTextHaloBlur().getFunction().getStops()).size()); + } + }); } @Test @@ -3615,19 +4465,24 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-blur"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - textHaloBlur(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + textHaloBlur(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getTextHaloBlur()); - assertNotNull(layer.getTextHaloBlur().getFunction()); - assertEquals(SourceFunction.class, layer.getTextHaloBlur().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloBlur().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getTextHaloBlur().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextHaloBlur()); + assertNotNull(layer.getTextHaloBlur().getFunction()); + assertEquals(SourceFunction.class, layer.getTextHaloBlur().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloBlur().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getTextHaloBlur().getFunction().getStops().getClass()); + } + }); } @Test @@ -3635,26 +4490,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-blur"); - assertNotNull(layer); - - // Set - layer.setProperties( - textHaloBlur( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, textHaloBlur(0.3f)) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textHaloBlur( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, textHaloBlur(0.3f)) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextHaloBlur()); - assertNotNull(layer.getTextHaloBlur().getFunction()); - assertEquals(SourceFunction.class, layer.getTextHaloBlur().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloBlur().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getTextHaloBlur().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getTextHaloBlur()); + assertNotNull(layer.getTextHaloBlur().getFunction()); + assertEquals(SourceFunction.class, layer.getTextHaloBlur().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloBlur().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getTextHaloBlur().getFunction().getStops().getClass()); + } + }); } @Test @@ -3662,29 +4522,35 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-blur"); - assertNotNull(layer); - - // Set - layer.setProperties( - textHaloBlur( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, textHaloBlur(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textHaloBlur( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, textHaloBlur(0.3f)) + ) + ).withDefaultValue(textHaloBlur(0.3f)) ) - ).withDefaultValue(textHaloBlur(0.3f)) - ) - ); + ); + + // Verify + assertNotNull(layer.getTextHaloBlur()); + assertNotNull(layer.getTextHaloBlur().getFunction()); + assertEquals(SourceFunction.class, layer.getTextHaloBlur().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloBlur().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getTextHaloBlur().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getTextHaloBlur().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getTextHaloBlur().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getTextHaloBlur().getFunction()).getDefaultValue().getValue()); + } + }); - // Verify - assertNotNull(layer.getTextHaloBlur()); - assertNotNull(layer.getTextHaloBlur().getFunction()); - assertEquals(SourceFunction.class, layer.getTextHaloBlur().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloBlur().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getTextHaloBlur().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getTextHaloBlur().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getTextHaloBlur().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getTextHaloBlur().getFunction()).getDefaultValue().getValue()); } @Test @@ -3692,34 +4558,39 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-halo-blur"); - assertNotNull(layer); - - // Set - layer.setProperties( - textHaloBlur( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, textHaloBlur(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(textHaloBlur(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getTextHaloBlur()); - assertNotNull(layer.getTextHaloBlur().getFunction()); - assertEquals(CompositeFunction.class, layer.getTextHaloBlur().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getTextHaloBlur().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getTextHaloBlur().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getTextHaloBlur().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getTextHaloBlur().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textHaloBlur( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, textHaloBlur(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(textHaloBlur(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getTextHaloBlur()); + assertNotNull(layer.getTextHaloBlur().getFunction()); + assertEquals(CompositeFunction.class, layer.getTextHaloBlur().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getTextHaloBlur().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getTextHaloBlur().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getTextHaloBlur().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getTextHaloBlur().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test @@ -3727,12 +4598,17 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-translateTransitionOptions"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.setTextTranslateTransition(options); - assertEquals(layer.getTextTranslateTransition(), options); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setTextTranslateTransition(options); + assertEquals(layer.getTextTranslateTransition(), options); + } + }); } @Test @@ -3740,11 +4616,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-translate"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textTranslate(new Float[]{0f,0f})); - assertEquals((Float[]) layer.getTextTranslate().getValue(), (Float[]) new Float[]{0f,0f}); + // Set and Get + layer.setProperties(textTranslate(new Float[] {0f, 0f})); + assertEquals((Float[]) layer.getTextTranslate().getValue(), (Float[]) new Float[] {0f, 0f}); + } + }); } @Test @@ -3752,26 +4633,31 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-translate"); - assertNotNull(layer); - - // Set - layer.setProperties( - textTranslate( - zoom( - exponential( - stop(2, textTranslate(new Float[]{0f,0f})) - ).withBase(0.5f) - ) - ) - ); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textTranslate( + zoom( + exponential( + stop(2, textTranslate(new Float[] {0f, 0f})) + ).withBase(0.5f) + ) + ) + ); - // Verify - assertNotNull(layer.getTextTranslate()); - assertNotNull(layer.getTextTranslate().getFunction()); - assertEquals(CameraFunction.class, layer.getTextTranslate().getFunction().getClass()); - assertEquals(ExponentialStops.class, layer.getTextTranslate().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.getTextTranslate().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.getTextTranslate().getFunction().getStops()).size()); + // Verify + assertNotNull(layer.getTextTranslate()); + assertNotNull(layer.getTextTranslate().getFunction()); + assertEquals(CameraFunction.class, layer.getTextTranslate().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getTextTranslate().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getTextTranslate().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getTextTranslate().getFunction().getStops()).size()); + } + }); } @Test @@ -3779,11 +4665,16 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-translate-anchor"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(textTranslateAnchor(TEXT_TRANSLATE_ANCHOR_MAP)); - assertEquals((String) layer.getTextTranslateAnchor().getValue(), (String) TEXT_TRANSLATE_ANCHOR_MAP); + // Set and Get + layer.setProperties(textTranslateAnchor(TEXT_TRANSLATE_ANCHOR_MAP)); + assertEquals((String) layer.getTextTranslateAnchor().getValue(), (String) TEXT_TRANSLATE_ANCHOR_MAP); + } + }); } @Test @@ -3791,25 +4682,30 @@ public class SymbolLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("text-translate-anchor"); - assertNotNull(layer); - - // Set - layer.setProperties( - textTranslateAnchor( - zoom( - interval( - stop(2, textTranslateAnchor(TEXT_TRANSLATE_ANCHOR_MAP)) - ) - ) - ) - ); - - // Verify - assertNotNull(layer.getTextTranslateAnchor()); - assertNotNull(layer.getTextTranslateAnchor().getFunction()); - assertEquals(CameraFunction.class, layer.getTextTranslateAnchor().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getTextTranslateAnchor().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getTextTranslateAnchor().getFunction().getStops()).size()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textTranslateAnchor( + zoom( + interval( + stop(2, textTranslateAnchor(TEXT_TRANSLATE_ANCHOR_MAP)) + ) + ) + ) + ); + + // Verify + assertNotNull(layer.getTextTranslateAnchor()); + assertNotNull(layer.getTextTranslateAnchor().getFunction()); + assertEquals(CameraFunction.class, layer.getTextTranslateAnchor().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getTextTranslateAnchor().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getTextTranslateAnchor().getFunction().getStops()).size()); + } + }); } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs index 02aedadfa5..192740f708 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs @@ -7,9 +7,9 @@ package com.mapbox.mapboxsdk.testapp.style; import android.graphics.Color; -import android.support.test.espresso.Espresso; -import android.support.test.rule.ActivityTestRule; +import android.support.test.espresso.UiController; import android.support.test.runner.AndroidJUnit4; + import timber.log.Timber; import com.mapbox.mapboxsdk.maps.MapboxMap; @@ -23,20 +23,16 @@ import com.mapbox.mapboxsdk.style.functions.stops.IntervalStops; import com.mapbox.mapboxsdk.style.functions.stops.Stop; import com.mapbox.mapboxsdk.style.functions.stops.Stops; import com.mapbox.mapboxsdk.style.layers.<%- camelize(type) %>Layer; -import com.mapbox.mapboxsdk.testapp.R; -import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; -import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import static com.mapbox.mapboxsdk.style.functions.Function.*; import static com.mapbox.mapboxsdk.style.functions.stops.Stop.stop; import static com.mapbox.mapboxsdk.style.functions.stops.Stops.*; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; import static org.junit.Assert.*; import static com.mapbox.mapboxsdk.style.layers.Property.*; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; @@ -57,19 +53,30 @@ public class <%- camelize(type) %>LayerTest extends BaseActivityTest { return EspressoTestActivity.class; } - private void setupLayer(){ + private void setupLayer() { <% if (type === 'background') { -%> Timber.i("Retrieving layer"); - layer = mapboxMap.getLayerAs("background"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + layer = mapboxMap.getLayerAs("background"); + } + }); <% } else { -%> - if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { - Timber.i("Adding layer"); - layer = new <%- camelize(type) %>Layer("my-layer", "composite"); - layer.setSourceLayer("composite"); - mapboxMap.addLayer(layer); - // Layer reference is now stale, get new reference - layer = mapboxMap.getLayerAs("my-layer"); - } + Timber.i("Retrieving layer"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Timber.i("Adding layer"); + layer = new <%- camelize(type) %>Layer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + // Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + } + }); <% } -%> } @@ -78,14 +85,19 @@ public class <%- camelize(type) %>LayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("Visibility"); - assertNotNull(layer); - - // Get initial - assertEquals(layer.getVisibility().getValue(), VISIBLE); - - // Set - layer.setProperties(visibility(NONE)); - assertEquals(layer.getVisibility().getValue(), NONE); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + // Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + }); } <% if (!(type === 'background' || type === 'raster')) { -%> @@ -94,15 +106,20 @@ public class <%- camelize(type) %>LayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("SourceLayer"); - assertNotNull(layer); - - // Get initial - assertEquals(layer.getSourceLayer(), "composite"); - - // Set - final String sourceLayer = "test"; - layer.setSourceLayer(sourceLayer); - assertEquals(layer.getSourceLayer(), sourceLayer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Get initial + assertEquals(layer.getSourceLayer(), "composite"); + + // Set + final String sourceLayer = "test"; + layer.setSourceLayer(sourceLayer); + assertEquals(layer.getSourceLayer(), sourceLayer); + } + }); } <% } -%> <% for (const property of properties) { -%> @@ -113,12 +130,17 @@ public class <%- camelize(type) %>LayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("<%- property.name %>TransitionOptions"); - assertNotNull(layer); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - layer.set<%- camelize(property.name) %>Transition(options); - assertEquals(layer.get<%- camelize(property.name) %>Transition(), options); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.set<%- camelize(property.name) %>Transition(options); + assertEquals(layer.get<%- camelize(property.name) %>Transition(), options); + } + }); } <% } -%> @@ -127,11 +149,16 @@ public class <%- camelize(type) %>LayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("<%- property.name %>"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(<%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)); - assertEquals((<%- propertyType(property) %>) layer.get<%- camelize(property.name) %>().getValue(), (<%- propertyType(property) %>) <%- defaultValueJava(property) %>); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(<%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)); + assertEquals((<%- propertyType(property) %>) layer.get<%- camelize(property.name) %>().getValue(), (<%- propertyType(property) %>) <%- defaultValueJava(property) %>); + } + }); } <% if (supportsZoomFunction(property)) { -%> @@ -140,37 +167,42 @@ public class <%- camelize(type) %>LayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("<%- property.name %>"); - assertNotNull(layer); - - // Set - layer.setProperties( - <%- camelizeWithLeadingLowercase(property.name) %>( - zoom( + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + <%- camelizeWithLeadingLowercase(property.name) %>( + zoom( <% if (property.function == 'piecewise-constant') { -%> - interval( - stop(2, <%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)) - ) + interval( + stop(2, <%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)) + ) <% } else { -%> - exponential( - stop(2, <%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)) - ).withBase(0.5f) + exponential( + stop(2, <%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)) + ).withBase(0.5f) <% } -%> - ) - ) - ); - - // Verify - assertNotNull(layer.get<%- camelize(property.name) %>()); - assertNotNull(layer.get<%- camelize(property.name) %>().getFunction()); - assertEquals(CameraFunction.class, layer.get<%- camelize(property.name) %>().getFunction().getClass()); + ) + ) + ); + + // Verify + assertNotNull(layer.get<%- camelize(property.name) %>()); + assertNotNull(layer.get<%- camelize(property.name) %>().getFunction()); + assertEquals(CameraFunction.class, layer.get<%- camelize(property.name) %>().getFunction().getClass()); <% if (property.function == 'piecewise-constant') { -%> - assertEquals(IntervalStops.class, layer.get<%- camelize(property.name) %>().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.get<%- camelize(property.name) %>().getFunction().getStops()).size()); + assertEquals(IntervalStops.class, layer.get<%- camelize(property.name) %>().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.get<%- camelize(property.name) %>().getFunction().getStops()).size()); <% } else { -%> - assertEquals(ExponentialStops.class, layer.get<%- camelize(property.name) %>().getFunction().getStops().getClass()); - assertEquals(0.5f, ((ExponentialStops) layer.get<%- camelize(property.name) %>().getFunction().getStops()).getBase(), 0.001); - assertEquals(1, ((ExponentialStops) layer.get<%- camelize(property.name) %>().getFunction().getStops()).size()); + assertEquals(ExponentialStops.class, layer.get<%- camelize(property.name) %>().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.get<%- camelize(property.name) %>().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.get<%- camelize(property.name) %>().getFunction().getStops()).size()); <% } -%> + } + }); } <% } -%> <% if (supportsPropertyFunction(property)) { -%> @@ -180,19 +212,24 @@ public class <%- camelize(type) %>LayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("<%- property.name %>"); - assertNotNull(layer); - - // Set - layer.setProperties( - <%- camelizeWithLeadingLowercase(property.name) %>(property("FeaturePropertyA", Stops.<<%- propertyType(property) %>>identity())) - ); - - // Verify - assertNotNull(layer.get<%- camelize(property.name) %>()); - assertNotNull(layer.get<%- camelize(property.name) %>().getFunction()); - assertEquals(SourceFunction.class, layer.get<%- camelize(property.name) %>().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.get<%- camelize(property.name) %>().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + <%- camelizeWithLeadingLowercase(property.name) %>(property("FeaturePropertyA", Stops.<<%- propertyType(property) %>>identity())) + ); + + // Verify + assertNotNull(layer.get<%- camelize(property.name) %>()); + assertNotNull(layer.get<%- camelize(property.name) %>().getFunction()); + assertEquals(SourceFunction.class, layer.get<%- camelize(property.name) %>().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.get<%- camelize(property.name) %>().getFunction().getStops().getClass()); + } + }); } <% if (property.function == 'piecewise-constant') { -%> @@ -201,30 +238,35 @@ public class <%- camelize(type) %>LayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("<%- property.name %>"); - assertNotNull(layer); - - // Set - layer.setProperties( - <%- camelizeWithLeadingLowercase(property.name) %>( - property( - "FeaturePropertyA", - interval( + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + <%- camelizeWithLeadingLowercase(property.name) %>( + property( + "FeaturePropertyA", + interval( <% if (property.type == 'color') { -%> - stop(Color.RED, <%- camelizeWithLeadingLowercase(property.name) %>(Color.RED)) + stop(Color.RED, <%- camelizeWithLeadingLowercase(property.name) %>(Color.RED)) <% } else {-%> - stop(1, <%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)) - ) + stop(1, <%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)) + ) <% } -%> - ) - ) - ); - - // Verify - assertNotNull(layer.get<%- camelize(property.name) %>()); - assertNotNull(layer.get<%- camelize(property.name) %>().getFunction()); - assertEquals(SourceFunction.class, layer.get<%- camelize(property.name) %>().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getProperty()); - assertEquals(IntervalStops.class, layer.get<%- camelize(property.name) %>().getFunction().getStops().getClass()); + ) + ) + ); + + // Verify + assertNotNull(layer.get<%- camelize(property.name) %>()); + assertNotNull(layer.get<%- camelize(property.name) %>().getFunction()); + assertEquals(SourceFunction.class, layer.get<%- camelize(property.name) %>().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getProperty()); + assertEquals(IntervalStops.class, layer.get<%- camelize(property.name) %>().getFunction().getStops().getClass()); + } + }); } <% } else if (property.type === 'array') { -%> @@ -233,30 +275,35 @@ public class <%- camelize(type) %>LayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("<%- property.name %>"); - assertNotNull(layer); - - // Set - layer.setProperties( - <%- camelizeWithLeadingLowercase(property.name) %>( - property( - "FeaturePropertyA", - interval( + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + <%- camelizeWithLeadingLowercase(property.name) %>( + property( + "FeaturePropertyA", + interval( <% if (property.type == 'color') { -%> - stop(Color.RED, <%- camelizeWithLeadingLowercase(property.name) %>(Color.RED)) + stop(Color.RED, <%- camelizeWithLeadingLowercase(property.name) %>(Color.RED)) <% } else {-%> - stop(1, <%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)) + stop(1, <%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)) <% } -%> + ) + ) ) - ) - ) - ); - - // Verify - assertNotNull(layer.get<%- camelize(property.name) %>()); - assertNotNull(layer.get<%- camelize(property.name) %>().getFunction()); - assertEquals(SourceFunction.class, layer.get<%- camelize(property.name) %>().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getProperty()); - assertEquals(IntervalStops.class, layer.get<%- camelize(property.name) %>().getFunction().getStops().getClass()); + ); + + // Verify + assertNotNull(layer.get<%- camelize(property.name) %>()); + assertNotNull(layer.get<%- camelize(property.name) %>().getFunction()); + assertEquals(SourceFunction.class, layer.get<%- camelize(property.name) %>().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getProperty()); + assertEquals(IntervalStops.class, layer.get<%- camelize(property.name) %>().getFunction().getStops().getClass()); + } + }); } <% } else { -%> @@ -265,30 +312,35 @@ public class <%- camelize(type) %>LayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("<%- property.name %>"); - assertNotNull(layer); - - // Set - layer.setProperties( - <%- camelizeWithLeadingLowercase(property.name) %>( - property( - "FeaturePropertyA", - exponential( + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + <%- camelizeWithLeadingLowercase(property.name) %>( + property( + "FeaturePropertyA", + exponential( <% if (property.type == 'color') { -%> - stop(Color.RED, <%- camelizeWithLeadingLowercase(property.name) %>(Color.RED)) + stop(Color.RED, <%- camelizeWithLeadingLowercase(property.name) %>(Color.RED)) <% } else {-%> - stop(<%- defaultValueJava(property) %>, <%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)) + stop(<%- defaultValueJava(property) %>, <%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)) <% } -%> - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.get<%- camelize(property.name) %>()); - assertNotNull(layer.get<%- camelize(property.name) %>().getFunction()); - assertEquals(SourceFunction.class, layer.get<%- camelize(property.name) %>().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.get<%- camelize(property.name) %>().getFunction().getStops().getClass()); + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.get<%- camelize(property.name) %>()); + assertNotNull(layer.get<%- camelize(property.name) %>().getFunction()); + assertEquals(SourceFunction.class, layer.get<%- camelize(property.name) %>().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.get<%- camelize(property.name) %>().getFunction().getStops().getClass()); + } + }); } @Test @@ -296,39 +348,45 @@ public class <%- camelize(type) %>LayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("<%- property.name %>"); - assertNotNull(layer); - - // Set - layer.setProperties( - <%- camelizeWithLeadingLowercase(property.name) %>( - property( - "FeaturePropertyA", - categorical( + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + <%- camelizeWithLeadingLowercase(property.name) %>( + property( + "FeaturePropertyA", + categorical( <% if (property.type == 'color') { -%> - stop("valueA", <%- camelizeWithLeadingLowercase(property.name) %>(Color.RED)) - ) - ).withDefaultValue(<%- camelizeWithLeadingLowercase(property.name) %>(Color.GREEN)) + stop("valueA", <%- camelizeWithLeadingLowercase(property.name) %>(Color.RED)) + ) + ).withDefaultValue(<%- camelizeWithLeadingLowercase(property.name) %>(Color.GREEN)) <% } else {-%> - stop(1.0f, <%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)) - ) - ).withDefaultValue(<%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)) + stop(1.0f, <%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)) + ) + ).withDefaultValue(<%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)) <% } -%> - ) - ); - - // Verify - assertNotNull(layer.get<%- camelize(property.name) %>()); - assertNotNull(layer.get<%- camelize(property.name) %>().getFunction()); - assertEquals(SourceFunction.class, layer.get<%- camelize(property.name) %>().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.get<%- camelize(property.name) %>().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getDefaultValue().getValue()); + ) + ); + + // Verify + assertNotNull(layer.get<%- camelize(property.name) %>()); + assertNotNull(layer.get<%- camelize(property.name) %>().getFunction()); + assertEquals(SourceFunction.class, layer.get<%- camelize(property.name) %>().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.get<%- camelize(property.name) %>().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getDefaultValue().getValue()); <% if (property.type === 'color') { -%> - assertEquals(Color.GREEN, (int) ((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getDefaultValue().getColorInt()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getDefaultValue().getColorInt()); <% } else { -%> - assertEquals(<%- defaultValueJava(property) %>, ((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getDefaultValue().getValue()); + assertEquals(<%- defaultValueJava(property) %>, ((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getDefaultValue().getValue()); <% } -%> + } + }); + } <% if (property.type !== 'color') { -%> @@ -337,38 +395,43 @@ public class <%- camelize(type) %>LayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("<%- property.name %>"); - assertNotNull(layer); - - // Set - layer.setProperties( - <%- camelizeWithLeadingLowercase(property.name) %>( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, <%- camelizeWithLeadingLowercase(property.name) %>(0.9f)) - ).withBase(0.5f) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + <%- camelizeWithLeadingLowercase(property.name) %>( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, <%- camelizeWithLeadingLowercase(property.name) %>(0.9f)) + ).withBase(0.5f) <% if (property.type == 'number') { -%> - ).withDefaultValue(<%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)) + ).withDefaultValue(<%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)) <% } else { -%> - ) + ) <% } -%> - ) - ); - - // Verify - assertNotNull(layer.get<%- camelize(property.name) %>()); - assertNotNull(layer.get<%- camelize(property.name) %>().getFunction()); - assertEquals(CompositeFunction.class, layer.get<%- camelize(property.name) %>().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.get<%- camelize(property.name) %>().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.get<%- camelize(property.name) %>().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.get<%- camelize(property.name) %>().getFunction().getStops()).size()); - - ExponentialStops>, <%- propertyType(property) %>> stops = - (ExponentialStops>, <%- propertyType(property) %>>) layer.get<%- camelize(property.name) %>().getFunction().getStops(); - Stop>, <%- propertyType(property) %>> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + ) + ); + + // Verify + assertNotNull(layer.get<%- camelize(property.name) %>()); + assertNotNull(layer.get<%- camelize(property.name) %>().getFunction()); + assertEquals(CompositeFunction.class, layer.get<%- camelize(property.name) %>().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.get<%- camelize(property.name) %>().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.get<%- camelize(property.name) %>().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.get<%- camelize(property.name) %>().getFunction().getStops()).size()); + + ExponentialStops>, <%- propertyType(property) %>> stops = + (ExponentialStops>, <%- propertyType(property) %>>) layer.get<%- camelize(property.name) %>().getFunction().getStops(); + Stop>, <%- propertyType(property) %>> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } <% } -%> <% } -%> @@ -380,11 +443,16 @@ public class <%- camelize(type) %>LayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("<%- property.name %>"); - assertNotNull(layer); - - // Set and Get - layer.setProperties(<%- camelizeWithLeadingLowercase(property.name) %>(Color.RED)); - assertEquals(layer.get<%- camelize(property.name) %>AsInt(), Color.RED); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(<%- camelizeWithLeadingLowercase(property.name) %>(Color.RED)); + assertEquals(layer.get<%- camelize(property.name) %>AsInt(), Color.RED); + } + }); } <% } -%> <% } -%> diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/light.junit.ejs b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/light.junit.ejs index cb3ba58100..2f22a8f3f0 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/light.junit.ejs +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/light.junit.ejs @@ -9,6 +9,7 @@ import android.support.test.espresso.ViewAction; import android.support.test.runner.AndroidJUnit4; import android.view.View; +import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.style.light.Light; import com.mapbox.mapboxsdk.style.functions.Function; import com.mapbox.mapboxsdk.style.functions.stops.IdentityStops; @@ -16,6 +17,7 @@ import com.mapbox.mapboxsdk.style.layers.FillExtrusionLayer; import com.mapbox.mapboxsdk.style.layers.TransitionOptions; import com.mapbox.mapboxsdk.style.light.Position; import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; import com.mapbox.mapboxsdk.testapp.activity.style.FillExtrusionStyleTestActivity; @@ -35,6 +37,7 @@ import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionCol import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionHeight; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionOpacity; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; @@ -48,14 +51,18 @@ public class LightTest extends BaseActivityTest { @Test public void test<%- camelize(property.name) %>Transition() { validateTestSetup(); - setupLayer(); + setupLight(); Timber.i("<%- property.name %>TransitionOptions"); - assertNotNull(light); - - // Set and Get - TransitionOptions options = new TransitionOptions(300, 100); - light.set<%- camelize(property.name) %>Transition(options); - assertEquals("Transition options should match", options, light.get<%- camelize(property.name) %>Transition()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(light); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + light.set<%- camelize(property.name) %>Transition(options); + assertEquals("Transition options should match", options, light.get<%- camelize(property.name) %>Transition()); + } + }); } <% } -%> <% if (property.name == "position") { -%> @@ -63,35 +70,44 @@ public class LightTest extends BaseActivityTest { @Test public void test<%- camelize(property.name) %>() { validateTestSetup(); - setupLayer(); + setupLight(); Timber.i("<%- property.name %>"); - assertNotNull(light); - - // Set and Get - Position position = new Position(1,2,3); - light.set<%- camelize(property.name) %>(position); - assertEquals("Position should match", position, light.get<%- camelize(property.name) %>()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(light); + // Set and Get + Position position = new Position(1, 2, 3); + light.set<%- camelize(property.name) %>(position); + assertEquals("Position should match", position, light.get<%- camelize(property.name) %>()); + } + }); } <% } else { -%> @Test public void test<%- camelize(property.name) %>() { validateTestSetup(); - setupLayer(); + setupLight(); Timber.i("<%- property.name %>"); - assertNotNull(light); - // Set and Get - light.set<%- camelize(property.name) %>(<%- defaultValueJava(property) %>); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(light); + // Set and Get + light.set<%- camelize(property.name) %>(<%- defaultValueJava(property) %>); <% if (property.name == 'color') { -%> - assertEquals("<%- camelize(property.name) %> should match", <%- defaultValueJava(property) %>.replaceAll("\\s+",""), light.get<%- camelize(property.name) %>()); + assertEquals("<%- camelize(property.name) %> should match", <%- defaultValueJava(property) %>.replaceAll("\\s+", ""), light.get<%- camelize(property.name) %>()); <% } else { -%> - assertEquals("<%- camelize(property.name) %> should match", <%- defaultValueJava(property) %>, light.get<%- camelize(property.name) %>()); + assertEquals("<%- camelize(property.name) %> should match", <%- defaultValueJava(property) %>, light.get<%- camelize(property.name) %>()); <% } -%> + } + }); } <% } -%> <% } -%> - private void setupLayer() { + private void setupLight() { onView(withId(R.id.mapView)).perform(new ViewAction() { @Override public Matcher getConstraints() { diff --git a/platform/android/scripts/generate-style-code.js b/platform/android/scripts/generate-style-code.js index bb04e3ba2a..a8b2c98c86 100644 --- a/platform/android/scripts/generate-style-code.js +++ b/platform/android/scripts/generate-style-code.js @@ -167,11 +167,11 @@ global.defaultValueJava = function(property) { case 'string': return '[' + property['default'] + "]"; case 'number': - var result ='new Float[]{'; + var result ='new Float[] {'; for (var i = 0; i < property.length; i++) { result += "0f"; if (i +1 != property.length) { - result += ","; + result += ", "; } } return result + "}"; -- cgit v1.2.1 From 87a05b29c9f09ad36ec01b71f78ba5e6ad3aa88b Mon Sep 17 00:00:00 2001 From: Fabian Guerra Date: Mon, 12 Jun 2017 11:30:53 -0400 Subject: [ios, macos] Fix MGLSphericalPosition.radial misleading type. --- platform/darwin/src/MGLLight.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/darwin/src/MGLLight.h b/platform/darwin/src/MGLLight.h index ef9811bd33..6dd24712e2 100644 --- a/platform/darwin/src/MGLLight.h +++ b/platform/darwin/src/MGLLight.h @@ -20,7 +20,7 @@ typedef NS_ENUM(NSUInteger, MGLLightAnchor) { */ typedef struct MGLSphericalPosition { /** Distance from the center of the base of an object to its light. */ - CLLocationDistance radial; + CGFloat radial; /** Position of the light relative to 0° (0° when `MGLLight.anchor` is set to viewport corresponds to the top of the viewport, or 0° when `MGLLight.anchor` is set to map corresponds to due north, and degrees proceed clockwise). */ -- cgit v1.2.1 From 0c275ad6fa8d2c1e2523b6df7696d6fb09587411 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Tue, 13 Jun 2017 12:43:48 +0200 Subject: [android] - correct source changed map event javadoc (#9243) --- .../src/main/java/com/mapbox/mapboxsdk/maps/MapView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9a1f2fc515..098c701e03 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 @@ -774,7 +774,7 @@ public class MapView extends FrameLayout { public static final int DID_FINISH_LOADING_STYLE = 14; /** - * This {@link MapChange} is triggered when a source attribution changes. + * This {@link MapChange} is triggered when a source changes. *

      * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}. *

      -- cgit v1.2.1 From 7bfcce02662a9c429c3ac715728de63e2850231e Mon Sep 17 00:00:00 2001 From: Tobrun Date: Wed, 14 Jun 2017 14:34:03 +0200 Subject: Cherry pick release (#9263) * [core] - bump earcut version dependency to handle unused lamba warning (#9242) * [android] - snapshot bitmap contains view based content (#9252) --- CMakeLists.txt | 2 +- .../com/mapbox/mapboxsdk/maps/NativeMapView.java | 16 ++++++++--- .../com/mapbox/mapboxsdk/utils/BitmapUtils.java | 33 ++++++++++++++++++++++ 3 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/BitmapUtils.java diff --git a/CMakeLists.txt b/CMakeLists.txt index f0c7a2ac57..8144d880ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,7 +50,7 @@ mason_use(boost VERSION 1.62.0 HEADER_ONLY) mason_use(geojsonvt VERSION 6.2.0 HEADER_ONLY) mason_use(supercluster VERSION 0.2.0-1 HEADER_ONLY) mason_use(kdbush VERSION 0.1.1-1 HEADER_ONLY) -mason_use(earcut VERSION 0.12.1 HEADER_ONLY) +mason_use(earcut VERSION 0.12.3 HEADER_ONLY) mason_use(protozero VERSION 1.4.2 HEADER_ONLY) mason_use(pixelmatch VERSION 0.10.0 HEADER_ONLY) mason_use(geojson VERSION 0.4.0 HEADER_ONLY) 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 a31babc1c5..af3b57151d 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 @@ -29,6 +29,7 @@ import com.mapbox.mapboxsdk.style.layers.Layer; import com.mapbox.mapboxsdk.style.light.Light; import com.mapbox.mapboxsdk.style.sources.CannotAddSourceException; import com.mapbox.mapboxsdk.style.sources.Source; +import com.mapbox.mapboxsdk.utils.BitmapUtils; import com.mapbox.services.commons.geojson.Feature; import java.nio.ByteBuffer; @@ -39,7 +40,6 @@ import java.util.concurrent.CopyOnWriteArrayList; import timber.log.Timber; - // Class that wraps the native methods for convenience final class NativeMapView { @@ -920,12 +920,20 @@ final class NativeMapView { } protected void onFpsChanged(double fps) { + if (isDestroyedOn("OnFpsChanged")) { + return; + } mapView.onFpsChanged(fps); } - protected void onSnapshotReady(Bitmap bitmap) { - if (snapshotReadyCallback != null && bitmap != null) { - snapshotReadyCallback.onSnapshotReady(bitmap); + protected void onSnapshotReady(Bitmap mapContent) { + if (isDestroyedOn("OnSnapshotReady")) { + return; + } + + Bitmap viewContent = BitmapUtils.createBitmapFromView(mapView); + if (snapshotReadyCallback != null && mapContent != null && viewContent != null) { + snapshotReadyCallback.onSnapshotReady(BitmapUtils.mergeBitmap(mapContent, viewContent)); } } 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 new file mode 100644 index 0000000000..e3fc765734 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/BitmapUtils.java @@ -0,0 +1,33 @@ +package com.mapbox.mapboxsdk.utils; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.support.annotation.NonNull; +import android.view.View; + +public class BitmapUtils { + + public static Bitmap createBitmapFromView(@NonNull View view) { + view.setDrawingCacheEnabled(true); + view.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_LOW); + view.buildDrawingCache(); + + if (view.getDrawingCache() == null) { + return null; + } + + Bitmap snapshot = Bitmap.createBitmap(view.getDrawingCache()); + view.setDrawingCacheEnabled(false); + view.destroyDrawingCache(); + return snapshot; + } + + public static Bitmap mergeBitmap(@NonNull Bitmap background, @NonNull Bitmap foreground) { + Bitmap result = Bitmap.createBitmap(background.getWidth(), background.getHeight(), background.getConfig()); + Canvas canvas = new Canvas(result); + canvas.drawBitmap(background, 0f, 0f, null); + canvas.drawBitmap(foreground, 10, 10, null); + return result; + } + +} -- cgit v1.2.1 From 441b80d574783e959bf18c01bdb8cfee740424c5 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 12 Jun 2017 16:39:59 -0700 Subject: [core] Reduce number of varyings to 8 or less For #pragmas, don't generate varyings for attributes that aren't used by the fragment shader. Pack other varyings more tightly. --- scripts/generate-shaders.js | 65 ++++++++++++++++----------------------- src/mbgl/shaders/circle.cpp | 24 ++++++++------- src/mbgl/shaders/line.cpp | 6 ++-- src/mbgl/shaders/line_pattern.cpp | 6 ++-- src/mbgl/shaders/line_sdf.cpp | 6 ++-- src/mbgl/shaders/symbol_sdf.cpp | 49 ++++++++++++++++------------- 6 files changed, 73 insertions(+), 83 deletions(-) diff --git a/scripts/generate-shaders.js b/scripts/generate-shaders.js index 2f1f4c2f9c..2813d27365 100755 --- a/scripts/generate-shaders.js +++ b/scripts/generate-shaders.js @@ -61,42 +61,31 @@ ${fragmentPrelude} 'symbol_icon', 'symbol_sdf' ].forEach(function (shaderName) { - function applyPragmas(source, pragmas) { - return source.replace(/#pragma mapbox: ([\w]+) ([\w]+) ([\w]+) ([\w]+)/g, (match, operation, precision, type, name) => { - const a_type = type === "float" ? "vec2" : "vec4"; - return pragmas[operation] - .join("\n") - .replace(/\{type\}/g, type) - .replace(/\{a_type}/g, a_type) - .replace(/\{precision\}/g, precision) - .replace(/\{name\}/g, name); - }); - } - - function vertexSource() { - const source = fs.readFileSync(path.join(inputPath, shaderName + '.vertex.glsl'), 'utf8'); - return applyPragmas(source, { - define: [ - "uniform lowp float a_{name}_t;", - "attribute {precision} {a_type} a_{name};", - "varying {precision} {type} {name};" - ], - initialize: [ - "{name} = unpack_mix_{a_type}(a_{name}, a_{name}_t);" - ] - }); - } - - function fragmentSource() { - const source = fs.readFileSync(path.join(inputPath, shaderName + '.fragment.glsl'), 'utf8'); - return applyPragmas(source, { - define: [ - "varying {precision} {type} {name};" - ], - initialize: [ - ] - }); - } + const re = /#pragma mapbox: ([\w]+) ([\w]+) ([\w]+) ([\w]+)/g; + const fragmentPragmas = new Set(); + + let fragmentSource = fs.readFileSync(path.join(inputPath, shaderName + '.fragment.glsl'), 'utf8'); + let vertexSource = fs.readFileSync(path.join(inputPath, shaderName + '.vertex.glsl'), 'utf8'); + + fragmentSource = fragmentSource.replace(re, (match, operation, precision, type, name) => { + fragmentPragmas.add(name); + return operation === "define" ? + `varying ${precision} ${type} ${name};` : + ``; + }); + + vertexSource = vertexSource.replace(re, (match, operation, precision, type, name) => { + const a_type = type === "float" ? "vec2" : "vec4"; + if (fragmentPragmas.has(name)) { + return operation === "define" ? + `uniform lowp float a_${name}_t;\nattribute ${precision} ${a_type} a_${name};\nvarying ${precision} ${type} ${name};` : + `${name} = unpack_mix_${a_type}(a_${name}, a_${name}_t);`; + } else { + return operation === "define" ? + `uniform lowp float a_${name}_t;\nattribute ${precision} ${a_type} a_${name};` : + `${precision} ${type} ${name} = unpack_mix_${a_type}(a_${name}, a_${name}_t);`; + } + }); writeIfModified(path.join(outputPath, `${shaderName}.hpp`), `// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. @@ -125,10 +114,10 @@ namespace shaders { const char* ${shaderName}::name = "${shaderName}"; const char* ${shaderName}::vertexSource = R"MBGL_SHADER( -${vertexSource()} +${vertexSource} )MBGL_SHADER"; const char* ${shaderName}::fragmentSource = R"MBGL_SHADER( -${fragmentSource()} +${fragmentSource} )MBGL_SHADER"; } // namespace shaders diff --git a/src/mbgl/shaders/circle.cpp b/src/mbgl/shaders/circle.cpp index 1c977d2bce..2ecceeca70 100644 --- a/src/mbgl/shaders/circle.cpp +++ b/src/mbgl/shaders/circle.cpp @@ -35,8 +35,7 @@ uniform lowp float a_stroke_opacity_t; attribute lowp vec2 a_stroke_opacity; varying lowp float stroke_opacity; -varying vec2 v_extrude; -varying lowp float v_antialiasblur; +varying vec3 v_data; void main(void) { color = unpack_mix_vec4(a_color, a_color_t); @@ -48,23 +47,24 @@ void main(void) { stroke_opacity = unpack_mix_vec2(a_stroke_opacity, a_stroke_opacity_t); // unencode the extrusion vector that we snuck into the a_pos vector - v_extrude = vec2(mod(a_pos, 2.0) * 2.0 - 1.0); + vec2 extrude = vec2(mod(a_pos, 2.0) * 2.0 - 1.0); - vec2 extrude = v_extrude * (radius + stroke_width) * u_extrude_scale; // multiply a_pos by 0.5, since we had it * 2 in order to sneak // in extrusion data gl_Position = u_matrix * vec4(floor(a_pos * 0.5), 0, 1); if (u_scale_with_map) { - gl_Position.xy += extrude; + gl_Position.xy += extrude * (radius + stroke_width) * u_extrude_scale; } else { - gl_Position.xy += extrude * gl_Position.w; + gl_Position.xy += extrude * (radius + stroke_width) * u_extrude_scale * gl_Position.w; } // This is a minimum blur distance that serves as a faux-antialiasing for // the circle. since blur is a ratio of the circle's size and the intent is // to keep the blur at roughly 1px, the two are inversely related. - v_antialiasblur = 1.0 / DEVICE_PIXEL_RATIO / (radius + stroke_width); + lowp float antialiasblur = 1.0 / DEVICE_PIXEL_RATIO / (radius + stroke_width); + + v_data = vec3(extrude.x, extrude.y, antialiasblur); } )MBGL_SHADER"; @@ -77,8 +77,7 @@ varying highp vec4 stroke_color; varying mediump float stroke_width; varying lowp float stroke_opacity; -varying vec2 v_extrude; -varying lowp float v_antialiasblur; +varying vec3 v_data; void main() { @@ -89,8 +88,11 @@ void main() { - float extrude_length = length(v_extrude); - float antialiased_blur = -max(blur, v_antialiasblur); + vec2 extrude = v_data.xy; + float extrude_length = length(extrude); + + lowp float antialiasblur = v_data.z; + float antialiased_blur = -max(blur, antialiasblur); float opacity_t = smoothstep(0.0, antialiased_blur, extrude_length - 1.0); diff --git a/src/mbgl/shaders/line.cpp b/src/mbgl/shaders/line.cpp index 4392bd051f..e101cf6ee1 100644 --- a/src/mbgl/shaders/line.cpp +++ b/src/mbgl/shaders/line.cpp @@ -44,17 +44,15 @@ attribute lowp vec2 a_opacity; varying lowp float opacity; uniform lowp float a_gapwidth_t; attribute mediump vec2 a_gapwidth; -varying mediump float gapwidth; uniform lowp float a_offset_t; attribute lowp vec2 a_offset; -varying lowp float offset; void main() { color = unpack_mix_vec4(a_color, a_color_t); blur = unpack_mix_vec2(a_blur, a_blur_t); opacity = unpack_mix_vec2(a_opacity, a_opacity_t); - gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t); - offset = unpack_mix_vec2(a_offset, a_offset_t); + mediump float gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t); + lowp float offset = unpack_mix_vec2(a_offset, a_offset_t); vec2 a_extrude = a_data.xy - 128.0; float a_direction = mod(a_data.z, 4.0) - 1.0; diff --git a/src/mbgl/shaders/line_pattern.cpp b/src/mbgl/shaders/line_pattern.cpp index f52a8e2157..79433b53a0 100644 --- a/src/mbgl/shaders/line_pattern.cpp +++ b/src/mbgl/shaders/line_pattern.cpp @@ -44,16 +44,14 @@ attribute lowp vec2 a_opacity; varying lowp float opacity; uniform lowp float a_offset_t; attribute lowp vec2 a_offset; -varying lowp float offset; uniform lowp float a_gapwidth_t; attribute mediump vec2 a_gapwidth; -varying mediump float gapwidth; void main() { blur = unpack_mix_vec2(a_blur, a_blur_t); opacity = unpack_mix_vec2(a_opacity, a_opacity_t); - offset = unpack_mix_vec2(a_offset, a_offset_t); - gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t); + lowp float offset = unpack_mix_vec2(a_offset, a_offset_t); + mediump float gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t); vec2 a_extrude = a_data.xy - 128.0; float a_direction = mod(a_data.z, 4.0) - 1.0; diff --git a/src/mbgl/shaders/line_sdf.cpp b/src/mbgl/shaders/line_sdf.cpp index 17a6a19739..4f6cf814f9 100644 --- a/src/mbgl/shaders/line_sdf.cpp +++ b/src/mbgl/shaders/line_sdf.cpp @@ -52,17 +52,15 @@ attribute lowp vec2 a_opacity; varying lowp float opacity; uniform lowp float a_gapwidth_t; attribute mediump vec2 a_gapwidth; -varying mediump float gapwidth; uniform lowp float a_offset_t; attribute lowp vec2 a_offset; -varying lowp float offset; void main() { color = unpack_mix_vec4(a_color, a_color_t); blur = unpack_mix_vec2(a_blur, a_blur_t); opacity = unpack_mix_vec2(a_opacity, a_opacity_t); - gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t); - offset = unpack_mix_vec2(a_offset, a_offset_t); + mediump float gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t); + lowp float offset = unpack_mix_vec2(a_offset, a_offset_t); vec2 a_extrude = a_data.xy - 128.0; float a_direction = mod(a_data.z, 4.0) - 1.0; diff --git a/src/mbgl/shaders/symbol_sdf.cpp b/src/mbgl/shaders/symbol_sdf.cpp index 194e624036..0c39c5f4ac 100644 --- a/src/mbgl/shaders/symbol_sdf.cpp +++ b/src/mbgl/shaders/symbol_sdf.cpp @@ -57,10 +57,8 @@ uniform vec2 u_extrude_scale; uniform vec2 u_texsize; -varying vec2 v_tex; -varying vec2 v_fade_tex; -varying float v_gamma_scale; -varying float v_size; +varying vec4 v_data0; +varying vec2 v_data1; void main() { fill_color = unpack_mix_vec4(a_fill_color, a_fill_color_t); @@ -81,6 +79,7 @@ void main() { mediump vec2 a_zoom = unpack_float(a_data[3]); mediump float a_minzoom = a_zoom[0]; mediump float a_maxzoom = a_zoom[1]; + float size; // In order to accommodate placing labels around corners in // symbol-placement: line, each glyph in a label could have multiple @@ -92,22 +91,22 @@ void main() { // based on the scale of rendered text size relative to layout text size. mediump float layoutSize; if (!u_is_size_zoom_constant && !u_is_size_feature_constant) { - v_size = mix(a_size[0], a_size[1], u_size_t) / 10.0; + size = mix(a_size[0], a_size[1], u_size_t) / 10.0; layoutSize = a_size[2] / 10.0; } else if (u_is_size_zoom_constant && !u_is_size_feature_constant) { - v_size = a_size[0] / 10.0; - layoutSize = v_size; + size = a_size[0] / 10.0; + layoutSize = size; } else if (!u_is_size_zoom_constant && u_is_size_feature_constant) { - v_size = u_size; + size = u_size; layoutSize = u_layout_size; } else { - v_size = u_size; + size = u_size; layoutSize = u_size; } - float fontScale = u_is_text ? v_size / 24.0 : v_size; + float fontScale = u_is_text ? size / 24.0 : size; - mediump float zoomAdjust = log2(v_size / layoutSize); + mediump float zoomAdjust = log2(size / layoutSize); mediump float adjustedZoom = (u_zoom - zoomAdjust) * 10.0; // result: z = 0 if a_minzoom <= adjustedZoom < a_maxzoom, and 1 otherwise // Used below to move the vertex out of the clip space for when the current @@ -156,10 +155,13 @@ void main() { gl_Position = u_matrix * vec4(a_pos, 0, 1) + vec4(extrude, 0, 0); } - v_gamma_scale = gl_Position.w; + float gamma_scale = gl_Position.w; - v_tex = a_tex / u_texsize; - v_fade_tex = vec2(a_labelminzoom / 255.0, 0.0); + vec2 tex = a_tex / u_texsize; + vec2 fade_tex = vec2(a_labelminzoom / 255.0, 0.0); + + v_data0 = vec4(tex.x, tex.y, fade_tex.x, fade_tex.y); + v_data1 = vec2(gamma_scale, size); } )MBGL_SHADER"; @@ -179,10 +181,8 @@ uniform sampler2D u_fadetexture; uniform highp float u_gamma_scale; uniform bool u_is_text; -varying vec2 v_tex; -varying vec2 v_fade_tex; -varying float v_gamma_scale; -varying float v_size; +varying vec4 v_data0; +varying vec2 v_data1; void main() { @@ -191,7 +191,12 @@ void main() { - float fontScale = u_is_text ? v_size / 24.0 : v_size; + vec2 tex = v_data0.xy; + vec2 fade_tex = v_data0.zw; + float gamma_scale = v_data1.x; + float size = v_data1.y; + + float fontScale = u_is_text ? size / 24.0 : size; lowp vec4 color = fill_color; highp float gamma = EDGE_GAMMA / (fontScale * u_gamma_scale); @@ -202,9 +207,9 @@ void main() { buff = (6.0 - halo_width / fontScale) / SDF_PX; } - lowp float dist = texture2D(u_texture, v_tex).a; - lowp float fade_alpha = texture2D(u_fadetexture, v_fade_tex).a; - highp float gamma_scaled = gamma * v_gamma_scale; + lowp float dist = texture2D(u_texture, tex).a; + lowp float fade_alpha = texture2D(u_fadetexture, fade_tex).a; + highp float gamma_scaled = gamma * gamma_scale; highp float alpha = smoothstep(buff - gamma_scaled, buff + gamma_scaled, dist) * fade_alpha; gl_FragColor = color * (alpha * opacity); -- cgit v1.2.1 From 951f5997065d39597e2aad1e4586a11053d6fe1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Sun, 4 Jun 2017 02:47:20 +0200 Subject: [core] store vertex attribute binding to prevent duplicate binds We have an "oldBinding" value that we use for checking whether the vertex attribute was already bound to the current VAO, but we never set the state. Additionally, we're also checking whether the previous state was already any binding (optional is set), and don't re-enable the vertex attribute array. Additionally, we now only disable the vertex attribute array when the previous state was in fact an array attribute. We still don't deduplicate constant glVertexAttrib* calls, but that's a little trickier. --- src/mbgl/gl/attribute.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mbgl/gl/attribute.cpp b/src/mbgl/gl/attribute.cpp index eacaa37457..8c52121f6e 100644 --- a/src/mbgl/gl/attribute.cpp +++ b/src/mbgl/gl/attribute.cpp @@ -29,6 +29,7 @@ void VariableAttributeBinding::bind(Context& context, } context.vertexBuffer = vertexBuffer; MBGL_CHECK_ERROR(glEnableVertexAttribArray(location)); + oldBinding = *this; MBGL_CHECK_ERROR(glVertexAttribPointer( location, static_cast(attributeSize), -- cgit v1.2.1 From eaa8f236729814b5edd47a03d5b7e4a25092f044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Sun, 4 Jun 2017 15:45:03 +0200 Subject: [core] only bind uniforms that exist in the program --- src/mbgl/gl/uniform.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mbgl/gl/uniform.hpp b/src/mbgl/gl/uniform.hpp index 34a32aeee9..bb3453b2d8 100644 --- a/src/mbgl/gl/uniform.hpp +++ b/src/mbgl/gl/uniform.hpp @@ -30,7 +30,7 @@ public: class State { public: void operator=(const Value& value) { - if (!current || *current != value.t) { + if (location >= 0 && (!current || *current != value.t)) { current = value.t; bindUniform(location, value.t); } -- cgit v1.2.1 From b141707b8d17fb72276010075fdc75297de8675e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Sun, 4 Jun 2017 15:43:27 +0200 Subject: [core] add shader defines for enabling/disabling attributes/uniforms for DDS --- scripts/generate-shaders.js | 49 ++++++++-- src/mbgl/shaders/circle.cpp | 140 ++++++++++++++++++++++++++-- src/mbgl/shaders/fill.cpp | 40 +++++++- src/mbgl/shaders/fill_extrusion.cpp | 60 +++++++++++- src/mbgl/shaders/fill_extrusion_pattern.cpp | 40 +++++++- src/mbgl/shaders/fill_outline.cpp | 40 +++++++- src/mbgl/shaders/fill_outline_pattern.cpp | 20 +++- src/mbgl/shaders/fill_pattern.cpp | 20 +++- src/mbgl/shaders/line.cpp | 80 +++++++++++++++- src/mbgl/shaders/line_pattern.cpp | 60 +++++++++++- src/mbgl/shaders/line_sdf.cpp | 80 +++++++++++++++- src/mbgl/shaders/symbol_icon.cpp | 20 +++- src/mbgl/shaders/symbol_sdf.cpp | 100 +++++++++++++++++++- 13 files changed, 708 insertions(+), 41 deletions(-) diff --git a/scripts/generate-shaders.js b/scripts/generate-shaders.js index 2813d27365..159817f62f 100755 --- a/scripts/generate-shaders.js +++ b/scripts/generate-shaders.js @@ -69,21 +69,52 @@ ${fragmentPrelude} fragmentSource = fragmentSource.replace(re, (match, operation, precision, type, name) => { fragmentPragmas.add(name); - return operation === "define" ? - `varying ${precision} ${type} ${name};` : - ``; + return operation === "define" ? ` +#ifndef HAS_UNIFORM_u_${name} +varying ${precision} ${type} ${name}; +#else +uniform ${precision} ${type} u_${name}; +#endif +` : ` +#ifdef HAS_UNIFORM_u_${name} + ${precision} ${type} ${name} = u_${name}; +#endif +`; }); vertexSource = vertexSource.replace(re, (match, operation, precision, type, name) => { const a_type = type === "float" ? "vec2" : "vec4"; if (fragmentPragmas.has(name)) { - return operation === "define" ? - `uniform lowp float a_${name}_t;\nattribute ${precision} ${a_type} a_${name};\nvarying ${precision} ${type} ${name};` : - `${name} = unpack_mix_${a_type}(a_${name}, a_${name}_t);`; + return operation === "define" ? ` +#ifdef HAS_UNIFORM_u_${name} +uniform lowp float a_${name}_t; +attribute ${precision} ${a_type} a_${name}; +varying ${precision} ${type} ${name}; +#else +uniform ${precision} ${type} u_${name}; +#endif +` : ` +#ifndef HAS_UNIFORM_u_${name} + ${name} = unpack_mix_${a_type}(a_${name}, a_${name}_t); +#else + ${precision} ${type} ${name} = u_${name}; +#endif +`; } else { - return operation === "define" ? - `uniform lowp float a_${name}_t;\nattribute ${precision} ${a_type} a_${name};` : - `${precision} ${type} ${name} = unpack_mix_${a_type}(a_${name}, a_${name}_t);`; + return operation === "define" ? ` +#ifdef HAS_UNIFORM_u_${name} +uniform lowp float a_${name}_t; +attribute ${precision} ${a_type} a_${name}; +#else +uniform ${precision} ${type} u_${name}; +#endif +` : ` +#ifndef HAS_UNIFORM_u_${name} + ${precision} ${type} ${name} = unpack_mix_${a_type}(a_${name}, a_${name}_t); +#else + ${precision} ${type} ${name} = u_${name}; +#endif +`; } }); diff --git a/src/mbgl/shaders/circle.cpp b/src/mbgl/shaders/circle.cpp index 2ecceeca70..2e0c76122c 100644 --- a/src/mbgl/shaders/circle.cpp +++ b/src/mbgl/shaders/circle.cpp @@ -13,38 +13,108 @@ uniform vec2 u_extrude_scale; attribute vec2 a_pos; + +#ifndef HAS_UNIFORM_u_color uniform lowp float a_color_t; attribute highp vec4 a_color; varying highp vec4 color; +#else +uniform highp vec4 u_color; +#endif + +#ifndef HAS_UNIFORM_u_radius uniform lowp float a_radius_t; attribute mediump vec2 a_radius; varying mediump float radius; +#else +uniform mediump float u_radius; +#endif + +#ifndef HAS_UNIFORM_u_blur uniform lowp float a_blur_t; attribute lowp vec2 a_blur; varying lowp float blur; +#else +uniform lowp float u_blur; +#endif + +#ifndef HAS_UNIFORM_u_opacity uniform lowp float a_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif + +#ifndef HAS_UNIFORM_u_stroke_color uniform lowp float a_stroke_color_t; attribute highp vec4 a_stroke_color; varying highp vec4 stroke_color; +#else +uniform highp vec4 u_stroke_color; +#endif + +#ifndef HAS_UNIFORM_u_stroke_width uniform lowp float a_stroke_width_t; attribute mediump vec2 a_stroke_width; varying mediump float stroke_width; +#else +uniform mediump float u_stroke_width; +#endif + +#ifndef HAS_UNIFORM_u_stroke_opacity uniform lowp float a_stroke_opacity_t; attribute lowp vec2 a_stroke_opacity; varying lowp float stroke_opacity; +#else +uniform lowp float u_stroke_opacity; +#endif varying vec3 v_data; void main(void) { + +#ifndef HAS_UNIFORM_u_color color = unpack_mix_vec4(a_color, a_color_t); +#else + highp vec4 color = u_color; +#endif + +#ifndef HAS_UNIFORM_u_radius radius = unpack_mix_vec2(a_radius, a_radius_t); +#else + mediump float radius = u_radius; +#endif + +#ifndef HAS_UNIFORM_u_blur blur = unpack_mix_vec2(a_blur, a_blur_t); +#else + lowp float blur = u_blur; +#endif + +#ifndef HAS_UNIFORM_u_opacity opacity = unpack_mix_vec2(a_opacity, a_opacity_t); +#else + lowp float opacity = u_opacity; +#endif + +#ifndef HAS_UNIFORM_u_stroke_color stroke_color = unpack_mix_vec4(a_stroke_color, a_stroke_color_t); +#else + highp vec4 stroke_color = u_stroke_color; +#endif + +#ifndef HAS_UNIFORM_u_stroke_width stroke_width = unpack_mix_vec2(a_stroke_width, a_stroke_width_t); +#else + mediump float stroke_width = u_stroke_width; +#endif + +#ifndef HAS_UNIFORM_u_stroke_opacity stroke_opacity = unpack_mix_vec2(a_stroke_opacity, a_stroke_opacity_t); +#else + lowp float stroke_opacity = u_stroke_opacity; +#endif // unencode the extrusion vector that we snuck into the a_pos vector vec2 extrude = vec2(mod(a_pos, 2.0) * 2.0 - 1.0); @@ -69,24 +139,80 @@ void main(void) { )MBGL_SHADER"; const char* circle::fragmentSource = R"MBGL_SHADER( + +#ifndef HAS_UNIFORM_u_color varying highp vec4 color; +#else +uniform highp vec4 u_color; +#endif + +#ifndef HAS_UNIFORM_u_radius varying mediump float radius; +#else +uniform mediump float u_radius; +#endif + +#ifndef HAS_UNIFORM_u_blur varying lowp float blur; +#else +uniform lowp float u_blur; +#endif + +#ifndef HAS_UNIFORM_u_opacity varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif + +#ifndef HAS_UNIFORM_u_stroke_color varying highp vec4 stroke_color; +#else +uniform highp vec4 u_stroke_color; +#endif + +#ifndef HAS_UNIFORM_u_stroke_width varying mediump float stroke_width; +#else +uniform mediump float u_stroke_width; +#endif + +#ifndef HAS_UNIFORM_u_stroke_opacity varying lowp float stroke_opacity; +#else +uniform lowp float u_stroke_opacity; +#endif varying vec3 v_data; void main() { - - - - - - - + +#ifdef HAS_UNIFORM_u_color + highp vec4 color = u_color; +#endif + +#ifdef HAS_UNIFORM_u_radius + mediump float radius = u_radius; +#endif + +#ifdef HAS_UNIFORM_u_blur + lowp float blur = u_blur; +#endif + +#ifdef HAS_UNIFORM_u_opacity + lowp float opacity = u_opacity; +#endif + +#ifdef HAS_UNIFORM_u_stroke_color + highp vec4 stroke_color = u_stroke_color; +#endif + +#ifdef HAS_UNIFORM_u_stroke_width + mediump float stroke_width = u_stroke_width; +#endif + +#ifdef HAS_UNIFORM_u_stroke_opacity + lowp float stroke_opacity = u_stroke_opacity; +#endif vec2 extrude = v_data.xy; float extrude_length = length(extrude); diff --git a/src/mbgl/shaders/fill.cpp b/src/mbgl/shaders/fill.cpp index 0b775273d2..8f5f304014 100644 --- a/src/mbgl/shaders/fill.cpp +++ b/src/mbgl/shaders/fill.cpp @@ -11,28 +11,64 @@ attribute vec2 a_pos; uniform mat4 u_matrix; + +#ifndef HAS_UNIFORM_u_color uniform lowp float a_color_t; attribute highp vec4 a_color; varying highp vec4 color; +#else +uniform highp vec4 u_color; +#endif + +#ifndef HAS_UNIFORM_u_opacity uniform lowp float a_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif void main() { + +#ifndef HAS_UNIFORM_u_color color = unpack_mix_vec4(a_color, a_color_t); +#else + highp vec4 color = u_color; +#endif + +#ifndef HAS_UNIFORM_u_opacity opacity = unpack_mix_vec2(a_opacity, a_opacity_t); +#else + lowp float opacity = u_opacity; +#endif gl_Position = u_matrix * vec4(a_pos, 0, 1); } )MBGL_SHADER"; const char* fill::fragmentSource = R"MBGL_SHADER( + +#ifndef HAS_UNIFORM_u_color varying highp vec4 color; +#else +uniform highp vec4 u_color; +#endif + +#ifndef HAS_UNIFORM_u_opacity varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif void main() { - - + +#ifdef HAS_UNIFORM_u_color + highp vec4 color = u_color; +#endif + +#ifdef HAS_UNIFORM_u_opacity + lowp float opacity = u_opacity; +#endif gl_FragColor = color * opacity; diff --git a/src/mbgl/shaders/fill_extrusion.cpp b/src/mbgl/shaders/fill_extrusion.cpp index ea1c80545e..ad14e4f32e 100644 --- a/src/mbgl/shaders/fill_extrusion.cpp +++ b/src/mbgl/shaders/fill_extrusion.cpp @@ -18,21 +18,51 @@ attribute float a_edgedistance; varying vec4 v_color; + +#ifndef HAS_UNIFORM_u_base uniform lowp float a_base_t; attribute lowp vec2 a_base; varying lowp float base; +#else +uniform lowp float u_base; +#endif + +#ifndef HAS_UNIFORM_u_height uniform lowp float a_height_t; attribute lowp vec2 a_height; varying lowp float height; +#else +uniform lowp float u_height; +#endif + +#ifndef HAS_UNIFORM_u_color uniform lowp float a_color_t; attribute highp vec4 a_color; varying highp vec4 color; +#else +uniform highp vec4 u_color; +#endif void main() { + +#ifndef HAS_UNIFORM_u_base base = unpack_mix_vec2(a_base, a_base_t); +#else + lowp float base = u_base; +#endif + +#ifndef HAS_UNIFORM_u_height height = unpack_mix_vec2(a_height, a_height_t); +#else + lowp float height = u_height; +#endif + +#ifndef HAS_UNIFORM_u_color color = unpack_mix_vec4(a_color, a_color_t); +#else + highp vec4 color = u_color; +#endif base = max(0.0, base); height = max(0.0, height); @@ -76,14 +106,38 @@ void main() { )MBGL_SHADER"; const char* fill_extrusion::fragmentSource = R"MBGL_SHADER( varying vec4 v_color; + +#ifndef HAS_UNIFORM_u_base varying lowp float base; +#else +uniform lowp float u_base; +#endif + +#ifndef HAS_UNIFORM_u_height varying lowp float height; +#else +uniform lowp float u_height; +#endif + +#ifndef HAS_UNIFORM_u_color varying highp vec4 color; +#else +uniform highp vec4 u_color; +#endif void main() { - - - + +#ifdef HAS_UNIFORM_u_base + lowp float base = u_base; +#endif + +#ifdef HAS_UNIFORM_u_height + lowp float height = u_height; +#endif + +#ifdef HAS_UNIFORM_u_color + highp vec4 color = u_color; +#endif gl_FragColor = v_color; diff --git a/src/mbgl/shaders/fill_extrusion_pattern.cpp b/src/mbgl/shaders/fill_extrusion_pattern.cpp index e2de5c20b2..66c24b1bb0 100644 --- a/src/mbgl/shaders/fill_extrusion_pattern.cpp +++ b/src/mbgl/shaders/fill_extrusion_pattern.cpp @@ -30,16 +30,36 @@ varying vec2 v_pos_b; varying vec4 v_lighting; varying float v_directional; + +#ifndef HAS_UNIFORM_u_base uniform lowp float a_base_t; attribute lowp vec2 a_base; varying lowp float base; +#else +uniform lowp float u_base; +#endif + +#ifndef HAS_UNIFORM_u_height uniform lowp float a_height_t; attribute lowp vec2 a_height; varying lowp float height; +#else +uniform lowp float u_height; +#endif void main() { + +#ifndef HAS_UNIFORM_u_base base = unpack_mix_vec2(a_base, a_base_t); +#else + lowp float base = u_base; +#endif + +#ifndef HAS_UNIFORM_u_height height = unpack_mix_vec2(a_height, a_height_t); +#else + lowp float height = u_height; +#endif base = max(0.0, base); height = max(0.0, height); @@ -81,12 +101,28 @@ varying vec2 v_pos_a; varying vec2 v_pos_b; varying vec4 v_lighting; + +#ifndef HAS_UNIFORM_u_base varying lowp float base; +#else +uniform lowp float u_base; +#endif + +#ifndef HAS_UNIFORM_u_height varying lowp float height; +#else +uniform lowp float u_height; +#endif void main() { - - + +#ifdef HAS_UNIFORM_u_base + lowp float base = u_base; +#endif + +#ifdef HAS_UNIFORM_u_height + lowp float height = u_height; +#endif vec2 imagecoord = mod(v_pos_a, 1.0); vec2 pos = mix(u_pattern_tl_a, u_pattern_br_a, imagecoord); diff --git a/src/mbgl/shaders/fill_outline.cpp b/src/mbgl/shaders/fill_outline.cpp index 3e160ac6c2..45bc716be3 100644 --- a/src/mbgl/shaders/fill_outline.cpp +++ b/src/mbgl/shaders/fill_outline.cpp @@ -14,16 +14,36 @@ uniform vec2 u_world; varying vec2 v_pos; + +#ifndef HAS_UNIFORM_u_outline_color uniform lowp float a_outline_color_t; attribute highp vec4 a_outline_color; varying highp vec4 outline_color; +#else +uniform highp vec4 u_outline_color; +#endif + +#ifndef HAS_UNIFORM_u_opacity uniform lowp float a_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif void main() { + +#ifndef HAS_UNIFORM_u_outline_color outline_color = unpack_mix_vec4(a_outline_color, a_outline_color_t); +#else + highp vec4 outline_color = u_outline_color; +#endif + +#ifndef HAS_UNIFORM_u_opacity opacity = unpack_mix_vec2(a_opacity, a_opacity_t); +#else + lowp float opacity = u_opacity; +#endif gl_Position = u_matrix * vec4(a_pos, 0, 1); v_pos = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * u_world; @@ -31,14 +51,30 @@ void main() { )MBGL_SHADER"; const char* fill_outline::fragmentSource = R"MBGL_SHADER( + +#ifndef HAS_UNIFORM_u_outline_color varying highp vec4 outline_color; +#else +uniform highp vec4 u_outline_color; +#endif + +#ifndef HAS_UNIFORM_u_opacity varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif varying vec2 v_pos; void main() { - - + +#ifdef HAS_UNIFORM_u_outline_color + highp vec4 outline_color = u_outline_color; +#endif + +#ifdef HAS_UNIFORM_u_opacity + lowp float opacity = u_opacity; +#endif float dist = length(v_pos - gl_FragCoord.xy); float alpha = smoothstep(1.0, 0.0, dist); diff --git a/src/mbgl/shaders/fill_outline_pattern.cpp b/src/mbgl/shaders/fill_outline_pattern.cpp index 5e38023382..5315709e3a 100644 --- a/src/mbgl/shaders/fill_outline_pattern.cpp +++ b/src/mbgl/shaders/fill_outline_pattern.cpp @@ -23,12 +23,22 @@ varying vec2 v_pos_a; varying vec2 v_pos_b; varying vec2 v_pos; + +#ifndef HAS_UNIFORM_u_opacity uniform lowp float a_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif void main() { + +#ifndef HAS_UNIFORM_u_opacity opacity = unpack_mix_vec2(a_opacity, a_opacity_t); +#else + lowp float opacity = u_opacity; +#endif gl_Position = u_matrix * vec4(a_pos, 0, 1); @@ -52,10 +62,18 @@ varying vec2 v_pos_a; varying vec2 v_pos_b; varying vec2 v_pos; + +#ifndef HAS_UNIFORM_u_opacity varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif void main() { - + +#ifdef HAS_UNIFORM_u_opacity + lowp float opacity = u_opacity; +#endif vec2 imagecoord = mod(v_pos_a, 1.0); vec2 pos = mix(u_pattern_tl_a, u_pattern_br_a, imagecoord); diff --git a/src/mbgl/shaders/fill_pattern.cpp b/src/mbgl/shaders/fill_pattern.cpp index 0357fed40e..dd99e4efff 100644 --- a/src/mbgl/shaders/fill_pattern.cpp +++ b/src/mbgl/shaders/fill_pattern.cpp @@ -21,12 +21,22 @@ attribute vec2 a_pos; varying vec2 v_pos_a; varying vec2 v_pos_b; + +#ifndef HAS_UNIFORM_u_opacity uniform lowp float a_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif void main() { + +#ifndef HAS_UNIFORM_u_opacity opacity = unpack_mix_vec2(a_opacity, a_opacity_t); +#else + lowp float opacity = u_opacity; +#endif gl_Position = u_matrix * vec4(a_pos, 0, 1); @@ -47,10 +57,18 @@ uniform sampler2D u_image; varying vec2 v_pos_a; varying vec2 v_pos_b; + +#ifndef HAS_UNIFORM_u_opacity varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif void main() { - + +#ifdef HAS_UNIFORM_u_opacity + lowp float opacity = u_opacity; +#endif vec2 imagecoord = mod(v_pos_a, 1.0); vec2 pos = mix(u_pattern_tl_a, u_pattern_br_a, imagecoord); diff --git a/src/mbgl/shaders/line.cpp b/src/mbgl/shaders/line.cpp index e101cf6ee1..dce6046257 100644 --- a/src/mbgl/shaders/line.cpp +++ b/src/mbgl/shaders/line.cpp @@ -33,26 +33,76 @@ varying vec2 v_normal; varying vec2 v_width2; varying float v_gamma_scale; + +#ifndef HAS_UNIFORM_u_color uniform lowp float a_color_t; attribute highp vec4 a_color; varying highp vec4 color; +#else +uniform highp vec4 u_color; +#endif + +#ifndef HAS_UNIFORM_u_blur uniform lowp float a_blur_t; attribute lowp vec2 a_blur; varying lowp float blur; +#else +uniform lowp float u_blur; +#endif + +#ifndef HAS_UNIFORM_u_opacity uniform lowp float a_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif + +#ifndef HAS_UNIFORM_u_gapwidth uniform lowp float a_gapwidth_t; attribute mediump vec2 a_gapwidth; +#else +uniform mediump float u_gapwidth; +#endif + +#ifndef HAS_UNIFORM_u_offset uniform lowp float a_offset_t; attribute lowp vec2 a_offset; +#else +uniform lowp float u_offset; +#endif void main() { + +#ifndef HAS_UNIFORM_u_color color = unpack_mix_vec4(a_color, a_color_t); +#else + highp vec4 color = u_color; +#endif + +#ifndef HAS_UNIFORM_u_blur blur = unpack_mix_vec2(a_blur, a_blur_t); +#else + lowp float blur = u_blur; +#endif + +#ifndef HAS_UNIFORM_u_opacity opacity = unpack_mix_vec2(a_opacity, a_opacity_t); +#else + lowp float opacity = u_opacity; +#endif + +#ifndef HAS_UNIFORM_u_gapwidth mediump float gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t); +#else + mediump float gapwidth = u_gapwidth; +#endif + +#ifndef HAS_UNIFORM_u_offset lowp float offset = unpack_mix_vec2(a_offset, a_offset_t); +#else + lowp float offset = u_offset; +#endif vec2 a_extrude = a_data.xy - 128.0; float a_direction = mod(a_data.z, 4.0) - 1.0; @@ -103,18 +153,42 @@ void main() { )MBGL_SHADER"; const char* line::fragmentSource = R"MBGL_SHADER( + +#ifndef HAS_UNIFORM_u_color varying highp vec4 color; +#else +uniform highp vec4 u_color; +#endif + +#ifndef HAS_UNIFORM_u_blur varying lowp float blur; +#else +uniform lowp float u_blur; +#endif + +#ifndef HAS_UNIFORM_u_opacity varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif varying vec2 v_width2; varying vec2 v_normal; varying float v_gamma_scale; void main() { - - - + +#ifdef HAS_UNIFORM_u_color + highp vec4 color = u_color; +#endif + +#ifdef HAS_UNIFORM_u_blur + lowp float blur = u_blur; +#endif + +#ifdef HAS_UNIFORM_u_opacity + lowp float opacity = u_opacity; +#endif // Calculate the distance of the pixel from the line in pixels. float dist = length(v_normal) * v_width2.s; diff --git a/src/mbgl/shaders/line_pattern.cpp b/src/mbgl/shaders/line_pattern.cpp index 79433b53a0..1c07b4f515 100644 --- a/src/mbgl/shaders/line_pattern.cpp +++ b/src/mbgl/shaders/line_pattern.cpp @@ -36,22 +36,62 @@ varying vec2 v_width2; varying float v_linesofar; varying float v_gamma_scale; + +#ifndef HAS_UNIFORM_u_blur uniform lowp float a_blur_t; attribute lowp vec2 a_blur; varying lowp float blur; +#else +uniform lowp float u_blur; +#endif + +#ifndef HAS_UNIFORM_u_opacity uniform lowp float a_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif + +#ifndef HAS_UNIFORM_u_offset uniform lowp float a_offset_t; attribute lowp vec2 a_offset; +#else +uniform lowp float u_offset; +#endif + +#ifndef HAS_UNIFORM_u_gapwidth uniform lowp float a_gapwidth_t; attribute mediump vec2 a_gapwidth; +#else +uniform mediump float u_gapwidth; +#endif void main() { + +#ifndef HAS_UNIFORM_u_blur blur = unpack_mix_vec2(a_blur, a_blur_t); +#else + lowp float blur = u_blur; +#endif + +#ifndef HAS_UNIFORM_u_opacity opacity = unpack_mix_vec2(a_opacity, a_opacity_t); +#else + lowp float opacity = u_opacity; +#endif + +#ifndef HAS_UNIFORM_u_offset lowp float offset = unpack_mix_vec2(a_offset, a_offset_t); +#else + lowp float offset = u_offset; +#endif + +#ifndef HAS_UNIFORM_u_gapwidth mediump float gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t); +#else + mediump float gapwidth = u_gapwidth; +#endif vec2 a_extrude = a_data.xy - 128.0; float a_direction = mod(a_data.z, 4.0) - 1.0; @@ -118,12 +158,28 @@ varying vec2 v_width2; varying float v_linesofar; varying float v_gamma_scale; + +#ifndef HAS_UNIFORM_u_blur varying lowp float blur; +#else +uniform lowp float u_blur; +#endif + +#ifndef HAS_UNIFORM_u_opacity varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif void main() { - - + +#ifdef HAS_UNIFORM_u_blur + lowp float blur = u_blur; +#endif + +#ifdef HAS_UNIFORM_u_opacity + lowp float opacity = u_opacity; +#endif // Calculate the distance of the pixel from the line in pixels. float dist = length(v_normal) * v_width2.s; diff --git a/src/mbgl/shaders/line_sdf.cpp b/src/mbgl/shaders/line_sdf.cpp index 4f6cf814f9..b37bf688d4 100644 --- a/src/mbgl/shaders/line_sdf.cpp +++ b/src/mbgl/shaders/line_sdf.cpp @@ -41,26 +41,76 @@ varying vec2 v_tex_a; varying vec2 v_tex_b; varying float v_gamma_scale; + +#ifndef HAS_UNIFORM_u_color uniform lowp float a_color_t; attribute highp vec4 a_color; varying highp vec4 color; +#else +uniform highp vec4 u_color; +#endif + +#ifndef HAS_UNIFORM_u_blur uniform lowp float a_blur_t; attribute lowp vec2 a_blur; varying lowp float blur; +#else +uniform lowp float u_blur; +#endif + +#ifndef HAS_UNIFORM_u_opacity uniform lowp float a_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif + +#ifndef HAS_UNIFORM_u_gapwidth uniform lowp float a_gapwidth_t; attribute mediump vec2 a_gapwidth; +#else +uniform mediump float u_gapwidth; +#endif + +#ifndef HAS_UNIFORM_u_offset uniform lowp float a_offset_t; attribute lowp vec2 a_offset; +#else +uniform lowp float u_offset; +#endif void main() { + +#ifndef HAS_UNIFORM_u_color color = unpack_mix_vec4(a_color, a_color_t); +#else + highp vec4 color = u_color; +#endif + +#ifndef HAS_UNIFORM_u_blur blur = unpack_mix_vec2(a_blur, a_blur_t); +#else + lowp float blur = u_blur; +#endif + +#ifndef HAS_UNIFORM_u_opacity opacity = unpack_mix_vec2(a_opacity, a_opacity_t); +#else + lowp float opacity = u_opacity; +#endif + +#ifndef HAS_UNIFORM_u_gapwidth mediump float gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t); +#else + mediump float gapwidth = u_gapwidth; +#endif + +#ifndef HAS_UNIFORM_u_offset lowp float offset = unpack_mix_vec2(a_offset, a_offset_t); +#else + lowp float offset = u_offset; +#endif vec2 a_extrude = a_data.xy - 128.0; float a_direction = mod(a_data.z, 4.0) - 1.0; @@ -125,14 +175,38 @@ varying vec2 v_tex_a; varying vec2 v_tex_b; varying float v_gamma_scale; + +#ifndef HAS_UNIFORM_u_color varying highp vec4 color; +#else +uniform highp vec4 u_color; +#endif + +#ifndef HAS_UNIFORM_u_blur varying lowp float blur; +#else +uniform lowp float u_blur; +#endif + +#ifndef HAS_UNIFORM_u_opacity varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif void main() { - - - + +#ifdef HAS_UNIFORM_u_color + highp vec4 color = u_color; +#endif + +#ifdef HAS_UNIFORM_u_blur + lowp float blur = u_blur; +#endif + +#ifdef HAS_UNIFORM_u_opacity + lowp float opacity = u_opacity; +#endif // Calculate the distance of the pixel from the line in pixels. float dist = length(v_normal) * v_width2.s; diff --git a/src/mbgl/shaders/symbol_icon.cpp b/src/mbgl/shaders/symbol_icon.cpp index b6fbed428e..bc570cf361 100644 --- a/src/mbgl/shaders/symbol_icon.cpp +++ b/src/mbgl/shaders/symbol_icon.cpp @@ -19,9 +19,14 @@ uniform mediump float u_size_t; // used to interpolate between zoom stops when s uniform mediump float u_size; // used when size is both zoom and feature constant uniform mediump float u_layout_size; // used when size is feature constant + +#ifndef HAS_UNIFORM_u_opacity uniform lowp float a_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif // matrix is for the vertex position. uniform mat4 u_matrix; @@ -37,7 +42,12 @@ varying vec2 v_tex; varying vec2 v_fade_tex; void main() { + +#ifndef HAS_UNIFORM_u_opacity opacity = unpack_mix_vec2(a_opacity, a_opacity_t); +#else + lowp float opacity = u_opacity; +#endif vec2 a_pos = a_pos_offset.xy; vec2 a_offset = a_pos_offset.zw; @@ -97,13 +107,21 @@ const char* symbol_icon::fragmentSource = R"MBGL_SHADER( uniform sampler2D u_texture; uniform sampler2D u_fadetexture; + +#ifndef HAS_UNIFORM_u_opacity varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif varying vec2 v_tex; varying vec2 v_fade_tex; void main() { - + +#ifdef HAS_UNIFORM_u_opacity + lowp float opacity = u_opacity; +#endif lowp float alpha = texture2D(u_fadetexture, v_fade_tex).a * opacity; gl_FragColor = texture2D(u_texture, v_tex) * alpha; diff --git a/src/mbgl/shaders/symbol_sdf.cpp b/src/mbgl/shaders/symbol_sdf.cpp index 0c39c5f4ac..cce6b769a6 100644 --- a/src/mbgl/shaders/symbol_sdf.cpp +++ b/src/mbgl/shaders/symbol_sdf.cpp @@ -27,21 +27,46 @@ uniform mediump float u_size_t; // used to interpolate between zoom stops when s uniform mediump float u_size; // used when size is both zoom and feature constant uniform mediump float u_layout_size; // used when size is feature constant + +#ifndef HAS_UNIFORM_u_fill_color uniform lowp float a_fill_color_t; attribute highp vec4 a_fill_color; varying highp vec4 fill_color; +#else +uniform highp vec4 u_fill_color; +#endif + +#ifndef HAS_UNIFORM_u_halo_color uniform lowp float a_halo_color_t; attribute highp vec4 a_halo_color; varying highp vec4 halo_color; +#else +uniform highp vec4 u_halo_color; +#endif + +#ifndef HAS_UNIFORM_u_opacity uniform lowp float a_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif + +#ifndef HAS_UNIFORM_u_halo_width uniform lowp float a_halo_width_t; attribute lowp vec2 a_halo_width; varying lowp float halo_width; +#else +uniform lowp float u_halo_width; +#endif + +#ifndef HAS_UNIFORM_u_halo_blur uniform lowp float a_halo_blur_t; attribute lowp vec2 a_halo_blur; varying lowp float halo_blur; +#else +uniform lowp float u_halo_blur; +#endif // matrix is for the vertex position. uniform mat4 u_matrix; @@ -61,11 +86,36 @@ varying vec4 v_data0; varying vec2 v_data1; void main() { + +#ifndef HAS_UNIFORM_u_fill_color fill_color = unpack_mix_vec4(a_fill_color, a_fill_color_t); +#else + highp vec4 fill_color = u_fill_color; +#endif + +#ifndef HAS_UNIFORM_u_halo_color halo_color = unpack_mix_vec4(a_halo_color, a_halo_color_t); +#else + highp vec4 halo_color = u_halo_color; +#endif + +#ifndef HAS_UNIFORM_u_opacity opacity = unpack_mix_vec2(a_opacity, a_opacity_t); +#else + lowp float opacity = u_opacity; +#endif + +#ifndef HAS_UNIFORM_u_halo_width halo_width = unpack_mix_vec2(a_halo_width, a_halo_width_t); +#else + lowp float halo_width = u_halo_width; +#endif + +#ifndef HAS_UNIFORM_u_halo_blur halo_blur = unpack_mix_vec2(a_halo_blur, a_halo_blur_t); +#else + lowp float halo_blur = u_halo_blur; +#endif vec2 a_pos = a_pos_offset.xy; vec2 a_offset = a_pos_offset.zw; @@ -170,11 +220,36 @@ const char* symbol_sdf::fragmentSource = R"MBGL_SHADER( #define EDGE_GAMMA 0.105/DEVICE_PIXEL_RATIO uniform bool u_is_halo; + +#ifndef HAS_UNIFORM_u_fill_color varying highp vec4 fill_color; +#else +uniform highp vec4 u_fill_color; +#endif + +#ifndef HAS_UNIFORM_u_halo_color varying highp vec4 halo_color; +#else +uniform highp vec4 u_halo_color; +#endif + +#ifndef HAS_UNIFORM_u_opacity varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif + +#ifndef HAS_UNIFORM_u_halo_width varying lowp float halo_width; +#else +uniform lowp float u_halo_width; +#endif + +#ifndef HAS_UNIFORM_u_halo_blur varying lowp float halo_blur; +#else +uniform lowp float u_halo_blur; +#endif uniform sampler2D u_texture; uniform sampler2D u_fadetexture; @@ -185,11 +260,26 @@ varying vec4 v_data0; varying vec2 v_data1; void main() { - - - - - + +#ifdef HAS_UNIFORM_u_fill_color + highp vec4 fill_color = u_fill_color; +#endif + +#ifdef HAS_UNIFORM_u_halo_color + highp vec4 halo_color = u_halo_color; +#endif + +#ifdef HAS_UNIFORM_u_opacity + lowp float opacity = u_opacity; +#endif + +#ifdef HAS_UNIFORM_u_halo_width + lowp float halo_width = u_halo_width; +#endif + +#ifdef HAS_UNIFORM_u_halo_blur + lowp float halo_blur = u_halo_blur; +#endif vec2 tex = v_data0.xy; vec2 fade_tex = v_data0.zw; -- cgit v1.2.1 From cf85873f365e5baee73de0fb33113cd7bb134a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Sun, 4 Jun 2017 23:17:59 +0200 Subject: [core] add uniforms to DataDrivenPaintPropertys --- src/mbgl/programs/uniforms.hpp | 14 +++++++++++++- src/mbgl/style/layers/circle_layer_properties.hpp | 15 ++++++++------- .../layers/fill_extrusion_layer_properties.hpp | 7 ++++--- src/mbgl/style/layers/fill_layer_properties.hpp | 7 ++++--- src/mbgl/style/layers/line_layer_properties.hpp | 11 ++++++----- src/mbgl/style/layers/symbol_layer_properties.hpp | 21 +++++++++++---------- src/mbgl/style/paint_property.hpp | 3 ++- 7 files changed, 48 insertions(+), 30 deletions(-) diff --git a/src/mbgl/programs/uniforms.hpp b/src/mbgl/programs/uniforms.hpp index 972405d5a9..60a50a7cb2 100644 --- a/src/mbgl/programs/uniforms.hpp +++ b/src/mbgl/programs/uniforms.hpp @@ -16,7 +16,19 @@ MBGL_DEFINE_UNIFORM_SCALAR(float, u_blur); MBGL_DEFINE_UNIFORM_SCALAR(float, u_zoom); MBGL_DEFINE_UNIFORM_SCALAR(float, u_pitch); MBGL_DEFINE_UNIFORM_SCALAR(float, u_bearing); - +MBGL_DEFINE_UNIFORM_SCALAR(float, u_radius); +MBGL_DEFINE_UNIFORM_SCALAR(float, u_stroke_width); +MBGL_DEFINE_UNIFORM_SCALAR(Color, u_stroke_color); +MBGL_DEFINE_UNIFORM_SCALAR(float, u_stroke_opacity); +MBGL_DEFINE_UNIFORM_SCALAR(Color, u_fill_color); +MBGL_DEFINE_UNIFORM_SCALAR(Color, u_halo_color); +MBGL_DEFINE_UNIFORM_SCALAR(float, u_halo_width); +MBGL_DEFINE_UNIFORM_SCALAR(float, u_halo_blur); +MBGL_DEFINE_UNIFORM_SCALAR(Color, u_outline_color); +MBGL_DEFINE_UNIFORM_SCALAR(float, u_height); +MBGL_DEFINE_UNIFORM_SCALAR(float, u_base); +MBGL_DEFINE_UNIFORM_SCALAR(float, u_gap_width); +MBGL_DEFINE_UNIFORM_SCALAR(float, u_offset); MBGL_DEFINE_UNIFORM_SCALAR(Size, u_world); MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_extrude_scale); diff --git a/src/mbgl/style/layers/circle_layer_properties.hpp b/src/mbgl/style/layers/circle_layer_properties.hpp index 1cb4f5a635..58206c61da 100644 --- a/src/mbgl/style/layers/circle_layer_properties.hpp +++ b/src/mbgl/style/layers/circle_layer_properties.hpp @@ -6,23 +6,24 @@ #include #include #include +#include namespace mbgl { namespace style { -struct CircleRadius : DataDrivenPaintProperty { +struct CircleRadius : DataDrivenPaintProperty { static float defaultValue() { return 5; } }; -struct CircleColor : DataDrivenPaintProperty { +struct CircleColor : DataDrivenPaintProperty { static Color defaultValue() { return Color::black(); } }; -struct CircleBlur : DataDrivenPaintProperty { +struct CircleBlur : DataDrivenPaintProperty { static float defaultValue() { return 0; } }; -struct CircleOpacity : DataDrivenPaintProperty { +struct CircleOpacity : DataDrivenPaintProperty { static float defaultValue() { return 1; } }; @@ -38,15 +39,15 @@ struct CirclePitchScale : PaintProperty { static CirclePitchScaleType defaultValue() { return CirclePitchScaleType::Map; } }; -struct CircleStrokeWidth : DataDrivenPaintProperty { +struct CircleStrokeWidth : DataDrivenPaintProperty { static float defaultValue() { return 0; } }; -struct CircleStrokeColor : DataDrivenPaintProperty { +struct CircleStrokeColor : DataDrivenPaintProperty { static Color defaultValue() { return Color::black(); } }; -struct CircleStrokeOpacity : DataDrivenPaintProperty { +struct CircleStrokeOpacity : DataDrivenPaintProperty { static float defaultValue() { return 1; } }; diff --git a/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp b/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp index c1dd3b079d..f41ce68b94 100644 --- a/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp +++ b/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace mbgl { namespace style { @@ -14,7 +15,7 @@ struct FillExtrusionOpacity : PaintProperty { static float defaultValue() { return 1; } }; -struct FillExtrusionColor : DataDrivenPaintProperty { +struct FillExtrusionColor : DataDrivenPaintProperty { static Color defaultValue() { return Color::black(); } }; @@ -30,11 +31,11 @@ struct FillExtrusionPattern : CrossFadedPaintProperty { static std::string defaultValue() { return ""; } }; -struct FillExtrusionHeight : DataDrivenPaintProperty { +struct FillExtrusionHeight : DataDrivenPaintProperty { static float defaultValue() { return 0; } }; -struct FillExtrusionBase : DataDrivenPaintProperty { +struct FillExtrusionBase : DataDrivenPaintProperty { static float defaultValue() { return 0; } }; diff --git a/src/mbgl/style/layers/fill_layer_properties.hpp b/src/mbgl/style/layers/fill_layer_properties.hpp index f44a18d0e0..ee1e5158ce 100644 --- a/src/mbgl/style/layers/fill_layer_properties.hpp +++ b/src/mbgl/style/layers/fill_layer_properties.hpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace mbgl { namespace style { @@ -14,15 +15,15 @@ struct FillAntialias : PaintProperty { static bool defaultValue() { return true; } }; -struct FillOpacity : DataDrivenPaintProperty { +struct FillOpacity : DataDrivenPaintProperty { static float defaultValue() { return 1; } }; -struct FillColor : DataDrivenPaintProperty { +struct FillColor : DataDrivenPaintProperty { static Color defaultValue() { return Color::black(); } }; -struct FillOutlineColor : DataDrivenPaintProperty { +struct FillOutlineColor : DataDrivenPaintProperty { static Color defaultValue() { return {}; } }; diff --git a/src/mbgl/style/layers/line_layer_properties.hpp b/src/mbgl/style/layers/line_layer_properties.hpp index 724026e3a6..0b234921ad 100644 --- a/src/mbgl/style/layers/line_layer_properties.hpp +++ b/src/mbgl/style/layers/line_layer_properties.hpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace mbgl { namespace style { @@ -30,11 +31,11 @@ struct LineRoundLimit : LayoutProperty { static float defaultValue() { return 1; } }; -struct LineOpacity : DataDrivenPaintProperty { +struct LineOpacity : DataDrivenPaintProperty { static float defaultValue() { return 1; } }; -struct LineColor : DataDrivenPaintProperty { +struct LineColor : DataDrivenPaintProperty { static Color defaultValue() { return Color::black(); } }; @@ -50,15 +51,15 @@ struct LineWidth : PaintProperty { static float defaultValue() { return 1; } }; -struct LineGapWidth : DataDrivenPaintProperty { +struct LineGapWidth : DataDrivenPaintProperty { static float defaultValue() { return 0; } }; -struct LineOffset : DataDrivenPaintProperty> { +struct LineOffset : DataDrivenPaintProperty, uniforms::u_offset> { static float defaultValue() { return 0; } }; -struct LineBlur : DataDrivenPaintProperty { +struct LineBlur : DataDrivenPaintProperty { static float defaultValue() { return 0; } }; diff --git a/src/mbgl/style/layers/symbol_layer_properties.hpp b/src/mbgl/style/layers/symbol_layer_properties.hpp index 42f593890b..5b57175785 100644 --- a/src/mbgl/style/layers/symbol_layer_properties.hpp +++ b/src/mbgl/style/layers/symbol_layer_properties.hpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace mbgl { namespace style { @@ -180,23 +181,23 @@ struct TextOptional : LayoutProperty { static bool defaultValue() { return false; } }; -struct IconOpacity : DataDrivenPaintProperty { +struct IconOpacity : DataDrivenPaintProperty { static float defaultValue() { return 1; } }; -struct IconColor : DataDrivenPaintProperty { +struct IconColor : DataDrivenPaintProperty { static Color defaultValue() { return Color::black(); } }; -struct IconHaloColor : DataDrivenPaintProperty { +struct IconHaloColor : DataDrivenPaintProperty { static Color defaultValue() { return {}; } }; -struct IconHaloWidth : DataDrivenPaintProperty { +struct IconHaloWidth : DataDrivenPaintProperty { static float defaultValue() { return 0; } }; -struct IconHaloBlur : DataDrivenPaintProperty { +struct IconHaloBlur : DataDrivenPaintProperty { static float defaultValue() { return 0; } }; @@ -208,23 +209,23 @@ struct IconTranslateAnchor : PaintProperty { static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; } }; -struct TextOpacity : DataDrivenPaintProperty { +struct TextOpacity : DataDrivenPaintProperty { static float defaultValue() { return 1; } }; -struct TextColor : DataDrivenPaintProperty { +struct TextColor : DataDrivenPaintProperty { static Color defaultValue() { return Color::black(); } }; -struct TextHaloColor : DataDrivenPaintProperty { +struct TextHaloColor : DataDrivenPaintProperty { static Color defaultValue() { return {}; } }; -struct TextHaloWidth : DataDrivenPaintProperty { +struct TextHaloWidth : DataDrivenPaintProperty { static float defaultValue() { return 0; } }; -struct TextHaloBlur : DataDrivenPaintProperty { +struct TextHaloBlur : DataDrivenPaintProperty { static float defaultValue() { return 0; } }; diff --git a/src/mbgl/style/paint_property.hpp b/src/mbgl/style/paint_property.hpp index f1752e69d9..c203083c49 100644 --- a/src/mbgl/style/paint_property.hpp +++ b/src/mbgl/style/paint_property.hpp @@ -92,7 +92,7 @@ public: static constexpr bool IsDataDriven = false; }; -template +template class DataDrivenPaintProperty { public: using ValueType = DataDrivenPropertyValue; @@ -104,6 +104,7 @@ public: using Type = T; using Attribute = A; + using Uniform = U; }; template -- cgit v1.2.1 From a64828218a3934c036f7fb256b6799723c30830a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Sun, 4 Jun 2017 23:58:02 +0200 Subject: [core] add constant DDS values as uniforms --- src/mbgl/programs/program.hpp | 2 +- src/mbgl/programs/symbol_program.hpp | 2 +- src/mbgl/renderer/paint_property_binder.hpp | 23 +++++++++++++++++++++-- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/mbgl/programs/program.hpp b/src/mbgl/programs/program.hpp index 7eec15e755..420d2e1397 100644 --- a/src/mbgl/programs/program.hpp +++ b/src/mbgl/programs/program.hpp @@ -62,7 +62,7 @@ public: std::move(stencilMode), std::move(colorMode), uniformValues - .concat(paintPropertyBinders.uniformValues(currentZoom)), + .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)), LayoutAttributes::allVariableBindings(layoutVertexBuffer) .concat(paintPropertyBinders.attributeBindings(currentProperties)), indexBuffer, diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index 46f532e5c4..1b7232c9e4 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -377,7 +377,7 @@ public: std::move(colorMode), uniformValues .concat(symbolSizeBinder.uniformValues(currentZoom)) - .concat(paintPropertyBinders.uniformValues(currentZoom)), + .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)), LayoutAttributes::allVariableBindings(layoutVertexBuffer) .concat(symbolSizeBinder.attributeBindings(currentSizeValue)) .concat(paintPropertyBinders.attributeBindings(currentProperties)), diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp index 3e53bcc884..a4bea24bbf 100644 --- a/src/mbgl/renderer/paint_property_binder.hpp +++ b/src/mbgl/renderer/paint_property_binder.hpp @@ -88,6 +88,7 @@ public: virtual void upload(gl::Context& context) = 0; virtual AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const = 0; virtual float interpolationFactor(float currentZoom) const = 0; + virtual T uniformValue(const PossiblyEvaluatedPropertyValue& currentValue) const = 0; static std::unique_ptr create(const PossiblyEvaluatedPropertyValue& value, float zoom, T defaultValue); @@ -118,6 +119,10 @@ public: return 0.0f; } + T uniformValue(const PossiblyEvaluatedPropertyValue& currentValue) const override { + return currentValue.constantOr(constant); + } + private: T constant; }; @@ -165,6 +170,11 @@ public: return 0.0f; } + T uniformValue(const PossiblyEvaluatedPropertyValue&) const override { + // Uniform values for vertex attribute arrays are unused. + return {}; + } + private: style::SourceFunction function; T defaultValue; @@ -220,6 +230,11 @@ public: return util::interpolationFactor(1.0f, std::get<0>(coveringRanges), currentZoom); } + T uniformValue(const PossiblyEvaluatedPropertyValue&) const override { + // Uniform values for vertex attribute arrays are unused. + return {}; + } + private: using InnerStops = typename style::CompositeFunction::InnerStops; style::CompositeFunction function; @@ -306,14 +321,18 @@ public: }; } - using Uniforms = gl::Uniforms...>; + using Uniforms = gl::Uniforms..., typename Ps::Uniform...>; using UniformValues = typename Uniforms::Values; - UniformValues uniformValues(float currentZoom) const { + template + UniformValues uniformValues(float currentZoom, const EvaluatedProperties& currentProperties) const { (void)currentZoom; // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56958 return UniformValues { typename InterpolationUniform::Value { binders.template get()->interpolationFactor(currentZoom) + }..., + typename Ps::Uniform::Value { + binders.template get()->uniformValue(currentProperties.template get()) }... }; } -- cgit v1.2.1 From 212ae5273dc3930a035b51c603c540b4f02fa777 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 13 Jun 2017 11:47:39 -0700 Subject: [core] cleanup ProgramParameters --- cmake/core-files.cmake | 1 + src/mbgl/gl/program.hpp | 4 ++-- src/mbgl/programs/program_parameters.cpp | 32 ++++++++++++++++++++++++++++++++ src/mbgl/programs/program_parameters.hpp | 15 +++++++-------- src/mbgl/programs/programs.hpp | 4 ++-- src/mbgl/shaders/shaders.cpp | 22 ++-------------------- src/mbgl/shaders/shaders.hpp | 1 - 7 files changed, 46 insertions(+), 33 deletions(-) create mode 100644 src/mbgl/programs/program_parameters.cpp diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index 4779abba86..069b6cb4c9 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -150,6 +150,7 @@ set(MBGL_CORE_FILES src/mbgl/programs/line_program.cpp src/mbgl/programs/line_program.hpp src/mbgl/programs/program.hpp + src/mbgl/programs/program_parameters.cpp src/mbgl/programs/program_parameters.hpp src/mbgl/programs/programs.hpp src/mbgl/programs/raster_program.cpp diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp index 1b23abe2b1..c36543839c 100644 --- a/src/mbgl/gl/program.hpp +++ b/src/mbgl/gl/program.hpp @@ -55,11 +55,11 @@ public: shaders::vertexSource(programParameters, vertexSource_); const std::string fragmentSource = shaders::fragmentSource(programParameters, fragmentSource_); - const std::string cachePath = - shaders::programCachePath(programParameters, name); const std::string identifier = shaders::programIdentifier(vertexSource, fragmentSource_); + const std::string cachePath = programParameters.cachePath(name); + try { if (auto cachedBinaryProgram = util::readFile(cachePath)) { const BinaryProgram binaryProgram(std::move(*cachedBinaryProgram)); diff --git a/src/mbgl/programs/program_parameters.cpp b/src/mbgl/programs/program_parameters.cpp new file mode 100644 index 0000000000..f9f680ac1e --- /dev/null +++ b/src/mbgl/programs/program_parameters.cpp @@ -0,0 +1,32 @@ +#include + +#include +#include + +namespace mbgl { + +ProgramParameters::ProgramParameters(const float pixelRatio, + const bool overdraw, + std::string cacheDir_) + : defines([&] { + std::ostringstream ss; + ss.imbue(std::locale("C")); + ss.setf(std::ios_base::showpoint); + ss << "#define DEVICE_PIXEL_RATIO " << pixelRatio << std::endl; + if (overdraw) { + ss << "#define OVERDRAW_INSPECTOR" << std::endl; + } + return ss.str(); + }()), + hash(std::hash()(defines)), + cacheDir(std::move(cacheDir_)) { +} + +std::string ProgramParameters::cachePath(const char* name) const { + std::ostringstream ss; + ss << cacheDir << "/com.mapbox.gl.shader." << name << "." << std::setfill('0') + << std::setw(sizeof(size_t) * 2) << std::hex << hash << ".pbf"; + return ss.str(); +} + +} // namespace mbgl diff --git a/src/mbgl/programs/program_parameters.hpp b/src/mbgl/programs/program_parameters.hpp index b91b41f358..420658d089 100644 --- a/src/mbgl/programs/program_parameters.hpp +++ b/src/mbgl/programs/program_parameters.hpp @@ -6,16 +6,15 @@ namespace mbgl { class ProgramParameters { public: - ProgramParameters(float pixelRatio_ = 1.0, - bool overdraw_ = false, - const std::string& cacheDir_ = "") - : pixelRatio(pixelRatio_), overdraw(overdraw_), cacheDir(cacheDir_) { - } + ProgramParameters(float pixelRatio, bool overdraw, std::string cacheDir); - const float pixelRatio; - const bool overdraw; + const std::string defines; + + std::string cachePath(const char* name) const; + +private: + const std::size_t hash; const std::string cacheDir; }; } // namespace mbgl - diff --git a/src/mbgl/programs/programs.hpp b/src/mbgl/programs/programs.hpp index ff6b1cd505..b58d2e3bee 100644 --- a/src/mbgl/programs/programs.hpp +++ b/src/mbgl/programs/programs.hpp @@ -31,8 +31,8 @@ public: symbolIcon(context, programParameters), symbolIconSDF(context, programParameters), symbolGlyph(context, programParameters), - debug(context, ProgramParameters(programParameters.pixelRatio, false, programParameters.cacheDir)), - collisionBox(context, ProgramParameters(programParameters.pixelRatio, false, programParameters.cacheDir)) { + debug(context, programParameters), + collisionBox(context, programParameters) { } CircleProgram circle; diff --git a/src/mbgl/shaders/shaders.cpp b/src/mbgl/shaders/shaders.cpp index 03d796edba..93e273f985 100644 --- a/src/mbgl/shaders/shaders.cpp +++ b/src/mbgl/shaders/shaders.cpp @@ -9,30 +9,12 @@ namespace mbgl { namespace shaders { -static std::string pixelRatioDefine(const ProgramParameters& parameters) { - std::ostringstream pixelRatioSS; - pixelRatioSS.imbue(std::locale("C")); - pixelRatioSS.setf(std::ios_base::showpoint); - pixelRatioSS << parameters.pixelRatio; - return std::string("#define DEVICE_PIXEL_RATIO ") + pixelRatioSS.str() + "\n"; -} - std::string fragmentSource(const ProgramParameters& parameters, const char* fragmentSource) { - std::string source = pixelRatioDefine(parameters) + fragmentPrelude + fragmentSource; - if (parameters.overdraw) { - assert(source.find("#ifdef OVERDRAW_INSPECTOR") != std::string::npos); - source.replace(source.find_first_of('\n'), 1, "\n#define OVERDRAW_INSPECTOR\n"); - } - return source; + return parameters.defines + fragmentPrelude + fragmentSource; } std::string vertexSource(const ProgramParameters& parameters, const char* vertexSource) { - return pixelRatioDefine(parameters) + vertexPrelude + vertexSource; -} - -std::string programCachePath(const ProgramParameters& parameters, const char* name) { - return parameters.cacheDir + "/com.mapbox.gl.shader." + name + - (parameters.overdraw ? ".overdraw.pbf" : ".pbf"); + return parameters.defines + vertexPrelude + vertexSource; } std::string programIdentifier(const std::string& vertexSource, const std::string& fragmentSource) { diff --git a/src/mbgl/shaders/shaders.hpp b/src/mbgl/shaders/shaders.hpp index 126c64bb9e..513d37fa6f 100644 --- a/src/mbgl/shaders/shaders.hpp +++ b/src/mbgl/shaders/shaders.hpp @@ -10,7 +10,6 @@ namespace shaders { std::string fragmentSource(const ProgramParameters&, const char* fragmentSource); std::string vertexSource(const ProgramParameters&, const char* vertexSource); -std::string programCachePath(const ProgramParameters&, const char* name); std::string programIdentifier(const std::string& vertexSource, const std::string& fragmentSource); } // namespace shaders -- cgit v1.2.1 From d618d4a274023257988a91e96ecf794338189bf8 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 5 Jun 2017 12:15:27 -0700 Subject: [core] Dynamic program compilation for data-driven properties --- include/mbgl/map/map.hpp | 2 +- src/mbgl/gl/program.hpp | 11 +++-- src/mbgl/map/map.cpp | 8 ++-- src/mbgl/programs/program.hpp | 35 +++++++++++++++- src/mbgl/programs/program_parameters.cpp | 30 ++++++++++---- src/mbgl/programs/program_parameters.hpp | 14 ++++--- src/mbgl/programs/programs.hpp | 26 ++++++------ src/mbgl/programs/symbol_program.hpp | 3 +- src/mbgl/renderer/paint_property_binder.hpp | 60 ++++++++++++++++++++-------- src/mbgl/renderer/painter.cpp | 2 +- src/mbgl/renderer/painter.hpp | 2 +- src/mbgl/renderer/painter_background.cpp | 4 +- src/mbgl/renderer/painter_circle.cpp | 2 +- src/mbgl/renderer/painter_clipping.cpp | 2 +- src/mbgl/renderer/painter_fill.cpp | 4 +- src/mbgl/renderer/painter_fill_extrusion.cpp | 4 +- src/mbgl/renderer/painter_line.cpp | 2 +- src/mbgl/renderer/painter_symbol.cpp | 2 +- src/mbgl/shaders/shaders.cpp | 4 +- 19 files changed, 148 insertions(+), 69 deletions(-) diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index 8072eda7dd..bbeeeac6cc 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -44,7 +44,7 @@ public: GLContextMode contextMode = GLContextMode::Unique, ConstrainMode constrainMode = ConstrainMode::HeightOnly, ViewportMode viewportMode = ViewportMode::Default, - const std::string& programCacheDir = ""); + const optional& programCacheDir = {}); ~Map(); // Register a callback that will get called (on the render thread) when all resources have diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp index c36543839c..47ad39de7c 100644 --- a/src/mbgl/gl/program.hpp +++ b/src/mbgl/gl/program.hpp @@ -50,7 +50,8 @@ public: const char* vertexSource_, const char* fragmentSource_) { #if MBGL_HAS_BINARY_PROGRAMS - if (!programParameters.cacheDir.empty() && context.supportsProgramBinaries()) { + optional cachePath = programParameters.cachePath(name); + if (cachePath && context.supportsProgramBinaries()) { const std::string vertexSource = shaders::vertexSource(programParameters, vertexSource_); const std::string fragmentSource = @@ -58,10 +59,8 @@ public: const std::string identifier = shaders::programIdentifier(vertexSource, fragmentSource_); - const std::string cachePath = programParameters.cachePath(name); - try { - if (auto cachedBinaryProgram = util::readFile(cachePath)) { + if (auto cachedBinaryProgram = util::readFile(*cachePath)) { const BinaryProgram binaryProgram(std::move(*cachedBinaryProgram)); if (binaryProgram.identifier() == identifier) { return Program { context, binaryProgram }; @@ -82,8 +81,8 @@ public: try { if (const auto binaryProgram = result.template get(context, identifier)) { - util::write_file(cachePath, binaryProgram->serialize()); - Log::Warning(Event::OpenGL, "Caching program in: %s", cachePath.c_str()); + util::write_file(*cachePath, binaryProgram->serialize()); + Log::Warning(Event::OpenGL, "Caching program in: %s", (*cachePath).c_str()); } } catch (std::runtime_error& error) { Log::Warning(Event::OpenGL, "Failed to cache program: %s", error.what()); diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 181370dc14..35457f3a5b 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -58,7 +58,7 @@ public: GLContextMode, ConstrainMode, ViewportMode, - const std::string& programCacheDir); + optional programCacheDir); void onSourceChanged(style::Source&) override; void onUpdate(Update) override; @@ -83,7 +83,7 @@ public: const MapMode mode; const GLContextMode contextMode; const float pixelRatio; - const std::string programCacheDir; + const optional programCacheDir; MapDebugOptions debugOptions { MapDebugOptions::NoDebug }; @@ -116,7 +116,7 @@ Map::Map(Backend& backend, GLContextMode contextMode, ConstrainMode constrainMode, ViewportMode viewportMode, - const std::string& programCacheDir) + const optional& programCacheDir) : impl(std::make_unique(*this, backend, pixelRatio, @@ -139,7 +139,7 @@ Map::Impl::Impl(Map& map_, GLContextMode contextMode_, ConstrainMode constrainMode_, ViewportMode viewportMode_, - const std::string& programCacheDir_) + optional programCacheDir_) : map(map_), observer(backend_), backend(backend_), diff --git a/src/mbgl/programs/program.hpp b/src/mbgl/programs/program.hpp index 420d2e1397..bbe4885745 100644 --- a/src/mbgl/programs/program.hpp +++ b/src/mbgl/programs/program.hpp @@ -9,18 +9,21 @@ #include #include +#include + namespace mbgl { template + class PaintProps> class Program { public: using LayoutAttributes = LayoutAttrs; using LayoutVertex = typename LayoutAttributes::Vertex; + using PaintProperties = PaintProps; using PaintPropertyBinders = typename PaintProperties::Binders; using PaintAttributes = typename PaintPropertyBinders::Attributes; using Attributes = gl::ConcatenateAttributes; @@ -71,4 +74,34 @@ public: } }; +template +class ProgramMap { +public: + using PaintProperties = typename Program::PaintProperties; + using PaintPropertyBinders = typename Program::PaintPropertyBinders; + using Bitset = typename PaintPropertyBinders::Bitset; + + ProgramMap(gl::Context& context_, ProgramParameters parameters_) + : context(context_), + parameters(std::move(parameters_)) { + } + + Program& get(const typename PaintProperties::Evaluated& currentProperties) { + Bitset bits = PaintPropertyBinders::constants(currentProperties); + auto it = programs.find(bits); + if (it != programs.end()) { + return it->second; + } + return programs.emplace(std::piecewise_construct, + std::forward_as_tuple(bits), + std::forward_as_tuple(context, + parameters.withAdditionalDefines(PaintPropertyBinders::defines(currentProperties)))).first->second; + } + +private: + gl::Context& context; + ProgramParameters parameters; + std::unordered_map programs; +}; + } // namespace mbgl diff --git a/src/mbgl/programs/program_parameters.cpp b/src/mbgl/programs/program_parameters.cpp index f9f680ac1e..e76ec4be71 100644 --- a/src/mbgl/programs/program_parameters.cpp +++ b/src/mbgl/programs/program_parameters.cpp @@ -7,7 +7,7 @@ namespace mbgl { ProgramParameters::ProgramParameters(const float pixelRatio, const bool overdraw, - std::string cacheDir_) + optional cacheDir_) : defines([&] { std::ostringstream ss; ss.imbue(std::locale("C")); @@ -18,15 +18,31 @@ ProgramParameters::ProgramParameters(const float pixelRatio, } return ss.str(); }()), - hash(std::hash()(defines)), cacheDir(std::move(cacheDir_)) { } -std::string ProgramParameters::cachePath(const char* name) const { - std::ostringstream ss; - ss << cacheDir << "/com.mapbox.gl.shader." << name << "." << std::setfill('0') - << std::setw(sizeof(size_t) * 2) << std::hex << hash << ".pbf"; - return ss.str(); +const std::string& ProgramParameters::getDefines() const { + return defines; +} + +optional ProgramParameters::cachePath(const char* name) const { + if (!cacheDir) { + return {}; + } else { + std::ostringstream ss; + ss << *cacheDir << "/com.mapbox.gl.shader." << name << "." << std::setfill('0') + << std::setw(sizeof(size_t) * 2) << std::hex << std::hash()(defines) << ".pbf"; + return ss.str(); + } +} + +ProgramParameters ProgramParameters::withAdditionalDefines(const std::vector& additionalDefines) const { + ProgramParameters result(*this); + for (const auto& define : additionalDefines) { + result.defines += define; + result.defines += "\n"; + } + return result; } } // namespace mbgl diff --git a/src/mbgl/programs/program_parameters.hpp b/src/mbgl/programs/program_parameters.hpp index 420658d089..e94e61c217 100644 --- a/src/mbgl/programs/program_parameters.hpp +++ b/src/mbgl/programs/program_parameters.hpp @@ -1,20 +1,24 @@ #pragma once +#include + #include +#include namespace mbgl { class ProgramParameters { public: - ProgramParameters(float pixelRatio, bool overdraw, std::string cacheDir); + ProgramParameters(float pixelRatio, bool overdraw, optional cacheDir); - const std::string defines; + const std::string& getDefines() const; + optional cachePath(const char* name) const; - std::string cachePath(const char* name) const; + ProgramParameters withAdditionalDefines(const std::vector& defines) const; private: - const std::size_t hash; - const std::string cacheDir; + std::string defines; + optional cacheDir; }; } // namespace mbgl diff --git a/src/mbgl/programs/programs.hpp b/src/mbgl/programs/programs.hpp index b58d2e3bee..37ced32745 100644 --- a/src/mbgl/programs/programs.hpp +++ b/src/mbgl/programs/programs.hpp @@ -35,21 +35,21 @@ public: collisionBox(context, programParameters) { } - CircleProgram circle; + ProgramMap circle; ExtrusionTextureProgram extrusionTexture; - FillProgram fill; - FillExtrusionProgram fillExtrusion; - FillExtrusionPatternProgram fillExtrusionPattern; - FillPatternProgram fillPattern; - FillOutlineProgram fillOutline; - FillOutlinePatternProgram fillOutlinePattern; - LineProgram line; - LineSDFProgram lineSDF; - LinePatternProgram linePattern; + ProgramMap fill; + ProgramMap fillExtrusion; + ProgramMap fillExtrusionPattern; + ProgramMap fillPattern; + ProgramMap fillOutline; + ProgramMap fillOutlinePattern; + ProgramMap line; + ProgramMap lineSDF; + ProgramMap linePattern; RasterProgram raster; - SymbolIconProgram symbolIcon; - SymbolSDFIconProgram symbolIconSDF; - SymbolSDFTextProgram symbolGlyph; + ProgramMap symbolIcon; + ProgramMap symbolIconSDF; + ProgramMap symbolGlyph; DebugProgram debug; CollisionBoxProgram collisionBox; diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index 1b7232c9e4..01e95f456d 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -324,7 +324,7 @@ template + class PaintProps> class SymbolProgram { public: using LayoutAttributes = LayoutAttrs; @@ -332,6 +332,7 @@ public: using LayoutAndSizeAttributes = gl::ConcatenateAttributes; + using PaintProperties = PaintProps; using PaintPropertyBinders = typename PaintProperties::Binders; using PaintAttributes = typename PaintPropertyBinders::Attributes; using Attributes = gl::ConcatenateAttributes; diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp index a4bea24bbf..062b77888e 100644 --- a/src/mbgl/renderer/paint_property_binder.hpp +++ b/src/mbgl/renderer/paint_property_binder.hpp @@ -6,6 +6,8 @@ #include #include +#include + namespace mbgl { /* @@ -54,8 +56,7 @@ std::array zoomInterpolatedAttributeValue(const std::array * For _constant_ properties -- those whose value is a constant, or the constant result of evaluating a camera function at a particular camera position -- we - don't need a vertex buffer, and can instead use a constant attribute binding - via the `glVertexAttrib*` family of functions. + don't need a vertex buffer, and instead use a uniform. * For source functions, we use a vertex buffer with a single attribute value, the evaluated result of the source function for the given feature. * For composite functions, we use a vertex buffer with two attributes: min and @@ -66,15 +67,8 @@ std::array zoomInterpolatedAttributeValue(const std::array between the min and max value at the final displayed zoom level. The use of a uniform allows us to cheaply update the value on every frame. - Note that the shader source is the same regardless of the strategy used to bind - the attribute -- in all cases the attribute is declared as a vec2, in order to - support composite min and max values (color attributes use a vec4 with special - packing). When the constant or source function strategies are used, the - interpolation uniform value is set to zero, and the second attribute element is - unused. This differs from the GL JS implementation, which dynamically generates - shader source based on the strategy used. We found that in WebGL, using - `glVertexAttrib*` was unnacceptably slow. Additionally, in GL Native we have - implemented binary shader caching, which works better if the shaders are constant. + Note that the shader source varies depending on whether we're using a uniform or + attribute. Like GL JS, we dynamically compile shaders at runtime to accomodate this. */ template class PaintPropertyBinder { @@ -170,9 +164,13 @@ public: return 0.0f; } - T uniformValue(const PossiblyEvaluatedPropertyValue&) const override { - // Uniform values for vertex attribute arrays are unused. - return {}; + T uniformValue(const PossiblyEvaluatedPropertyValue& currentValue) const override { + if (currentValue.isConstant()) { + return *currentValue.constant(); + } else { + // Uniform values for vertex attribute arrays are unused. + return {}; + } } private: @@ -230,9 +228,13 @@ public: return util::interpolationFactor(1.0f, std::get<0>(coveringRanges), currentZoom); } - T uniformValue(const PossiblyEvaluatedPropertyValue&) const override { - // Uniform values for vertex attribute arrays are unused. - return {}; + T uniformValue(const PossiblyEvaluatedPropertyValue& currentValue) const override { + if (currentValue.isConstant()) { + return *currentValue.constant(); + } else { + // Uniform values for vertex attribute arrays are unused. + return {}; + } } private: @@ -342,6 +344,30 @@ public: return binders.template get

      ()->statistics; } + + using Bitset = std::bitset; + + template + static Bitset constants(const EvaluatedProperties& currentProperties) { + Bitset result; + util::ignore({ + result.set(TypeIndex::value, + currentProperties.template get().isConstant())... + }); + return result; + } + + template + static std::vector defines(const EvaluatedProperties& currentProperties) { + std::vector result; + util::ignore({ + (result.push_back(currentProperties.template get().isConstant() + ? std::string("#define HAS_UNIFORM_") + Ps::Uniform::name() + : std::string()), 0)... + }); + return result; + } + private: Binders binders; }; diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index eed3bfcd8b..da4903864b 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -93,7 +93,7 @@ static gl::VertexVector extrusionTextureVertices() Painter::Painter(gl::Context& context_, const TransformState& state_, float pixelRatio, - const std::string& programCacheDir) + const optional& programCacheDir) : context(context_), state(state_), tileVertexBuffer(context.createVertexBuffer(tileVertices())), diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp index 47b469d971..4658f0c206 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -74,7 +74,7 @@ struct FrameData { class Painter : private util::noncopyable { public: - Painter(gl::Context&, const TransformState&, float pixelRatio, const std::string& programCacheDir); + Painter(gl::Context&, const TransformState&, float pixelRatio, const optional& programCacheDir); ~Painter(); void render(const style::Style&, diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp index 7cd9cbac5f..d01696ee3e 100644 --- a/src/mbgl/renderer/painter_background.cpp +++ b/src/mbgl/renderer/painter_background.cpp @@ -33,7 +33,7 @@ void Painter::renderBackground(PaintParameters& parameters, const RenderBackgrou spriteAtlas->bind(true, context, 0); for (const auto& tileID : util::tileCover(state, state.getIntegerZoom())) { - parameters.programs.fillPattern.draw( + parameters.programs.fillPattern.get(properties).draw( context, gl::Triangles(), depthModeForSublayer(0, gl::DepthMode::ReadOnly), @@ -58,7 +58,7 @@ void Painter::renderBackground(PaintParameters& parameters, const RenderBackgrou } } else { for (const auto& tileID : util::tileCover(state, state.getIntegerZoom())) { - parameters.programs.fill.draw( + parameters.programs.fill.get(properties).draw( context, gl::Triangles(), depthModeForSublayer(0, gl::DepthMode::ReadOnly), diff --git a/src/mbgl/renderer/painter_circle.cpp b/src/mbgl/renderer/painter_circle.cpp index 7c9194f6dd..13acb5f7fe 100644 --- a/src/mbgl/renderer/painter_circle.cpp +++ b/src/mbgl/renderer/painter_circle.cpp @@ -23,7 +23,7 @@ void Painter::renderCircle(PaintParameters& parameters, const CirclePaintProperties::Evaluated& properties = layer.evaluated; const bool scaleWithMap = properties.get() == CirclePitchScaleType::Map; - parameters.programs.circle.draw( + parameters.programs.circle.get(properties).draw( context, gl::Triangles(), depthModeForSublayer(0, gl::DepthMode::ReadOnly), diff --git a/src/mbgl/renderer/painter_clipping.cpp b/src/mbgl/renderer/painter_clipping.cpp index 0d3b5f1504..b3a2d77b1a 100644 --- a/src/mbgl/renderer/painter_clipping.cpp +++ b/src/mbgl/renderer/painter_clipping.cpp @@ -8,7 +8,7 @@ namespace mbgl { void Painter::renderClippingMask(const UnwrappedTileID& tileID, const ClipID& clip) { static const style::FillPaintProperties::Evaluated properties {}; static const FillProgram::PaintPropertyBinders paintAttibuteData(properties, 0); - programs->fill.draw( + programs->fill.get(properties).draw( context, gl::Triangles(), gl::DepthMode::disabled(), diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp index 622f6386ef..e1b59d8839 100644 --- a/src/mbgl/renderer/painter_fill.cpp +++ b/src/mbgl/renderer/painter_fill.cpp @@ -38,7 +38,7 @@ void Painter::renderFill(PaintParameters& parameters, const auto& drawMode, const auto& indexBuffer, const auto& segments) { - program.draw( + program.get(properties).draw( context, drawMode, depthModeForSublayer(sublayer, gl::DepthMode::ReadWrite), @@ -85,7 +85,7 @@ void Painter::renderFill(PaintParameters& parameters, const auto& drawMode, const auto& indexBuffer, const auto& segments) { - program.draw( + program.get(properties).draw( context, drawMode, depthModeForSublayer(sublayer, gl::DepthMode::ReadWrite), diff --git a/src/mbgl/renderer/painter_fill_extrusion.cpp b/src/mbgl/renderer/painter_fill_extrusion.cpp index af98cae569..95617525c7 100644 --- a/src/mbgl/renderer/painter_fill_extrusion.cpp +++ b/src/mbgl/renderer/painter_fill_extrusion.cpp @@ -36,7 +36,7 @@ void Painter::renderFillExtrusion(PaintParameters& parameters, spriteAtlas->bind(true, context, 0); - parameters.programs.fillExtrusionPattern.draw( + parameters.programs.fillExtrusionPattern.get(properties).draw( context, gl::Triangles(), depthModeForSublayer(0, gl::DepthMode::ReadWrite), @@ -62,7 +62,7 @@ void Painter::renderFillExtrusion(PaintParameters& parameters, state.getZoom()); } else { - parameters.programs.fillExtrusion.draw( + parameters.programs.fillExtrusion.get(properties).draw( context, gl::Triangles(), depthModeForSublayer(0, gl::DepthMode::ReadWrite), diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp index 4d7a27d0f6..9152ac8512 100644 --- a/src/mbgl/renderer/painter_line.cpp +++ b/src/mbgl/renderer/painter_line.cpp @@ -24,7 +24,7 @@ void Painter::renderLine(PaintParameters& parameters, const LinePaintProperties::Evaluated& properties = layer.evaluated; auto draw = [&] (auto& program, auto&& uniformValues) { - program.draw( + program.get(properties).draw( context, gl::Triangles(), depthModeForSublayer(0, gl::DepthMode::ReadOnly), diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp index 5a66d1e62f..86b2146b9f 100644 --- a/src/mbgl/renderer/painter_symbol.cpp +++ b/src/mbgl/renderer/painter_symbol.cpp @@ -41,7 +41,7 @@ void Painter::renderSymbol(PaintParameters& parameters, // We clip symbols to their tile extent in still mode. const bool needsClipping = frame.mapMode == MapMode::Still; - program.draw( + program.get(paintProperties).draw( context, gl::Triangles(), values_.pitchAlignment == AlignmentType::Map diff --git a/src/mbgl/shaders/shaders.cpp b/src/mbgl/shaders/shaders.cpp index 93e273f985..31ff405f02 100644 --- a/src/mbgl/shaders/shaders.cpp +++ b/src/mbgl/shaders/shaders.cpp @@ -10,11 +10,11 @@ namespace mbgl { namespace shaders { std::string fragmentSource(const ProgramParameters& parameters, const char* fragmentSource) { - return parameters.defines + fragmentPrelude + fragmentSource; + return parameters.getDefines() + fragmentPrelude + fragmentSource; } std::string vertexSource(const ProgramParameters& parameters, const char* vertexSource) { - return parameters.defines + vertexPrelude + vertexSource; + return parameters.getDefines() + vertexPrelude + vertexSource; } std::string programIdentifier(const std::string& vertexSource, const std::string& fragmentSource) { -- cgit v1.2.1 From d27740650bb71469ab5a2ce5528d71d59f23ad8a Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 13 Jun 2017 11:28:41 -0700 Subject: [core] Don't upload the FrameHistory texture in frames where it's not changing --- src/mbgl/renderer/frame_history.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mbgl/renderer/frame_history.cpp b/src/mbgl/renderer/frame_history.cpp index a933a9004a..35e246f488 100644 --- a/src/mbgl/renderer/frame_history.cpp +++ b/src/mbgl/renderer/frame_history.cpp @@ -39,15 +39,15 @@ void FrameHistory::record(const TimePoint& now, float zoom, const Duration& dura for (int16_t z = 0; z <= 255; z++) { std::chrono::duration timeDiff = now - changeTimes[z]; int32_t opacityChange = (duration == Milliseconds(0) ? 1 : (timeDiff / duration)) * 255; - if (z <= zoomIndex) { - opacities.data[z] = util::min(255, changeOpacities[z] + opacityChange); - } else { - opacities.data[z] = util::max(0, changeOpacities[z] - opacityChange); + uint8_t opacity = z <= zoomIndex + ? util::min(255, changeOpacities[z] + opacityChange) + : util::max(0, changeOpacities[z] - opacityChange); + if (opacities.data[z] != opacity) { + opacities.data[z] = opacity; + dirty = true; } } - dirty = true; - if (zoomIndex != previousZoomIndex) { previousZoomIndex = zoomIndex; previousTime = now; -- cgit v1.2.1 From df3af9738962d377b0b269347a9d91f2173da7e5 Mon Sep 17 00:00:00 2001 From: Jordan Kiley Date: Wed, 14 Jun 2017 11:26:34 -0700 Subject: [ios, macos] Revised descriptions for abstract classes (#9095) Addresses https://github.com/mapbox/mapbox-gl-native/issues/8635 --- platform/darwin/src/MGLForegroundStyleLayer.h | 7 ++++--- platform/darwin/src/MGLMultiPoint.h | 5 +++-- platform/darwin/src/MGLShape.h | 10 +++++----- platform/darwin/src/MGLSource.h | 7 ++++--- platform/darwin/src/MGLStyleLayer.h | 8 ++++---- platform/darwin/src/MGLStyleValue.h | 9 ++++----- platform/darwin/src/MGLTileSource.h | 6 +++--- platform/darwin/src/MGLVectorStyleLayer.h | 8 ++++---- platform/ios/src/MGLUserLocation.h | 2 +- 9 files changed, 32 insertions(+), 30 deletions(-) diff --git a/platform/darwin/src/MGLForegroundStyleLayer.h b/platform/darwin/src/MGLForegroundStyleLayer.h index 16a973630e..bcd323fb99 100644 --- a/platform/darwin/src/MGLForegroundStyleLayer.h +++ b/platform/darwin/src/MGLForegroundStyleLayer.h @@ -11,9 +11,10 @@ NS_ASSUME_NONNULL_BEGIN `MGLForegroundStyleLayer` is an abstract superclass for style layers whose content is defined by an `MGLSource` object. - Do not create instances of this class directly, and do not create your own - subclasses of this class. Instead, create instances of `MGLRasterStyleLayer` - and the concrete subclasses of `MGLVectorStyleLayer`. + Create instances of `MGLRasterStyleLayer` and the concrete subclasses of + `MGLVectorStyleLayer` in order to use `MGLForegroundStyleLayer`'s methods. + Do not create instances of `MGLForegroundStyleLayer` directly, and do not + create your own subclasses of this class. */ MGL_EXPORT @interface MGLForegroundStyleLayer : MGLStyleLayer diff --git a/platform/darwin/src/MGLMultiPoint.h b/platform/darwin/src/MGLMultiPoint.h index 429bbdb22d..ee9eb530a4 100644 --- a/platform/darwin/src/MGLMultiPoint.h +++ b/platform/darwin/src/MGLMultiPoint.h @@ -10,8 +10,9 @@ NS_ASSUME_NONNULL_BEGIN The `MGLMultiPoint` class is an abstract superclass used to define shapes composed of multiple vertices. - You do not create instances of this class directly. Instead, you create - instances of the `MGLPolyline` or `MGLPolygon` classes. However, you can use + Create instances of `MGLPolyline` or `MGLPolygon` in order to use + properties of `MGLMultiPoint`. Do not create instances of `MGLMultiPoint` + directly and do not create your own subclasses of this class. You can use the method and properties of this class to access information about the vertices of the line or polygon. diff --git a/platform/darwin/src/MGLShape.h b/platform/darwin/src/MGLShape.h index bd8b6152d2..e965710552 100644 --- a/platform/darwin/src/MGLShape.h +++ b/platform/darwin/src/MGLShape.h @@ -10,11 +10,11 @@ NS_ASSUME_NONNULL_BEGIN constitute the content of a map – not only the overlays atop the map, but also the content that forms the base map. - You do not create instances of this class directly or create subclasses of this - class. Instead, you create instances of `MGLPointAnnotation`, - `MGLPointCollection`, `MGLPolyline`, `MGLMultiPolyline`, `MGLPolygon`, - `MGLMultiPolygon`, or `MGLShapeCollection`. The shape classes correspond to the - Geometry object + Create instances of `MGLPointAnnotation`, `MGLPointCollection`, `MGLPolyline`, + `MGLMultiPolyline`, `MGLPolygon`, `MGLMultiPolygon`, or `MGLShapeCollection` in + order to use `MGLShape`'s methods. Do not create instances of `MGLShape` directly, + and do not create your own subclasses of this class. The shape classes correspond + to the Geometry object types in the GeoJSON standard, but some have nonstandard names for backwards compatibility. diff --git a/platform/darwin/src/MGLSource.h b/platform/darwin/src/MGLSource.h index 8bf48907cc..151363104e 100644 --- a/platform/darwin/src/MGLSource.h +++ b/platform/darwin/src/MGLSource.h @@ -16,9 +16,10 @@ NS_ASSUME_NONNULL_BEGIN add and remove sources dynamically using methods such as `-[MGLStyle addSource:]` and `-[MGLStyle sourceWithIdentifier:]`. - Do not create instances of this class directly, and do not create your own - subclasses of this class. Instead, create instances of `MGLShapeSource` and the - concrete subclasses of `MGLTileSource`, `MGLVectorSource` and `MGLRasterSource`. + Create instances of `MGLShapeSource` and the concrete subclasses of + `MGLTileSource`, `MGLVectorSource` and `MGLRasterSource` in order to use + `MGLMultiPoint`'s properties and methods. Do not create instances of `MGLSource` + directly, and do not create your own subclasses of this class. */ MGL_EXPORT @interface MGLSource : NSObject diff --git a/platform/darwin/src/MGLStyleLayer.h b/platform/darwin/src/MGLStyleLayer.h index 7d181667d6..b610a27607 100644 --- a/platform/darwin/src/MGLStyleLayer.h +++ b/platform/darwin/src/MGLStyleLayer.h @@ -14,10 +14,10 @@ NS_ASSUME_NONNULL_BEGIN `MGLStyleLayer` object, which you can use to refine the map’s appearance. You can also add and remove style layers dynamically. - Do not create instances of this class directly, and do not create your own - subclasses of this class. Instead, create instances of - `MGLBackgroundStyleLayer` and the concrete subclasses of - `MGLForegroundStyleLayer`. + Create instances of `MGLBackgroundStyleLayer` and the concrete subclasses of + `MGLForegroundStyleLayer` in order to use `MGLStyleLayer`'s properties and methods. + You do not create instances of `MGLStyleLayer` directly, and do not + create your own subclasses of this class. Do not add `MGLStyleLayer` objects to the `style` property of a `MGLMapView` before `-mapView:didFinishLoadingStyle:` is called. diff --git a/platform/darwin/src/MGLStyleValue.h b/platform/darwin/src/MGLStyleValue.h index 2bb3aca4f4..9c9b1dc4d1 100644 --- a/platform/darwin/src/MGLStyleValue.h +++ b/platform/darwin/src/MGLStyleValue.h @@ -239,11 +239,10 @@ MGL_EXPORT defined by an `MGLCameraStyleFunction`, `MGLSourceStyleFunction`, or `MGLCompositeStyleFunction` object. - Do not create instances of this class directly, and do not create your own - subclasses of this class. Instead, use one of the class factory methods in - `MGLStyleValue` to create instances of the following concrete subclasses: - `MGLCameraStyleFunction`, `MGLSourceStyleFunction`, and - `MGLCompositeStyleFunction`. + Create instances of `MGLCameraStyleFunction`, `MGLSourceStyleFunction`, and + `MGLCompositeStyleFunction` in order to use `MGLStyleFunction`'s methods. Do + not create instances of `MGLStyleFunction` directly, and do not create your + own subclasses of this class. The `MGLStyleFunction` class takes a generic parameter `T` that indicates the Foundation class being wrapped by this class. diff --git a/platform/darwin/src/MGLTileSource.h b/platform/darwin/src/MGLTileSource.h index 538b94037e..caeafcd2f6 100644 --- a/platform/darwin/src/MGLTileSource.h +++ b/platform/darwin/src/MGLTileSource.h @@ -140,9 +140,9 @@ typedef NS_ENUM(NSUInteger, MGLTileCoordinateSystem) { Mapbox-hosted tile set, view it in Mapbox Studio’s Tilesets editor. - Do not create instances of this class directly, and do not create your own - subclasses of this class. Instead, create instances of `MGLRasterSource` and - `MGLVectorSource`. + Create instances of `MGLRasterSource` and `MGLVectorSource` in order to use + `MGLTileSource`'s properties and methods. Do not create instances of `MGLTileSource` + directly, and do not create your own subclasses of this class. */ MGL_EXPORT @interface MGLTileSource : MGLSource diff --git a/platform/darwin/src/MGLVectorStyleLayer.h b/platform/darwin/src/MGLVectorStyleLayer.h index c6193e6046..e54a580aed 100644 --- a/platform/darwin/src/MGLVectorStyleLayer.h +++ b/platform/darwin/src/MGLVectorStyleLayer.h @@ -9,10 +9,10 @@ NS_ASSUME_NONNULL_BEGIN `MGLVectorStyleLayer` is an abstract superclass for style layers whose content is defined by an `MGLShapeSource` or `MGLVectorSource` object. - Do not create instances of this class directly, and do not create your own - subclasses of this class. Instead, create instances of the following concrete - subclasses: `MGLCircleStyleLayer`, `MGLFillStyleLayer`, `MGLLineStyleLayer`, - and `MGLSymbolStyleLayer`. + Create instances of `MGLCircleStyleLayer`, `MGLFillStyleLayer`, `MGLLineStyleLayer`, + and `MGLSymbolStyleLayer` in order to use `MGLVectorStyleLayer`'s properties and + methods. Do not create instances of `MGLVectorStyleLayer` directly, and do not + create your own subclasses of this class. */ MGL_EXPORT @interface MGLVectorStyleLayer : MGLForegroundStyleLayer diff --git a/platform/ios/src/MGLUserLocation.h b/platform/ios/src/MGLUserLocation.h index c41c3ee7fd..30bfc592ca 100644 --- a/platform/ios/src/MGLUserLocation.h +++ b/platform/ios/src/MGLUserLocation.h @@ -8,7 +8,7 @@ NS_ASSUME_NONNULL_BEGIN /** The MGLUserLocation class defines a specific type of annotation that identifies the user’s current location. You do not create instances of this class - directly. Instead, you retrieve an existing MGLUserLocation object from the + directly. Instead, you retrieve an existing `MGLUserLocation` object from the `userLocation` property of the map view displayed in your application. */ @interface MGLUserLocation : NSObject -- cgit v1.2.1 From 6cba15f3a964b39184651dae32cccf32c8d706d0 Mon Sep 17 00:00:00 2001 From: Jason Wray Date: Wed, 14 Jun 2017 03:01:02 -0400 Subject: [ios] Remove old Fabric build infrastructure --- Makefile | 5 - platform/ios/DEVELOPING.md | 1 - platform/ios/scripts/deploy-packages.sh | 1 - platform/ios/scripts/release-fabric.sh | 37 ------- platform/ios/scripts/validate-fabric-zip.sh | 131 ------------------------- platform/ios/scripts/validate-framework-zip.sh | 131 +++++++++++++++++++++++++ 6 files changed, 131 insertions(+), 175 deletions(-) delete mode 100755 platform/ios/scripts/release-fabric.sh delete mode 100755 platform/ios/scripts/validate-fabric-zip.sh create mode 100755 platform/ios/scripts/validate-framework-zip.sh diff --git a/Makefile b/Makefile index abccb306a6..1a635cdd3c 100644 --- a/Makefile +++ b/Makefile @@ -253,11 +253,6 @@ iframework: $(IOS_PROJ_PATH) FORMAT=dynamic BUILD_DEVICE=$(BUILD_DEVICE) SYMBOLS=$(SYMBOLS) \ ./platform/ios/scripts/package.sh -.PHONY: ifabric -ifabric: $(IOS_PROJ_PATH) - FORMAT=static BUILD_DEVICE=$(BUILD_DEVICE) SYMBOLS=NO SELF_CONTAINED=YES \ - ./platform/ios/scripts/package.sh - .PHONY: ideploy ideploy: caffeinate -i ./platform/ios/scripts/deploy-packages.sh diff --git a/platform/ios/DEVELOPING.md b/platform/ios/DEVELOPING.md index 83064fbbd8..bcb837c243 100644 --- a/platform/ios/DEVELOPING.md +++ b/platform/ios/DEVELOPING.md @@ -46,7 +46,6 @@ Build and package the SDK by using one of the following commands: * `make iframework` builds a dynamic framework in the Debug configuration for devices and the iOS Simulator. The CocoaPods pod downloads the output of this target. * `make ipackage-sim` builds a dynamic framework in the Debug configuration for the iOS simulator. This is the fastest target. * `make ipackage-strip` builds both dynamic and static frameworks in the Debug configuration, stripped of debug symbols, for devices and the iOS Simulator. -* `make ifabric` builds a special static framework for compatibility with the Fabric Mac application. You can customize the build output by passing the following arguments into the `make` invocation: diff --git a/platform/ios/scripts/deploy-packages.sh b/platform/ios/scripts/deploy-packages.sh index 4a3c73295a..bdc946497d 100755 --- a/platform/ios/scripts/deploy-packages.sh +++ b/platform/ios/scripts/deploy-packages.sh @@ -112,6 +112,5 @@ buildPackageStyle "ipackage" "symbols" buildPackageStyle "ipackage-strip" buildPackageStyle "iframework" "symbols-dynamic" buildPackageStyle "iframework SYMBOLS=NO" "dynamic" -buildPackageStyle "ifabric" "fabric" step "Finished deploying ${PUBLISH_VERSION} in $(($SECONDS / 60)) minutes and $(($SECONDS % 60)) seconds" diff --git a/platform/ios/scripts/release-fabric.sh b/platform/ios/scripts/release-fabric.sh deleted file mode 100755 index a523705b7b..0000000000 --- a/platform/ios/scripts/release-fabric.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail -set -u - -export PUBLISH_VERSION=$1 -export BINARY_DIRECTORY=$2 -export ZIP_OUTPUT=mapbox-ios-sdk-${PUBLISH_VERSION}-fabric -export FILE_NAME=mapbox-ios-sdk-${PUBLISH_VERSION}-fabric.zip -export ZIP_ARCHIVE_PATH=${BINARY_DIRECTORY}/${FILE_NAME} -export BUNDLE_ID="com.mapbox.sdk.ios" - -echo "Downloading ${FILE_NAME}:" -wget -P ${BINARY_DIRECTORY} http://mapbox.s3.amazonaws.com/mapbox-gl-native/ios/builds/${FILE_NAME} - -echo "Extracting ${ZIP_ARCHIVE_PATH} to ${BINARY_DIRECTORY}/${ZIP_OUTPUT}" -unzip -q ${ZIP_ARCHIVE_PATH} -d ${BINARY_DIRECTORY}/${ZIP_OUTPUT} -ditto ${BINARY_DIRECTORY}/${ZIP_OUTPUT}/static/Mapbox.framework ${BINARY_DIRECTORY}/Mapbox.framework - -echo "Zipping framework:" -cd ${BINARY_DIRECTORY} -zip -q -r Mapbox.framework.zip Mapbox.framework -cd $OLDPWD - -echo "Validating framework:" -./validate-fabric-zip.sh ${BINARY_DIRECTORY}/Mapbox.framework.zip - -echo "Uploading ${BINARY_DIRECTORY}/Mapbox.framework.zip to https://kits.fabric.io/manage-api/v1/kit-releases/ios/$BUNDLE_ID/$PUBLISH_VERSION with key ${FABRIC_KIT_API_KEY}" -curl --fail -v -X PUT -H "X-FabricKits-ApiKey: ${FABRIC_KIT_API_KEY}" \ - -F "release_artifact=@${BINARY_DIRECTORY}/Mapbox.framework.zip;type=application/octet-stream" \ - https://kits.fabric.io/manage-api/v1/kit-releases/ios/$BUNDLE_ID/$PUBLISH_VERSION - -echo "Cleaning up" -rm -r #{BINARY_DIRECTORY} - -echo "Done" diff --git a/platform/ios/scripts/validate-fabric-zip.sh b/platform/ios/scripts/validate-fabric-zip.sh deleted file mode 100755 index 2cd1e90ee7..0000000000 --- a/platform/ios/scripts/validate-fabric-zip.sh +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env bash -# Created by Cory Dolphin on 03/21/16. -# Copyright (c) 2016 Twitter. All rights reserved. - -# Verifies a zip archive submission of SDKs passes basic static checks for format and contents. -# This test is likely to generate false positives, e.g. even if your SDK passes this, you still must -# test integration of your code fully. - -# Usage: $ ./validate_zip.sh - -set -e - -if [ ! -f "$1" ]; then - printf "No file found at ${1}\n" - printf "Usage: $ ./validate_zip.sh \n"; exit 1; -fi - -function verifyFramework() { - # set -x - local FRAMEWORK_PATH=$1 - local FRAMEWORK_NAME=$(basename $FRAMEWORK_PATH) - local PRODUCT="${FRAMEWORK_NAME%.*}" - local BINARY_PATH="${FRAMEWORK_PATH}/${PRODUCT}" - local HEADER_PATH="${FRAMEWORK_PATH}/Headers" - printf "Found $FRAMEWORK_NAME. Verifying...\n" - - local MODULE_MAP=( $(find $FRAMEWORK_PATH -name "*.modulemap") ) - if [[ -z "$MODULE_MAP" ]]; then - printf "ERROR: No modulemap found in $FRAMEWORK_NAME\n"; - exit 3; - fi - printf "$FRAMEWORK_NAME contains modulemap: ✓\n" - - # Verify there is a modulemap so Swift can use the framework - if grep -q "link" "$MODULE_MAP"; then - printf "$FRAMEWORK_NAME modulemap contains dependent system frameworks ✓\n" - else - printf "Warning: ${FRAMEWORK_NAME} does not list any system library dependencies. Double check all dependent frameworks and libraries are listed. \n"; - fi - - # Verify there is at least one header listed in the module map - if grep -q ".*.h" "$MODULE_MAP"; then - printf "$FRAMEWORK_NAME modulemap contains headers ✓\n"; - else - printf "Error: ${FRAMEWORK_NAME} does not list any headers in the modulemap\n"; - exit 4; - fi - - # Verify there is at least a headers folder - if [[ ! -d "$HEADER_PATH" ]]; then - printf "ERROR: Headers not not found in ${FRAMEWORK_NAME}\n"; - exit 5; - fi - - # Verify the static lib at least has simulator and the two common ARM architectures - local PRESENT_ARCHITECTURES=$( xcrun lipo -info "${BINARY_PATH}" ) - for arch in "armv7" "arm64" "i386" "x86_64"; do - if [[ ! $PRESENT_ARCHITECTURES == *$arch* ]]; then - printf "ERROR: Architecture ${arch} not found in ${FRAMEWORK_NAME}\n"; - exit 6; - fi - done - printf "$FRAMEWORK_NAME contains simulator and device architectures: ✓\n" - - # Verify there are at least some bitcode segments in the rmv7 and arm64 slices - # Note, this is not conclusive, it is possible some symbols are missing the segment - for arch in "armv7" "arm64"; do - local SYMBOLS=$(otool -l -arch "${arch}" "${BINARY_PATH}") - if [[ ! $SYMBOLS == *"LLVM"* ]]; then - printf "ERROR: Bitcode segments not found in ${FRAMEWORK_NAME}. Users will fail to archive their builds \n"; - exit 7; - fi - done - printf "$FRAMEWORK_NAME contains bitcode: ✓\n" - - # Verify there is a plist file - local PLIST_PATH=( $(find $FRAMEWORK_PATH -name Info.plist) ) - if [[ -z "$PLIST_PATH" ]]; then - printf "ERROR: No Info.plist found in $FRAMEWORK_NAME\n" - exit 8; - fi - printf "$FRAMEWORK_NAME contains Info.plist: ✓\n" - - # Verify there is a bundle identifier in Info.plist - # And verify it does not contain any vestigial string templating - local BUNDLE_NAME=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "${PLIST_PATH}") - if [[ -z "$BUNDLE_NAME" ]]; then - printf "ERROR: Info.plist not found in $FRAMEWORK_NAME or CFBundleIdentifier not set\n"; - exit 9; - elif [[ "$BUNDLE_NAME" == *"$"* ]]; then - printf "ERROR: CFBundleIdentifier is invalid: $BUNDLE_NAME\n"; - exit 10; - else - printf "$FRAMEWORK_NAME has bundle: $BUNDLE_NAME ✓\n" - fi - - # Verify there is a bundle version in the Info.plist - local BUNDLE_VERSION=$(/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" "${PLIST_PATH}") - if [[ -z "$BUNDLE_VERSION" ]]; then - printf "ERROR: No CFBundleShortVersionString found in $FRAMEWORK_NAME\n"; - exit 11; - else - printf "$FRAMEWORK_NAME has version: $BUNDLE_VERSION ✓\n" - fi - - printf "===========================================\n" - printf "Analyzed $PRODUCT version $BUNDLE_VERSION. \n" - printf "Basic static verifications passed. 🚀🚀🚀 \n" - printf "Please perform final verification testing \n\n" -} - -# Extract the zip archive to a temporary location -TEMP_DIR=$(mktemp -d /tmp/fabric_framework_validation.XXXXX) -printf "Unzipping $(basename "$1") to $TEMP_DIR\n" -unzip "$1" -d "$TEMP_DIR" &> /dev/null - -# Find frameworks and ensure they are at the top level, e.g. NOT nested within a sub directory -printf "Scanning for frameworks...\n" -FRAMEWORKS=( $(find "$TEMP_DIR" -name "*.framework" -maxdepth 1) ) -if [ -z "$FRAMEWORKS" ]; then - printf "ERROR: No frameworks found at the top level within the zip archive."; - exit 2; -fi - -# Verify each framework found individually -for framework in "${FRAMEWORKS[@]}"; do - verifyFramework "$framework" - printf "" -done - -rm -r "$TEMP_DIR" diff --git a/platform/ios/scripts/validate-framework-zip.sh b/platform/ios/scripts/validate-framework-zip.sh new file mode 100755 index 0000000000..2cd1e90ee7 --- /dev/null +++ b/platform/ios/scripts/validate-framework-zip.sh @@ -0,0 +1,131 @@ +#!/usr/bin/env bash +# Created by Cory Dolphin on 03/21/16. +# Copyright (c) 2016 Twitter. All rights reserved. + +# Verifies a zip archive submission of SDKs passes basic static checks for format and contents. +# This test is likely to generate false positives, e.g. even if your SDK passes this, you still must +# test integration of your code fully. + +# Usage: $ ./validate_zip.sh + +set -e + +if [ ! -f "$1" ]; then + printf "No file found at ${1}\n" + printf "Usage: $ ./validate_zip.sh \n"; exit 1; +fi + +function verifyFramework() { + # set -x + local FRAMEWORK_PATH=$1 + local FRAMEWORK_NAME=$(basename $FRAMEWORK_PATH) + local PRODUCT="${FRAMEWORK_NAME%.*}" + local BINARY_PATH="${FRAMEWORK_PATH}/${PRODUCT}" + local HEADER_PATH="${FRAMEWORK_PATH}/Headers" + printf "Found $FRAMEWORK_NAME. Verifying...\n" + + local MODULE_MAP=( $(find $FRAMEWORK_PATH -name "*.modulemap") ) + if [[ -z "$MODULE_MAP" ]]; then + printf "ERROR: No modulemap found in $FRAMEWORK_NAME\n"; + exit 3; + fi + printf "$FRAMEWORK_NAME contains modulemap: ✓\n" + + # Verify there is a modulemap so Swift can use the framework + if grep -q "link" "$MODULE_MAP"; then + printf "$FRAMEWORK_NAME modulemap contains dependent system frameworks ✓\n" + else + printf "Warning: ${FRAMEWORK_NAME} does not list any system library dependencies. Double check all dependent frameworks and libraries are listed. \n"; + fi + + # Verify there is at least one header listed in the module map + if grep -q ".*.h" "$MODULE_MAP"; then + printf "$FRAMEWORK_NAME modulemap contains headers ✓\n"; + else + printf "Error: ${FRAMEWORK_NAME} does not list any headers in the modulemap\n"; + exit 4; + fi + + # Verify there is at least a headers folder + if [[ ! -d "$HEADER_PATH" ]]; then + printf "ERROR: Headers not not found in ${FRAMEWORK_NAME}\n"; + exit 5; + fi + + # Verify the static lib at least has simulator and the two common ARM architectures + local PRESENT_ARCHITECTURES=$( xcrun lipo -info "${BINARY_PATH}" ) + for arch in "armv7" "arm64" "i386" "x86_64"; do + if [[ ! $PRESENT_ARCHITECTURES == *$arch* ]]; then + printf "ERROR: Architecture ${arch} not found in ${FRAMEWORK_NAME}\n"; + exit 6; + fi + done + printf "$FRAMEWORK_NAME contains simulator and device architectures: ✓\n" + + # Verify there are at least some bitcode segments in the rmv7 and arm64 slices + # Note, this is not conclusive, it is possible some symbols are missing the segment + for arch in "armv7" "arm64"; do + local SYMBOLS=$(otool -l -arch "${arch}" "${BINARY_PATH}") + if [[ ! $SYMBOLS == *"LLVM"* ]]; then + printf "ERROR: Bitcode segments not found in ${FRAMEWORK_NAME}. Users will fail to archive their builds \n"; + exit 7; + fi + done + printf "$FRAMEWORK_NAME contains bitcode: ✓\n" + + # Verify there is a plist file + local PLIST_PATH=( $(find $FRAMEWORK_PATH -name Info.plist) ) + if [[ -z "$PLIST_PATH" ]]; then + printf "ERROR: No Info.plist found in $FRAMEWORK_NAME\n" + exit 8; + fi + printf "$FRAMEWORK_NAME contains Info.plist: ✓\n" + + # Verify there is a bundle identifier in Info.plist + # And verify it does not contain any vestigial string templating + local BUNDLE_NAME=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "${PLIST_PATH}") + if [[ -z "$BUNDLE_NAME" ]]; then + printf "ERROR: Info.plist not found in $FRAMEWORK_NAME or CFBundleIdentifier not set\n"; + exit 9; + elif [[ "$BUNDLE_NAME" == *"$"* ]]; then + printf "ERROR: CFBundleIdentifier is invalid: $BUNDLE_NAME\n"; + exit 10; + else + printf "$FRAMEWORK_NAME has bundle: $BUNDLE_NAME ✓\n" + fi + + # Verify there is a bundle version in the Info.plist + local BUNDLE_VERSION=$(/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" "${PLIST_PATH}") + if [[ -z "$BUNDLE_VERSION" ]]; then + printf "ERROR: No CFBundleShortVersionString found in $FRAMEWORK_NAME\n"; + exit 11; + else + printf "$FRAMEWORK_NAME has version: $BUNDLE_VERSION ✓\n" + fi + + printf "===========================================\n" + printf "Analyzed $PRODUCT version $BUNDLE_VERSION. \n" + printf "Basic static verifications passed. 🚀🚀🚀 \n" + printf "Please perform final verification testing \n\n" +} + +# Extract the zip archive to a temporary location +TEMP_DIR=$(mktemp -d /tmp/fabric_framework_validation.XXXXX) +printf "Unzipping $(basename "$1") to $TEMP_DIR\n" +unzip "$1" -d "$TEMP_DIR" &> /dev/null + +# Find frameworks and ensure they are at the top level, e.g. NOT nested within a sub directory +printf "Scanning for frameworks...\n" +FRAMEWORKS=( $(find "$TEMP_DIR" -name "*.framework" -maxdepth 1) ) +if [ -z "$FRAMEWORKS" ]; then + printf "ERROR: No frameworks found at the top level within the zip archive."; + exit 2; +fi + +# Verify each framework found individually +for framework in "${FRAMEWORKS[@]}"; do + verifyFramework "$framework" + printf "" +done + +rm -r "$TEMP_DIR" -- cgit v1.2.1 From 67c09b18e491e66e2ba058498b8f3b44e49d0105 Mon Sep 17 00:00:00 2001 From: Fabian Guerra Soto Date: Fri, 16 Jun 2017 06:41:51 -0700 Subject: MGLLight autogenerate scripts (#9260) * [ios, macos] Add the MGLLight generation templates * [ios, macos] Add MGLLight generation script * [ios, macos] Add the auto-generation script for MGLLight.mm * [ios, macos] Add the auto-generation script for MGLLightTest.mm * [core] Add const to Position constructor. * [ios, macos] Simplify MGLLightTest.mm autogenerate script. --- include/mbgl/style/position.hpp | 2 +- platform/darwin/scripts/generate-style-code.js | 39 ++++- .../darwin/scripts/style-spec-overrides-v8.json | 6 + platform/darwin/src/MGLLight.h | 118 +++++++++++--- platform/darwin/src/MGLLight.h.ejs | 100 ++++++++++++ platform/darwin/src/MGLLight.mm | 41 ++--- platform/darwin/src/MGLLight.mm.ejs | 114 +++++++++++++ platform/darwin/test/MGLLightTest.mm | 181 ++++++--------------- platform/darwin/test/MGLLightTest.mm.ejs | 92 +++++++++++ 9 files changed, 518 insertions(+), 175 deletions(-) create mode 100644 platform/darwin/src/MGLLight.h.ejs create mode 100644 platform/darwin/src/MGLLight.mm.ejs create mode 100644 platform/darwin/test/MGLLightTest.mm.ejs diff --git a/include/mbgl/style/position.hpp b/include/mbgl/style/position.hpp index 3be8d1c55e..078e62bda8 100644 --- a/include/mbgl/style/position.hpp +++ b/include/mbgl/style/position.hpp @@ -9,7 +9,7 @@ namespace style { class Position { public: Position() = default; - Position(std::array& position_) + Position(const std::array& position_) : radial(position_[0]), azimuthal(position_[1]), polar(position_[2]) { calculateCartesian(); }; diff --git a/platform/darwin/scripts/generate-style-code.js b/platform/darwin/scripts/generate-style-code.js index 7efc8d441c..5a4936c0ee 100644 --- a/platform/darwin/scripts/generate-style-code.js +++ b/platform/darwin/scripts/generate-style-code.js @@ -149,6 +149,9 @@ global.mbglTestValue = function (property, layerType) { type = 'Alignment'; } let value = camelize(_.last(_.keys(property.values))); + if (property['light-property']) { + return `mbgl::style::Light${type}Type::${value}`; + } return `mbgl::style::${type}Type::${value}`; } case 'color': @@ -225,6 +228,9 @@ global.propertyDoc = function (propertyName, property, layerType, kind) { let doc = property.doc.replace(/`([^`]+?)` is set to `([^`]+?)`/g, function (m, peerPropertyName, propertyValue, offset, str) { let otherProperty = camelizeWithLeadingLowercase(peerPropertyName); let otherValue = objCType(layerType, peerPropertyName) + camelize(propertyValue); + if (property.type == 'array' && kind == 'light') { + otherValue = propertyValue; + } return '`' + `${otherProperty}` + '` is set to `' + `${otherValue}` + '`'; }); // Match references to our own property values. @@ -256,7 +262,7 @@ global.propertyDoc = function (propertyName, property, layerType, kind) { if (kind !== 'enum') { if ('default' in property) { doc += `\n\nThe default value of this property is ${propertyDefault(property, layerType)}.`; - if (!property.required) { + if (!property.required && kind != 'light') { doc += ' Set this property to `nil` to reset it to the default value.'; } } @@ -348,6 +354,8 @@ global.describeValue = function (value, property, layerType) { let objCType = global.objCType(layerType, property.name); return `${conjunction}\`${objCType}${camelize(possibleValue)}\``; }).join(separator); + } else if (property['light-property']) { + displayValue = `\`${prefix}Light${camelize(property.name)}${camelize(value)}\``; } else { let objCType = global.objCType(layerType, property.name); displayValue = `\`${objCType}${camelize(value)}\``; @@ -382,6 +390,8 @@ global.describeValue = function (value, property, layerType) { case 'offset': case 'translate': return 'an `NSValue` object containing a `CGVector` struct set to' + ` ${value[0]}${units} rightward and ${value[1]}${units} downward`; + case 'position': + return 'an `MGLSphericalPosition` struct set to' + ` ${value[0]} radial, ${value[1]} azimuthal and ${value[2]} polar`; default: return 'the array `' + value.join('`, `') + '`'; } @@ -418,6 +428,7 @@ global.propertyType = function (property) { return 'NSArray *'; case 'padding': return 'NSValue *'; + case 'position': case 'offset': case 'translate': return 'NSValue *'; @@ -457,6 +468,8 @@ global.valueTransformerArguments = function (property) { return ['std::vector', objCType, 'std::string']; case 'padding': return ['std::array', objCType]; + case 'position': + return ['mbgl::style::Position', objCType]; case 'offset': case 'translate': return ['std::array', objCType]; @@ -478,6 +491,9 @@ global.mbglType = function(property) { return 'std::string'; case 'enum': { let type = camelize(originalPropertyName(property)); + if (property['light-property']) { + return `mbgl::style::Light${type}Type`; + } if (/-translate-anchor$/.test(originalPropertyName(property))) { type = 'TranslateAnchor'; } @@ -499,6 +515,8 @@ global.mbglType = function(property) { case 'offset': case 'translate': return 'std::array'; + case 'position': + return 'mbgl::style::Position'; default: throw new Error(`unknown array type for ${property.name}`); } @@ -519,6 +537,17 @@ global.setSourceLayer = function() { return `_layer->setSourceLayer(sourceLayer.UTF8String);` }; +const lightProperties = Object.keys(spec['light']).reduce((memo, name) => { + var property = spec['light'][name]; + property.name = name; + property['light-property'] = true; + memo.push(property); + return memo; +}, []); + +const lightDoc = spec['light-cocoa-doc']; +const lightType = 'light'; + const layerH = ejs.compile(fs.readFileSync('platform/darwin/src/MGLStyleLayer.h.ejs', 'utf8'), { strict: true }); const layerM = ejs.compile(fs.readFileSync('platform/darwin/src/MGLStyleLayer.mm.ejs', 'utf8'), { strict: true}); const testLayers = ejs.compile(fs.readFileSync('platform/darwin/test/MGLStyleLayerTests.mm.ejs', 'utf8'), { strict: true}); @@ -526,6 +555,14 @@ const forStyleAuthorsMD = ejs.compile(fs.readFileSync('platform/darwin/docs/guid const ddsGuideMD = ejs.compile(fs.readFileSync('platform/darwin/docs/guides/Using Style Functions at Runtime.md.ejs', 'utf8'), { strict: true }); const templatesMD = ejs.compile(fs.readFileSync('platform/darwin/docs/guides/Tile URL Templates.md.ejs', 'utf8'), { strict: true }); +const lightH = ejs.compile(fs.readFileSync('platform/darwin/src/MGLLight.h.ejs', 'utf8'), {strict: true}); +const lightM = ejs.compile(fs.readFileSync('platform/darwin/src/MGLLight.mm.ejs', 'utf8'), {strict: true}); +const testLight = ejs.compile(fs.readFileSync('platform/darwin/test/MGLLightTest.mm.ejs', 'utf8'), { strict: true}); +fs.writeFileSync(`platform/darwin/src/MGLLight.h`, duplicatePlatformDecls(lightH({ properties: lightProperties, doc: lightDoc, type: lightType }))); +fs.writeFileSync(`platform/darwin/src/MGLLight.mm`, lightM({ properties: lightProperties, doc: lightDoc, type: lightType })); +fs.writeFileSync(`platform/darwin/test/MGLLightTest.mm`, testLight({ properties: lightProperties, doc: lightDoc, type: lightType })); + + const layers = _(spec.layer.type.values).map((value, layerType) => { const layoutProperties = Object.keys(spec[`layout_${layerType}`]).reduce((memo, name) => { if (name !== 'visibility') { diff --git a/platform/darwin/scripts/style-spec-overrides-v8.json b/platform/darwin/scripts/style-spec-overrides-v8.json index a594ef2957..67a6641fe7 100644 --- a/platform/darwin/scripts/style-spec-overrides-v8.json +++ b/platform/darwin/scripts/style-spec-overrides-v8.json @@ -1,4 +1,10 @@ { + "light-cocoa-doc": "An `MGLLight` object represents the light source for extruded geometries in `MGLStyle`.", + "light": { + "position": { + "doc": "Position of the `MGLLight` source relative to lit (extruded) geometries, in a `MGLSphericalPosition` struct [radial coordinate, azimuthal angle, polar angle] where radial indicates the distance from the center of the base of an object to its light, azimuthal indicates the position of the light relative to 0° (0° when `MGLLight.anchor` is set to `MGLLightAnchorViewport` corresponds to the top of the viewport, or 0° when `MGLLight.anchor` is set to `MGLLightAnchorMap` corresponds to due north, and degrees proceed clockwise), and polar indicates the height of the light (from 0°, directly above, to 180°, directly below)." + } + }, "layer": { "type": { "values": { diff --git a/platform/darwin/src/MGLLight.h b/platform/darwin/src/MGLLight.h index 6dd24712e2..55b789f043 100644 --- a/platform/darwin/src/MGLLight.h +++ b/platform/darwin/src/MGLLight.h @@ -1,3 +1,6 @@ +// This file is generated. +// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. + #import #import "MGLFoundation.h" @@ -5,13 +8,19 @@ NS_ASSUME_NONNULL_BEGIN - -/** Options to specify extruded geometries are lit relative to the map or viewport. */ +/** + Whether extruded geometries are lit relative to the map or viewport. + */ typedef NS_ENUM(NSUInteger, MGLLightAnchor) { - /** The position of the light source is aligned to the rotation of the map. */ + /** + The position of the light source is aligned to the rotation of the map. + */ MGLLightAnchorMap, - /** The position of the light source is aligned to the rotation of the viewport. */ - MGLLightAnchorViewport + /** + The position of the light source is aligned to the rotation of the + viewport. + */ + MGLLightAnchorViewport, }; /** @@ -38,7 +47,7 @@ typedef struct MGLSphericalPosition { @return Returns a `MGLSphericalPosition` struct containing the position attributes. */ -NS_INLINE MGLSphericalPosition MGLSphericalPositionMake(CLLocationDistance radial, CLLocationDirection azimuthal, CLLocationDirection polar) { +NS_INLINE MGLSphericalPosition MGLSphericalPositionMake(CGFloat radial, CLLocationDirection azimuthal, CLLocationDirection polar) { MGLSphericalPosition position; position.radial = radial; position.azimuthal = azimuthal; @@ -54,8 +63,17 @@ MGL_EXPORT @interface MGLLight : NSObject /** - `anchor` Whether extruded geometries are lit relative to the map or viewport. + Whether extruded geometries are lit relative to the map or viewport. + + The default value of this property is an `MGLStyleValue` object containing an + `NSValue` object containing `MGLLightAnchorViewport`. + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of + `MGLInterpolationModeInterval` + This property corresponds to the anchor light property in the Mapbox Style Specification. @@ -63,14 +81,25 @@ MGL_EXPORT @property (nonatomic) MGLStyleValue *anchor; /** - Values describing animated transitions to `anchor` property. - */ -@property (nonatomic) MGLTransition anchorTransition; - - -/** - Position of the light source relative to lit (extruded) geometries. + Position of the `MGLLight` source relative to lit (extruded) geometries, in a + `MGLSphericalPosition` struct [radial coordinate, azimuthal angle, polar angle] + where radial indicates the distance from the center of the base of an object to + its light, azimuthal indicates the position of the light relative to 0° (0° + when `MGLLight.anchor` is set to `MGLLightAnchorViewport` corresponds to the + top of the viewport, or 0° when `MGLLight.anchor` is set to `MGLLightAnchorMap` + corresponds to due north, and degrees proceed clockwise), and polar indicates + the height of the light (from 0°, directly above, to 180°, directly below). + + The default value of this property is an `MGLStyleValue` object containing an + `MGLSphericalPosition` struct set to 1.15 radial, 210 azimuthal and 30 polar. + + You can set this property to an instance of: + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + This property corresponds to the position light property in the Mapbox Style Specification. @@ -78,48 +107,87 @@ MGL_EXPORT @property (nonatomic) MGLStyleValue *position; /** - Values describing animated transitions to `position` property. - */ -@property (nonatomic) MGLTransition positionTransiton; + The transition affecting any changes to this layer’s `position` property. + This property corresponds to the `position-transition` property in the style JSON file format. +*/ +@property (nonatomic) MGLTransition positionTransition; #if TARGET_OS_IPHONE /** Color tint for lighting extruded geometries. + The default value of this property is an `MGLStyleValue` object containing + `UIColor.whiteColor`. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + This property corresponds to the color light property in the Mapbox Style Specification. */ @property (nonatomic) MGLStyleValue *color; #else - /** Color tint for lighting extruded geometries. + + The default value of this property is an `MGLStyleValue` object containing + `NSColor.whiteColor`. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + + This property corresponds to the color + light property in the Mapbox Style Specification. */ @property (nonatomic) MGLStyleValue *color; #endif /** - Values describing animated transitions to `color` property. - */ -@property (nonatomic) MGLTransition colorTransiton; + The transition affecting any changes to this layer’s `color` property. + This property corresponds to the `color-transition` property in the style JSON file format. +*/ +@property (nonatomic) MGLTransition colorTransition; /** - Intensity of lighting (on a scale from 0 to 1). Higher numbers will present as more extreme contrast. + Intensity of lighting (on a scale from 0 to 1). Higher numbers will present as + more extreme contrast. + + The default value of this property is an `MGLStyleValue` object containing an + `NSNumber` object containing the float `0.5`. + + You can set this property to an instance of: + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + This property corresponds to the intensity light property in the Mapbox Style Specification. */ -@property(nonatomic) MGLStyleValue *intensity; +@property (nonatomic) MGLStyleValue *intensity; /** - Values describing animated transitions to `intensity` property. - */ + The transition affecting any changes to this layer’s `intensity` property. + + This property corresponds to the `intensity-transition` property in the style JSON file format. +*/ @property (nonatomic) MGLTransition intensityTransition; + @end NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLLight.h.ejs b/platform/darwin/src/MGLLight.h.ejs new file mode 100644 index 0000000000..26ecefc3af --- /dev/null +++ b/platform/darwin/src/MGLLight.h.ejs @@ -0,0 +1,100 @@ +<% + const properties = locals.properties; + const type = locals.type; + const doc = locals.doc; +-%> +// This file is generated. +// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. + +#import + +#import "MGLFoundation.h" +#import "MGLStyleValue.h" + +NS_ASSUME_NONNULL_BEGIN + +<% for (const property of properties) { -%> +<% if (property.type == "enum") { -%> +/** +<%- propertyDoc(property.name, property, type, 'enum').wrap(80, 1) %> + */ +typedef NS_ENUM(NSUInteger, MGLLight<%- camelize(property.name) %>) { +<% for (const value in property.values) { -%> + /** +<%- propertyDoc(property.name, property.values[value], type, 'enum').wrap(80, 4+1) %> + */ + MGLLightAnchor<%- camelize(value) %>, +<% } -%> +}; +<% } -%> +<% } -%> + +/** + A structure containing information about the position of the light source + relative to lit geometries. + */ +typedef struct MGLSphericalPosition { + /** Distance from the center of the base of an object to its light. */ + CGFloat radial; + /** Position of the light relative to 0° (0° when `MGLLight.anchor` is set to viewport corresponds + to the top of the viewport, or 0° when `MGLLight.anchor` is set to map corresponds to due north, + and degrees proceed clockwise). */ + CLLocationDirection azimuthal; + /** Indicates the height of the light (from 0°, directly above, to 180°, directly below). */ + CLLocationDirection polar; +} MGLSphericalPosition; + +/** + Creates a new `MGLSphericalPosition` from the given radial, azimuthal, polar. + + @param radial The radial coordinate. + @param azimuthal The azimuthal angle. + @param polar The polar angle. + + @return Returns a `MGLSphericalPosition` struct containing the position attributes. + */ +NS_INLINE MGLSphericalPosition MGLSphericalPositionMake(CGFloat radial, CLLocationDirection azimuthal, CLLocationDirection polar) { + MGLSphericalPosition position; + position.radial = radial; + position.azimuthal = azimuthal; + position.polar = polar; + + return position; +} + +/** + <%- doc %> + */ +MGL_EXPORT +@interface MGLLight : NSObject +<% if (properties.length) { -%> + +<% for (const property of properties) { -%> +/** +<%- propertyDoc(property.name, property, type, 'light').wrap(80, 1) %> + + This property corresponds to the <%- originalPropertyName(property) %> + light property in the Mapbox Style Specification. + */ +@property (nonatomic<% if (property.getter) { %>, getter=<%- objCGetter(property) -%><% } %>) MGLStyleValue<<%- propertyType(property, true) %>> *<%- camelizeWithLeadingLowercase(property.name) %>; + +<% if (property.transition) { -%> +/** + The transition affecting any changes to this layer’s `<%- camelizeWithLeadingLowercase(property.name) %>` property. + + This property corresponds to the `<%- originalPropertyName(property) %>-transition` property in the style JSON file format. +*/ +@property (nonatomic) MGLTransition <%- camelizeWithLeadingLowercase(property.name) %>Transition; + +<% } -%> +<% if (property.original) { -%> +@property (nonatomic<% if (!property.required) { %>, null_resettable<% } %>) MGLStyleValue<<%- propertyType(property, true) %>> *<%- camelizeWithLeadingLowercase(originalPropertyName(property)) %> __attribute__((unavailable("Use <%- camelizeWithLeadingLowercase(property.name) %> instead."))); + +<% } -%> +<% } -%> +<% } -%> + +@end + +NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLLight.mm b/platform/darwin/src/MGLLight.mm index 262fad3b07..c83ef127a6 100644 --- a/platform/darwin/src/MGLLight.mm +++ b/platform/darwin/src/MGLLight.mm @@ -1,3 +1,7 @@ +// This file is generated. +// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. +// test + #import "MGLLight.h" #import "MGLTypes.h" @@ -9,7 +13,7 @@ #import namespace mbgl { - + MBGL_DEFINE_ENUM(MGLLightAnchor, { { MGLLightAnchorMap, "map" }, { MGLLightAnchorViewport, "viewport" }, @@ -47,11 +51,9 @@ NS_INLINE mbgl::style::TransitionOptions MGLOptionsFromTransition(MGLTransition } else { anchorStyleValue = MGLStyleValueTransformer().toEnumStyleValue(anchor); } - + _anchor = anchorStyleValue; - - _anchorTransition = MGLTransitionFromOptions(mbglLight->getAnchorTransition()); - + auto positionValue = mbglLight->getPosition(); if (positionValue.isUndefined()) { _position = MGLStyleValueTransformer().toStyleValue(mbglLight->getDefaultPosition()); @@ -59,8 +61,8 @@ NS_INLINE mbgl::style::TransitionOptions MGLOptionsFromTransition(MGLTransition _position = MGLStyleValueTransformer().toStyleValue(positionValue); } - _positionTransiton = MGLTransitionFromOptions(mbglLight->getPositionTransition()); - + _positionTransition = MGLTransitionFromOptions(mbglLight->getPositionTransition()); + auto colorValue = mbglLight->getColor(); if (colorValue.isUndefined()) { _color = MGLStyleValueTransformer().toStyleValue(mbglLight->getDefaultColor()); @@ -68,8 +70,8 @@ NS_INLINE mbgl::style::TransitionOptions MGLOptionsFromTransition(MGLTransition _color = MGLStyleValueTransformer().toStyleValue(colorValue); } - _colorTransiton = MGLTransitionFromOptions(mbglLight->getColorTransition()); - + _colorTransition = MGLTransitionFromOptions(mbglLight->getColorTransition()); + auto intensityValue = mbglLight->getIntensity(); if (intensityValue.isUndefined()) { _intensity = MGLStyleValueTransformer().toStyleValue(mbglLight->getDefaultIntensity()); @@ -78,6 +80,7 @@ NS_INLINE mbgl::style::TransitionOptions MGLOptionsFromTransition(MGLTransition } _intensityTransition = MGLTransitionFromOptions(mbglLight->getIntensityTransition()); + } return self; @@ -86,26 +89,24 @@ NS_INLINE mbgl::style::TransitionOptions MGLOptionsFromTransition(MGLTransition - (mbgl::style::Light)mbglLight { mbgl::style::Light mbglLight; - auto anchor = MGLStyleValueTransformer().toEnumPropertyValue(self.anchor); mbglLight.setAnchor(anchor); - - mbglLight.setAnchorTransition(MGLOptionsFromTransition(self.anchorTransition)); - + auto position = MGLStyleValueTransformer().toInterpolatablePropertyValue(self.position); mbglLight.setPosition(position); - - mbglLight.setPositionTransition(MGLOptionsFromTransition(self.positionTransiton)); - + + mbglLight.setPositionTransition(MGLOptionsFromTransition(self.positionTransition)); + auto color = MGLStyleValueTransformer().toInterpolatablePropertyValue(self.color); mbglLight.setColor(color); - - mbglLight.setColorTransition(MGLOptionsFromTransition(self.colorTransiton)); - + + mbglLight.setColorTransition(MGLOptionsFromTransition(self.colorTransition)); + auto intensity = MGLStyleValueTransformer().toInterpolatablePropertyValue(self.intensity); mbglLight.setIntensity(intensity); - + mbglLight.setIntensityTransition(MGLOptionsFromTransition(self.intensityTransition)); + return mbglLight; } diff --git a/platform/darwin/src/MGLLight.mm.ejs b/platform/darwin/src/MGLLight.mm.ejs new file mode 100644 index 0000000000..0d0da124c8 --- /dev/null +++ b/platform/darwin/src/MGLLight.mm.ejs @@ -0,0 +1,114 @@ +<% + const properties = locals.properties; +-%> +// This file is generated. +// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. +// test + +#import "MGLLight.h" + +#import "MGLTypes.h" +#import "NSDate+MGLAdditions.h" +#import "MGLStyleValue_Private.h" +#import "NSValue+MGLAdditions.h" + +#import +#import + +namespace mbgl { + + MBGL_DEFINE_ENUM(MGLLightAnchor, { +<% for (const property of properties) { -%> +<% if (property.type == "enum") { -%> +<% for (const value in property.values) { -%> + { MGLLightAnchor<%- camelize(value) %>, "<%- value %>" }, +<% } -%> +<% } -%> +<% } -%> + }); + +} + +NS_INLINE MGLTransition MGLTransitionFromOptions(const mbgl::style::TransitionOptions& options) { + MGLTransition transition; + transition.duration = MGLTimeIntervalFromDuration(options.duration.value_or(mbgl::Duration::zero())); + transition.delay = MGLTimeIntervalFromDuration(options.delay.value_or(mbgl::Duration::zero())); + + return transition; +} + +NS_INLINE mbgl::style::TransitionOptions MGLOptionsFromTransition(MGLTransition transition) { + mbgl::style::TransitionOptions options { { MGLDurationFromTimeInterval(transition.duration) }, { MGLDurationFromTimeInterval(transition.delay) } }; + return options; +} + +@interface MGLLight() + +@end + +@implementation MGLLight + +- (instancetype)initWithMBGLLight:(const mbgl::style::Light *)mbglLight +{ + if (self = [super init]) { +<% if (properties.length) { -%> +<% for (const property of properties) { -%> +<% if (property.type == "enum") { -%> + auto <%- camelizeWithLeadingLowercase(property.name) -%> = mbglLight->get<%- camelize(property.name) -%>(); + MGLStyleValue *<%- camelizeWithLeadingLowercase(property.name) -%>StyleValue; + if (<%- camelizeWithLeadingLowercase(property.name) -%>.isUndefined()) { + mbgl::style::PropertyValueType> default<%- camelize(property.name) -%> = mbglLight->getDefault<%- camelize(property.name) -%>(); + <%- camelizeWithLeadingLowercase(property.name) -%>StyleValue = MGLStyleValueTransformerType, MGLLight<%- camelize(property.name) -%>>().toEnumStyleValue(default<%- camelize(property.name) -%>); + } else { + <%- camelizeWithLeadingLowercase(property.name) -%>StyleValue = MGLStyleValueTransformerType, NSValue *, mbgl::style::Light<%- camelize(property.name) -%>Type, MGLLight<%- camelize(property.name) -%>>().toEnumStyleValue(<%- camelizeWithLeadingLowercase(property.name) -%>); + } + + _<%- camelizeWithLeadingLowercase(property.name) -%> = <%- camelizeWithLeadingLowercase(property.name) -%>StyleValue; + +<% if (property.transition) { -%> + _<%- camelizeWithLeadingLowercase(property.name) -%>Transition = MGLTransitionFromOptions(mbglLight->get<%- camelize(property.name) -%>Transition()); + +<% } -%> +<% } else {-%> + auto <%- camelizeWithLeadingLowercase(property.name) -%>Value = mbglLight->get<%- camelize(property.name) -%>(); + if (<%- camelizeWithLeadingLowercase(property.name) -%>Value.isUndefined()) { + _<%- camelizeWithLeadingLowercase(property.name) -%> = MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toStyleValue(mbglLight->getDefault<%- camelize(property.name) -%>()); + } else { + _<%- camelizeWithLeadingLowercase(property.name) -%> = MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toStyleValue(<%- camelizeWithLeadingLowercase(property.name) -%>Value); + } +<% if (property.transition) { -%> + _<%- camelizeWithLeadingLowercase(property.name) -%>Transition = MGLTransitionFromOptions(mbglLight->get<%- camelize(property.name) -%>Transition()); +<% } -%> +<% } -%> +<% } -%> +<% } -%> + } + + return self; +} + +- (mbgl::style::Light)mbglLight +{ + mbgl::style::Light mbglLight; +<% if (properties.length) { -%> +<% for (const property of properties) { -%> +<% if (property.type == "enum") { -%> + auto <%- camelizeWithLeadingLowercase(property.name) -%> = MGLStyleValueTransformerType, NSValue *, mbgl::style::Light<%- camelize(property.name) -%>Type, MGLLight<%- camelize(property.name) -%>>().toEnumPropertyValue(self.<%- camelizeWithLeadingLowercase(property.name) -%>); + mbglLight.set<%- camelize(property.name) -%>(<%- camelizeWithLeadingLowercase(property.name) -%>); + +<% } else {-%> + auto <%- camelizeWithLeadingLowercase(property.name) -%> = MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toInterpolatablePropertyValue(self.<%- camelizeWithLeadingLowercase(property.name) -%>); + mbglLight.set<%- camelize(property.name) -%>(<%- camelizeWithLeadingLowercase(property.name) -%>); + +<% } -%> +<% if (property.transition) { -%> + mbglLight.set<%- camelize(property.name) -%>Transition(MGLOptionsFromTransition(self.<%- camelizeWithLeadingLowercase(property.name) -%>Transition)); + +<% } -%> +<% } -%> +<% } -%> + + return mbglLight; +} + +@end diff --git a/platform/darwin/test/MGLLightTest.mm b/platform/darwin/test/MGLLightTest.mm index 2c3d1c7bd1..b021bd1b73 100644 --- a/platform/darwin/test/MGLLightTest.mm +++ b/platform/darwin/test/MGLLightTest.mm @@ -1,3 +1,5 @@ +// This file is generated. +// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. #import #import @@ -20,186 +22,109 @@ MGLTransition defaultTransition = MGLTransitionMake(0, 0); MGLTransition transition = MGLTransitionMake(6, 3); mbgl::style::TransitionOptions transitionOptions { { MGLDurationFromTimeInterval(6) }, { MGLDurationFromTimeInterval(3) } }; - + // anchor { mbgl::style::Light light; MGLLight *mglLight = [[MGLLight alloc] initWithMBGLLight:&light]; - - NSAssert([mglLight.anchor isKindOfClass:[MGLConstantStyleValue class]], @"mglLight.anchor isn’t a MGLConstantStyleValue."); + auto lightFromMGLlight = [mglLight mbglLight]; + + XCTAssertEqual(light.getDefaultAnchor(), lightFromMGLlight.getAnchor()); + XCTAssert([mglLight.anchor isKindOfClass:[MGLConstantStyleValue class]], @"mglLight.anchor isn’t a MGLConstantStyleValue."); NSValue *anchorValue = ((MGLConstantStyleValue *)mglLight.anchor).rawValue; XCTAssertEqual(anchorValue.MGLLightAnchorValue, MGLLightAnchorViewport); - XCTAssertEqual(mglLight.anchorTransition.delay, defaultTransition.delay); - XCTAssertEqual(mglLight.anchorTransition.duration, defaultTransition.duration); - - auto lightFromMGLlight = [mglLight mbglLight]; - - XCTAssertEqual(light.getDefaultAnchor(), lightFromMGLlight.getAnchor().asConstant()); - auto anchorTransition = lightFromMGLlight.getAnchorTransition(); - XCTAssert(anchorTransition.delay && MGLTimeIntervalFromDuration(*anchorTransition.delay) == defaultTransition.delay); - XCTAssert(anchorTransition.duration && MGLTimeIntervalFromDuration(*anchorTransition.duration) == defaultTransition.duration); - - MGLStyleValue *anchorStyleValue = [MGLStyleValue valueWithRawValue:[NSValue valueWithMGLLightAnchor:MGLLightAnchorMap]]; - mglLight.anchor = anchorStyleValue; - mglLight.anchorTransition = transition; - NSAssert([mglLight.anchor isKindOfClass:[MGLConstantStyleValue class]], @"mglLight.anchor isn’t a MGLConstantStyleValue."); - anchorValue = ((MGLConstantStyleValue *)mglLight.anchor).rawValue; - - XCTAssertEqual(anchorValue.MGLLightAnchorValue, MGLLightAnchorMap); - XCTAssertEqual(mglLight.anchorTransition.delay, transition.delay); - XCTAssertEqual(mglLight.anchorTransition.duration, transition.duration); - - mbgl::style::PropertyValue anchorProperty = { mbgl::style::LightAnchorType::Map }; - light.setAnchor(anchorProperty); - light.setAnchorTransition(transitionOptions); - + + mbgl::style::PropertyValue propertyValue = { mbgl::style::LightAnchorType::Viewport }; + + light.setAnchor(propertyValue); + + mglLight = [[MGLLight alloc] initWithMBGLLight:&light]; lightFromMGLlight = [mglLight mbglLight]; - - XCTAssertEqual(light.getAnchor().asConstant(), lightFromMGLlight.getAnchor().asConstant()); - anchorTransition = lightFromMGLlight.getAnchorTransition(); - XCTAssert(anchorTransition.delay && MGLTimeIntervalFromDuration(*anchorTransition.delay) == transition.delay); - XCTAssert(anchorTransition.duration && MGLTimeIntervalFromDuration(*anchorTransition.duration) == transition.duration); - + + XCTAssertEqual(light.getAnchor(), lightFromMGLlight.getAnchor()); } - + // position { mbgl::style::Light light; MGLLight *mglLight = [[MGLLight alloc] initWithMBGLLight:&light]; - NSAssert([mglLight.position isKindOfClass:[MGLConstantStyleValue class]], @"mglLight.position isn’t a MGLConstantStyleValue."); - NSValue *positionValue = ((MGLConstantStyleValue *)mglLight.position).rawValue; - auto positionArray = light.getDefaultPosition().getSpherical(); - MGLSphericalPosition defaultPosition = MGLSphericalPositionMake(positionArray[0], positionArray[1], positionArray[2]); - - XCTAssert(defaultPosition.radial == positionValue.MGLSphericalPositionValue.radial); - XCTAssert(defaultPosition.azimuthal == positionValue.MGLSphericalPositionValue.azimuthal); - XCTAssert(defaultPosition.polar == positionValue.MGLSphericalPositionValue.polar); - XCTAssertEqual(mglLight.positionTransiton.delay, defaultTransition.delay); - XCTAssertEqual(mglLight.positionTransiton.duration, defaultTransition.duration); - auto lightFromMGLlight = [mglLight mbglLight]; - - XCTAssertEqual(positionArray, lightFromMGLlight.getPosition().asConstant().getSpherical()); + + XCTAssertEqual(light.getDefaultPosition(), lightFromMGLlight.getPosition()); auto positionTransition = lightFromMGLlight.getPositionTransition(); XCTAssert(positionTransition.delay && MGLTimeIntervalFromDuration(*positionTransition.delay) == defaultTransition.delay); XCTAssert(positionTransition.duration && MGLTimeIntervalFromDuration(*positionTransition.duration) == defaultTransition.duration); - - defaultPosition = MGLSphericalPositionMake(6, 180, 90); - MGLStyleValue *positionStyleValue = [MGLStyleValue valueWithRawValue:[NSValue valueWithMGLSphericalPosition:defaultPosition]]; - mglLight.position = positionStyleValue; - mglLight.positionTransiton = transition; - - NSAssert([mglLight.position isKindOfClass:[MGLConstantStyleValue class]], @"mglLight.position isn’t a MGLConstantStyleValue."); - positionValue = ((MGLConstantStyleValue *)mglLight.position).rawValue; - - XCTAssert(defaultPosition.radial == positionValue.MGLSphericalPositionValue.radial); - XCTAssert(defaultPosition.azimuthal == positionValue.MGLSphericalPositionValue.azimuthal); - XCTAssert(defaultPosition.polar == positionValue.MGLSphericalPositionValue.polar); - XCTAssertEqual(mglLight.positionTransiton.delay, transition.delay); - XCTAssertEqual(mglLight.positionTransiton.duration, transition.duration); - - lightFromMGLlight = [mglLight mbglLight]; - - positionArray = { { 6, 180, 90 } }; + + const std::array positionArray = { { 6, 180, 90 } }; mbgl::style::Position position = { positionArray }; - mbgl::style::PropertyValue positionProperty = { position }; - light.setPosition(positionProperty); + mbgl::style::PropertyValue propertyValue = { position }; + + light.setPosition(propertyValue); light.setPositionTransition(transitionOptions); - XCTAssertEqual(positionArray, lightFromMGLlight.getPosition().asConstant().getSpherical()); + + mglLight = [[MGLLight alloc] initWithMBGLLight:&light]; + lightFromMGLlight = [mglLight mbglLight]; + + XCTAssertEqual(light.getPosition(), lightFromMGLlight.getPosition()); positionTransition = lightFromMGLlight.getPositionTransition(); XCTAssert(positionTransition.delay && MGLTimeIntervalFromDuration(*positionTransition.delay) == transition.delay); XCTAssert(positionTransition.duration && MGLTimeIntervalFromDuration(*positionTransition.duration) == transition.duration); } - + // color { mbgl::style::Light light; MGLLight *mglLight = [[MGLLight alloc] initWithMBGLLight:&light]; - NSAssert([mglLight.color isKindOfClass:[MGLConstantStyleValue class]], @"mglLight.color isn’t a MGLConstantStyleValue."); - MGLColor *colorValue = ((MGLConstantStyleValue *)mglLight.color).rawValue; - auto color = light.getDefaultColor(); - const CGFloat *colorComponents = CGColorGetComponents(colorValue.CGColor); - - XCTAssert(color.r == colorComponents[0] && color.g == colorComponents[1] && color.b == colorComponents[2] && - color.a == colorComponents[3]); - XCTAssertEqual(mglLight.colorTransiton.delay, defaultTransition.delay); - XCTAssertEqual(mglLight.colorTransiton.duration, defaultTransition.duration); - auto lightFromMGLlight = [mglLight mbglLight]; - - XCTAssertEqual(color, lightFromMGLlight.getColor().asConstant()); + + XCTAssertEqual(light.getDefaultColor(), lightFromMGLlight.getColor()); auto colorTransition = lightFromMGLlight.getColorTransition(); XCTAssert(colorTransition.delay && MGLTimeIntervalFromDuration(*colorTransition.delay) == defaultTransition.delay); XCTAssert(colorTransition.duration && MGLTimeIntervalFromDuration(*colorTransition.duration) == defaultTransition.duration); - - MGLStyleValue *colorStyleValue = [MGLStyleValue valueWithRawValue:[MGLColor blackColor]]; - mglLight.color = colorStyleValue; - mglLight.colorTransiton = transition; - - NSAssert([mglLight.color isKindOfClass:[MGLConstantStyleValue class]], @"mglLight.color isn’t a MGLConstantStyleValue."); - colorValue = ((MGLConstantStyleValue *)mglLight.color).rawValue; - - XCTAssertEqual([MGLColor blackColor], colorValue); - XCTAssertEqual(mglLight.colorTransiton.delay, transition.delay); - XCTAssertEqual(mglLight.colorTransiton.duration, transition.duration); - - mbgl::style::PropertyValue colorProperty = { { 0, 0, 0, 1 } }; - light.setColor(colorProperty); + + mbgl::style::PropertyValue propertyValue = { { 1, 0, 0, 1 } }; + + light.setColor(propertyValue); light.setColorTransition(transitionOptions); - + + + mglLight = [[MGLLight alloc] initWithMBGLLight:&light]; lightFromMGLlight = [mglLight mbglLight]; - - colorComponents = CGColorGetComponents(colorValue.CGColor); - color = lightFromMGLlight.getColor().asConstant(); - XCTAssertEqual(light.getColor().asConstant(),lightFromMGLlight.getColor().asConstant()); + + XCTAssertEqual(light.getColor(), lightFromMGLlight.getColor()); colorTransition = lightFromMGLlight.getColorTransition(); XCTAssert(colorTransition.delay && MGLTimeIntervalFromDuration(*colorTransition.delay) == transition.delay); XCTAssert(colorTransition.duration && MGLTimeIntervalFromDuration(*colorTransition.duration) == transition.duration); + } - + // intensity { mbgl::style::Light light; MGLLight *mglLight = [[MGLLight alloc] initWithMBGLLight:&light]; - NSAssert([mglLight.intensity isKindOfClass:[MGLConstantStyleValue class]], @"mglLight.intensity isn’t a MGLConstantStyleValue."); - NSNumber *intensityNumber = ((MGLConstantStyleValue *)mglLight.intensity).rawValue; - auto intensity = light.getDefaultIntensity(); - - XCTAssert(intensityNumber.floatValue == intensity); - XCTAssertEqual(mglLight.intensityTransition.delay, defaultTransition.delay); - XCTAssertEqual(mglLight.intensityTransition.duration, defaultTransition.duration); - auto lightFromMGLlight = [mglLight mbglLight]; - - XCTAssertEqual(intensity, lightFromMGLlight.getIntensity().asConstant()); + + XCTAssertEqual(light.getDefaultIntensity(), lightFromMGLlight.getIntensity()); auto intensityTransition = lightFromMGLlight.getIntensityTransition(); XCTAssert(intensityTransition.delay && MGLTimeIntervalFromDuration(*intensityTransition.delay) == defaultTransition.delay); XCTAssert(intensityTransition.duration && MGLTimeIntervalFromDuration(*intensityTransition.duration) == defaultTransition.duration); - - NSNumber *intensityValue = @0.4; - MGLStyleValue *intensityStyleValue = [MGLStyleValue valueWithRawValue:intensityValue]; - mglLight.intensity = intensityStyleValue; - mglLight.intensityTransition = transition; - - NSAssert([mglLight.intensity isKindOfClass:[MGLConstantStyleValue class]], @"mglLight.intensity isn’t a MGLConstantStyleValue."); - intensityNumber = ((MGLConstantStyleValue *)mglLight.intensity).rawValue; - XCTAssert(intensityNumber.floatValue == intensityValue.floatValue); - XCTAssertEqual(mglLight.intensityTransition.delay, transition.delay); - XCTAssertEqual(mglLight.intensityTransition.duration, transition.duration); - - mbgl::style::PropertyValue intensityProperty = { 0.4 }; - light.setIntensity(intensityProperty); + + mbgl::style::PropertyValue propertyValue = { 0xff }; + + light.setIntensity(propertyValue); light.setIntensityTransition(transitionOptions); + + mglLight = [[MGLLight alloc] initWithMBGLLight:&light]; lightFromMGLlight = [mglLight mbglLight]; - - XCTAssertEqual(light.getIntensity().asConstant(), lightFromMGLlight.getIntensity().asConstant()); + + XCTAssertEqual(light.getIntensity(), lightFromMGLlight.getIntensity()); intensityTransition = lightFromMGLlight.getIntensityTransition(); XCTAssert(intensityTransition.delay && MGLTimeIntervalFromDuration(*intensityTransition.delay) == transition.delay); XCTAssert(intensityTransition.duration && MGLTimeIntervalFromDuration(*intensityTransition.duration) == transition.duration); - + } } diff --git a/platform/darwin/test/MGLLightTest.mm.ejs b/platform/darwin/test/MGLLightTest.mm.ejs new file mode 100644 index 0000000000..c1904d5ab8 --- /dev/null +++ b/platform/darwin/test/MGLLightTest.mm.ejs @@ -0,0 +1,92 @@ +<% + const type = locals.type; + const properties = locals.properties; +-%> +// This file is generated. +// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. +#import +#import + +#import "MGLLight_Private.h" + +#import "../../darwin/src/NSDate+MGLAdditions.h" + +#import +#import +#include + +@interface MGLLightTest : XCTestCase + +@end + +@implementation MGLLightTest + +- (void)testProperties { + + MGLTransition defaultTransition = MGLTransitionMake(0, 0); + MGLTransition transition = MGLTransitionMake(6, 3); + mbgl::style::TransitionOptions transitionOptions { { MGLDurationFromTimeInterval(6) }, { MGLDurationFromTimeInterval(3) } }; + +<% for (const property of properties) { -%> + // <%- property.name %> + { + mbgl::style::Light light; + MGLLight *mglLight = [[MGLLight alloc] initWithMBGLLight:&light]; + auto lightFromMGLlight = [mglLight mbglLight]; + + XCTAssertEqual(light.getDefault<%- camelize(property.name) -%>(), lightFromMGLlight.get<%- camelize(property.name) -%>()); +<% if (property.transition) { -%> + auto <%- camelizeWithLeadingLowercase(property.name) -%>Transition = lightFromMGLlight.get<%- camelize(property.name) -%>Transition(); + XCTAssert(<%- camelizeWithLeadingLowercase(property.name) -%>Transition.delay && MGLTimeIntervalFromDuration(*<%- camelizeWithLeadingLowercase(property.name) -%>Transition.delay) == defaultTransition.delay); + XCTAssert(<%- camelizeWithLeadingLowercase(property.name) -%>Transition.duration && MGLTimeIntervalFromDuration(*<%- camelizeWithLeadingLowercase(property.name) -%>Transition.duration) == defaultTransition.duration); + +<% } -%> +<% if (property.type == "enum" && property.default) { -%> + XCTAssert([mglLight.<%- camelizeWithLeadingLowercase(property.name) -%> isKindOfClass:[MGLConstantStyleValue class]], @"mglLight.<%- camelizeWithLeadingLowercase(property.name) -%> isn’t a MGLConstantStyleValue."); + NSValue *<%- camelizeWithLeadingLowercase(property.name) -%>Value = ((MGLConstantStyleValue *)mglLight.<%- camelizeWithLeadingLowercase(property.name) -%>).rawValue; + XCTAssertEqual(<%- camelizeWithLeadingLowercase(property.name) -%>Value.MGLLight<%- camelize(property.name) -%>Value, MGLLight<%- camelize(property.name) -%><%- camelize(property.default) -%>); + +<% } -%> +<% if (property.type == "array") { -%> + const std::array positionArray = { { 6, 180, 90 } }; + mbgl::style::Position position = { positionArray }; + mbgl::style::PropertyValue propertyValue = { position }; +<% } else { -%> + mbgl::style::PropertyValue<<%- mbglType(property) %>> propertyValue = { <%- mbglTestValue(property, type) %> }; +<% } -%> + light.set<%- camelize(property.name) -%>(propertyValue); +<% if (property.transition) { -%> + light.set<%- camelize(property.name) -%>Transition(transitionOptions); + +<% } -%> + mglLight = [[MGLLight alloc] initWithMBGLLight:&light]; + lightFromMGLlight = [mglLight mbglLight]; + + XCTAssertEqual(light.get<%- camelize(property.name) -%>(), lightFromMGLlight.get<%- camelize(property.name) -%>()); +<% if (property.transition) { -%> + <%- camelizeWithLeadingLowercase(property.name) -%>Transition = lightFromMGLlight.get<%- camelize(property.name) -%>Transition(); + XCTAssert(<%- camelizeWithLeadingLowercase(property.name) -%>Transition.delay && MGLTimeIntervalFromDuration(*<%- camelizeWithLeadingLowercase(property.name) -%>Transition.delay) == transition.delay); + XCTAssert(<%- camelizeWithLeadingLowercase(property.name) -%>Transition.duration && MGLTimeIntervalFromDuration(*<%- camelizeWithLeadingLowercase(property.name) -%>Transition.duration) == transition.duration); + +<% } -%> + } + +<% } -%> +} + +- (void)testValueAdditions { + MGLSphericalPosition position = MGLSphericalPositionMake(1.15, 210, 30); + + XCTAssertEqual([NSValue valueWithMGLSphericalPosition:position].MGLSphericalPositionValue.radial, position.radial); + XCTAssertEqual([NSValue valueWithMGLSphericalPosition:position].MGLSphericalPositionValue.azimuthal, position.azimuthal); + XCTAssertEqual([NSValue valueWithMGLSphericalPosition:position].MGLSphericalPositionValue.polar, position.polar); +<% for (const property of properties) { -%> +<% if (property.type == "enum") { -%> +<% for (const value in property.values) { -%> + XCTAssertEqual([NSValue valueWithMGLLight<%- camelize(property.name) %>:MGLLight<%- camelize(property.name) %><%- camelize(value) %>].MGLLight<%- camelize(property.name) %>Value, MGLLight<%- camelize(property.name) %><%- camelize(value) %>); +<% } -%> +<% } -%> +<% } -%> +} + +@end -- cgit v1.2.1 From 6a781414c6fd1c86af73e450dfbf029fe4424cdb Mon Sep 17 00:00:00 2001 From: Fabian Guerra Date: Fri, 16 Jun 2017 13:03:42 -0400 Subject: [ios] Update pods spec for iOS v3.6.0-beta.3 --- platform/ios/Mapbox-iOS-SDK-symbols.podspec | 2 +- platform/ios/Mapbox-iOS-SDK.podspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/ios/Mapbox-iOS-SDK-symbols.podspec b/platform/ios/Mapbox-iOS-SDK-symbols.podspec index 3116ede9f5..18a8837d80 100644 --- a/platform/ios/Mapbox-iOS-SDK-symbols.podspec +++ b/platform/ios/Mapbox-iOS-SDK-symbols.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |m| - version = '3.6.0-beta.2' + version = '3.6.0-beta.3' m.name = 'Mapbox-iOS-SDK-symbols' m.version = "#{version}-symbols" diff --git a/platform/ios/Mapbox-iOS-SDK.podspec b/platform/ios/Mapbox-iOS-SDK.podspec index f6bc3030ab..07a725922b 100644 --- a/platform/ios/Mapbox-iOS-SDK.podspec +++ b/platform/ios/Mapbox-iOS-SDK.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |m| - version = '3.6.0-beta.2' + version = '3.6.0-beta.3' m.name = 'Mapbox-iOS-SDK' m.version = version -- cgit v1.2.1 From 8699bcdbf07550107dee77e2fddf3aa982b9fbfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Fri, 16 Jun 2017 11:55:12 -0700 Subject: [ios, macos] Updated changelogs --- platform/ios/CHANGELOG.md | 3 +++ platform/macos/CHANGELOG.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index c57063707a..83a8e08ae9 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -20,8 +20,10 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Fixed an issue preventing programmatically added style layers from appearing in already cached tiles. ([#8954](https://github.com/mapbox/mapbox-gl-native/pull/8954)) * Fixed an issue causing a composite function’s highest zoom level stop to be misinterpreted. ([#8613](https://github.com/mapbox/mapbox-gl-native/pull/8613), [#8790](https://github.com/mapbox/mapbox-gl-native/pull/8790)) * Fixed an issue where re-adding a layer that had been previously removed from a style would reset its paint properties. Moved initializers for `MGLTileSource`, `MGLStyleLayer`, and `MGLForegroundStyleLayer` to their concrete subclasses; because these classes were already intended for initialization only via concrete subclasses, this should have no developer impact. ([#8626](https://github.com/mapbox/mapbox-gl-native/pull/8626)) +* Fixed a crash that occurred when removing a source that was still being used by one or more style layers. Since this is a programming error, a warning is logged to the console instead. ([#9129](https://github.com/mapbox/mapbox-gl-native/pull/9129)) * Feature querying results now account for any changes to a feature’s size caused by a source or composite style function. ([#8665](https://github.com/mapbox/mapbox-gl-native/pull/8665)) * Letter spacing is now disabled in Arabic text so that ligatures are drawn correctly. ([#9062](https://github.com/mapbox/mapbox-gl-native/pull/9062)) +* Improved the performance of styles using source and composite style functions. ([#9185](https://github.com/mapbox/mapbox-gl-native/pull/9185), [#9257](https://github.com/mapbox/mapbox-gl-native/pull/9257)) ### Annotations @@ -35,6 +37,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT ### User interaction * Added a scale bar to `MGLMapView` that indicates the scale of the map. ([#7631](https://github.com/mapbox/mapbox-gl-native/pull/7631)) +* Fixed an issue causing the map to go blank during a flight animation that travels a very short distance. ([#9199](https://github.com/mapbox/mapbox-gl-native/pull/9199)) * Fixed an issue where gesture recognizers associated with map view interactivity were not disabled when their related interactions were disabled. ([#8304](https://github.com/mapbox/mapbox-gl-native/pull/8304)) * Fixed an issue preventing the Mapbox Telemetry confirmation dialog from appearing when opened from within a map view in a modal view controller. ([#9027](https://github.com/mapbox/mapbox-gl-native/pull/9027)) * Corrected the size of MGLMapView’s compass. ([#9060](https://github.com/mapbox/mapbox-gl-native/pull/9060)) diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index fc4e88b08f..5afdd32180 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -17,14 +17,17 @@ * Fixed an issue preventing programmatically added style layers from appearing in already cached tiles. ([#8954](https://github.com/mapbox/mapbox-gl-native/pull/8954)) * Fixed an issue causing a composite function’s highest zoom level stop to be misinterpreted. ([#8613](https://github.com/mapbox/mapbox-gl-native/pull/8613), [#8790](https://github.com/mapbox/mapbox-gl-native/pull/8790)) * Fixed an issue where re-adding a layer that had been previously removed from a style would reset its paint properties. Moved initializers for `MGLTileSource`, `MGLStyleLayer`, and `MGLForegroundStyleLayer` to their concrete subclasses; because these classes were already intended for initialization only via concrete subclasses, this should have no developer impact. ([#8626](https://github.com/mapbox/mapbox-gl-native/pull/8626)) +* Fixed a crash that occurred when removing a source that was still being used by one or more style layers. Since this is a programming error, a warning is logged to the console instead. ([#9129](https://github.com/mapbox/mapbox-gl-native/pull/9129)) * Feature querying results now account for any changes to a feature’s size caused by a source or composite style function. ([#8665](https://github.com/mapbox/mapbox-gl-native/pull/8665)) * Letter spacing is now disabled in Arabic text so that ligatures are drawn correctly. ([#9062](https://github.com/mapbox/mapbox-gl-native/pull/9062)) +* Improved the performance of styles using source and composite style functions. ([#9185](https://github.com/mapbox/mapbox-gl-native/pull/9185), [#9257](https://github.com/mapbox/mapbox-gl-native/pull/9257)) ### Other changes * Fixed a crash when calling `MGLMultiPolygon.coordinate` [#8713](https://github.com/mapbox/mapbox-gl-native/pull/8713) * Fixed an issue causing attribution button text to appear blue instead of black. ([#8701](https://github.com/mapbox/mapbox-gl-native/pull/8701)) * Fixed a crash or console spew when MGLMapView is initialized with a frame smaller than 64 points wide by 64 points tall. ([#8562](https://github.com/mapbox/mapbox-gl-native/pull/8562)) +* Fixed an issue causing the map to go blank during a flight animation that travels a very short distance. ([#9199](https://github.com/mapbox/mapbox-gl-native/pull/9199)) * The Improve This Map button in the attribution action sheet now leads to a feedback tool that matches MGLMapView’s rotation and pitch. `-[MGLAttributionInfo feedbackURLAtCenterCoordinate:zoomLevel:]` no longer respects the feedback URL specified in TileJSON. ([#9078](https://github.com/mapbox/mapbox-gl-native/pull/9078)) * The error passed into `-[MGLMapViewDelegate mapViewDidFailLoadingMap:withError:]` now includes a more specific description and failure reason. ([#8418](https://github.com/mapbox/mapbox-gl-native/pull/8418)) * The `MGLPolyline.coordinate` and `MGLPolygon.coordinate` properties now return the midpoint and centroid, respectively, instead of the first coordinate. ([#8713](https://github.com/mapbox/mapbox-gl-native/pull/8713)) -- cgit v1.2.1 From 1de8aeed31226f167c528bfdcfae97d12c5d67ca Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Fri, 16 Jun 2017 10:16:11 -0700 Subject: [core] Fix composite function approximation for non-integer stops --- include/mbgl/style/function/composite_function.hpp | 75 +++++++++++++++------- src/mbgl/renderer/paint_property_binder.hpp | 10 +-- test/style/function/composite_function.test.cpp | 25 ++++++++ 3 files changed, 83 insertions(+), 27 deletions(-) diff --git a/include/mbgl/style/function/composite_function.hpp b/include/mbgl/style/function/composite_function.hpp index 9275ccdf8f..b82e63bc37 100644 --- a/include/mbgl/style/function/composite_function.hpp +++ b/include/mbgl/style/function/composite_function.hpp @@ -49,8 +49,16 @@ public: defaultValue(std::move(defaultValue_)) { } - std::tuple, Range> - coveringRanges(float zoom) const { + struct CoveringRanges { + float zoom; + Range coveringZoomRange; + Range coveringStopsRange; + }; + + // Return the relevant stop zoom values and inner stops that bracket a given zoom level. This + // is the first step toward evaluating the function, and is used for in the course of both partial + // evaluation of data-driven paint properties, and full evaluation of data-driven layout properties. + CoveringRanges coveringRanges(float zoom) const { return stops.match( [&] (const auto& s) { assert(!s.stops.empty()); @@ -63,7 +71,8 @@ public: minIt--; } - return std::make_tuple( + return CoveringRanges { + zoom, Range { minIt == s.stops.end() ? s.stops.rbegin()->first : minIt->first, maxIt == s.stops.end() ? s.stops.rbegin()->first : maxIt->first @@ -72,38 +81,49 @@ public: s.innerStops(minIt == s.stops.end() ? s.stops.rbegin()->second : minIt->second), s.innerStops(maxIt == s.stops.end() ? s.stops.rbegin()->second : maxIt->second) } - ); + }; } ); } + // Given a range of zoom values (typically two adjacent integer zoom levels, e.g. 5.0 and 6.0), + // return the covering ranges for both. This is used in the course of partial evaluation for + // data-driven paint properties. + Range rangeOfCoveringRanges(Range zoomRange) { + return Range { + coveringRanges(zoomRange.min), + coveringRanges(zoomRange.max) + }; + } + + // Given the covering ranges for range of zoom values (typically two adjacent integer zoom levels, + // e.g. 5.0 and 6.0), and a feature, return the results of fully evaluating the function for that + // feature at each of the two zoom levels. These two results are what go into the paint vertex buffers + // for vertices associated with this feature. The shader will interpolate between them at render time. template - Range evaluate(Range coveringStops, - const Feature& feature, - T finalDefaultValue) const { - optional v = feature.getValue(property); - if (!v) { - return { + Range evaluate(const Range& ranges, const Feature& feature, T finalDefaultValue) { + optional value = feature.getValue(property); + if (!value) { + return Range { defaultValue.value_or(finalDefaultValue), defaultValue.value_or(finalDefaultValue) }; } - auto eval = [&] (const auto& s) { - return s.evaluate(*v).value_or(defaultValue.value_or(finalDefaultValue)); - }; return Range { - coveringStops.min.match(eval), - coveringStops.max.match(eval) + evaluateFinal(ranges.min, *value, finalDefaultValue), + evaluateFinal(ranges.max, *value, finalDefaultValue) }; } - T evaluate(float zoom, const GeometryTileFeature& feature, T finalDefaultValue) const { - std::tuple, Range> ranges = coveringRanges(zoom); - Range resultRange = evaluate(std::get<1>(ranges), feature, finalDefaultValue); - return util::interpolate( - resultRange.min, - resultRange.max, - util::interpolationFactor(1.0f, std::get<0>(ranges), zoom)); + // Fully evaluate the function for a zoom value and feature. This is used when evaluating data-driven + // layout properties. + template + T evaluate(float zoom, const Feature& feature, T finalDefaultValue) const { + optional value = feature.getValue(property); + if (!value) { + return defaultValue.value_or(finalDefaultValue); + } + return evaluateFinal(coveringRanges(zoom), *value, finalDefaultValue); } friend bool operator==(const CompositeFunction& lhs, @@ -115,6 +135,17 @@ public: std::string property; Stops stops; optional defaultValue; + +private: + T evaluateFinal(const CoveringRanges& ranges, const Value& value, T finalDefaultValue) const { + auto eval = [&] (const auto& s) { + return s.evaluate(value).value_or(defaultValue.value_or(finalDefaultValue)); + }; + return util::interpolate( + ranges.coveringStopsRange.min.match(eval), + ranges.coveringStopsRange.max.match(eval), + util::interpolationFactor(1.0f, ranges.coveringZoomRange, ranges.zoom)); + } }; } // namespace style diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp index 062b77888e..bcbc7c287d 100644 --- a/src/mbgl/renderer/paint_property_binder.hpp +++ b/src/mbgl/renderer/paint_property_binder.hpp @@ -194,11 +194,11 @@ public: CompositeFunctionPaintPropertyBinder(style::CompositeFunction function_, float zoom, T defaultValue_) : function(std::move(function_)), defaultValue(std::move(defaultValue_)), - coveringRanges(function.coveringRanges(zoom)) { + rangeOfCoveringRanges(function.rangeOfCoveringRanges({zoom, zoom + 1})) { } void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) override { - Range range = function.evaluate(std::get<1>(coveringRanges), feature, defaultValue); + Range range = function.evaluate(rangeOfCoveringRanges, feature, defaultValue); this->statistics.add(range.min); this->statistics.add(range.max); AttributeValue value = zoomInterpolatedAttributeValue( @@ -225,7 +225,7 @@ public: } float interpolationFactor(float currentZoom) const override { - return util::interpolationFactor(1.0f, std::get<0>(coveringRanges), currentZoom); + return util::interpolationFactor(1.0f, { rangeOfCoveringRanges.min.zoom, rangeOfCoveringRanges.max.zoom }, currentZoom); } T uniformValue(const PossiblyEvaluatedPropertyValue& currentValue) const override { @@ -238,10 +238,10 @@ public: } private: - using InnerStops = typename style::CompositeFunction::InnerStops; style::CompositeFunction function; T defaultValue; - std::tuple, Range> coveringRanges; + using CoveringRanges = typename style::CompositeFunction::CoveringRanges; + Range rangeOfCoveringRanges; gl::VertexVector vertexVector; optional> vertexBuffer; }; diff --git a/test/style/function/composite_function.test.cpp b/test/style/function/composite_function.test.cpp index e0804d4b27..09b79a8b8f 100644 --- a/test/style/function/composite_function.test.cpp +++ b/test/style/function/composite_function.test.cpp @@ -44,3 +44,28 @@ TEST(CompositeFunction, ZoomInterpolation) { }), 0.0f) .evaluate(0.0f, oneInteger, -1.0f)) << "Should interpolate TO the first stop"; } + +TEST(CompositeFunction, Issue8460) { + CompositeFunction fn1("property", CompositeExponentialStops({ + {15.0f, {{uint64_t(1), 0.0f}}}, + {15.2f, {{uint64_t(1), 600.0f}}}, + }), 0.0f); + + EXPECT_NEAR( 0.0f, fn1.evaluate(15.0f, oneInteger, -1.0f), 0.00); + EXPECT_NEAR(300.0f, fn1.evaluate(15.1f, oneInteger, -1.0f), 0.01); + EXPECT_NEAR(600.0f, fn1.evaluate(15.2f, oneInteger, -1.0f), 0.00); + EXPECT_NEAR(600.0f, fn1.evaluate(16.0f, oneInteger, -1.0f), 0.00); + + CompositeFunction fn2("property", CompositeExponentialStops({ + {15.0f, {{uint64_t(1), 0.0f}}}, + {15.2f, {{uint64_t(1), 300.0f}}}, + {18.0f, {{uint64_t(1), 600.0f}}}, + }), 0.0f); + + EXPECT_NEAR( 0.0f, fn2.evaluate(15.0f, oneInteger, -1.0f), 0.00); + EXPECT_NEAR(150.0f, fn2.evaluate(15.1f, oneInteger, -1.0f), 0.01); + EXPECT_NEAR(300.0f, fn2.evaluate(15.2f, oneInteger, -1.0f), 0.00); + EXPECT_NEAR(385.71f, fn2.evaluate(16.0f, oneInteger, -1.0f), 0.01); + EXPECT_NEAR(600.0f, fn2.evaluate(18.0f, oneInteger, -1.0f), 0.00); + EXPECT_NEAR(600.0f, fn2.evaluate(19.0f, oneInteger, -1.0f), 0.00); +} -- cgit v1.2.1 From 505999a52df625c21791eae352342ae25e9c48af Mon Sep 17 00:00:00 2001 From: Jesse Bounds Date: Mon, 19 Jun 2017 09:34:44 -1000 Subject: [ios] Update telemetry cert pinning (#9292) --- platform/ios/ios.xcodeproj/project.pbxproj | 36 ++++--- platform/ios/resources/api_mapbox_com-digicert.der | Bin 1913 -> 0 bytes .../ios/resources/api_mapbox_com-digicert_2016.der | Bin 0 -> 1913 bytes .../ios/resources/api_mapbox_com-digicert_2017.der | Bin 0 -> 2030 bytes platform/ios/resources/api_mapbox_com-geotrust.der | Bin 1757 -> 0 bytes .../ios/resources/api_mapbox_com-geotrust_2016.der | Bin 0 -> 1757 bytes .../ios/resources/api_mapbox_com-geotrust_2017.der | Bin 0 -> 1758 bytes platform/ios/src/MGLAPIClient.m | 114 +++++++++------------ 8 files changed, 73 insertions(+), 77 deletions(-) delete mode 100644 platform/ios/resources/api_mapbox_com-digicert.der create mode 100644 platform/ios/resources/api_mapbox_com-digicert_2016.der create mode 100644 platform/ios/resources/api_mapbox_com-digicert_2017.der delete mode 100644 platform/ios/resources/api_mapbox_com-geotrust.der create mode 100644 platform/ios/resources/api_mapbox_com-geotrust_2016.der create mode 100644 platform/ios/resources/api_mapbox_com-geotrust_2017.der diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index b6d422d0fc..5120d63f20 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -163,12 +163,12 @@ 404C26E71D89C55D000AA13D /* MGLTileSource_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 404C26E61D89C515000AA13D /* MGLTileSource_Private.h */; }; 404C26E81D89C55D000AA13D /* MGLTileSource_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 404C26E61D89C515000AA13D /* MGLTileSource_Private.h */; }; 40599F0C1DEE1B7600182B5D /* api_mapbox_staging.der in Resources */ = {isa = PBXBuildFile; fileRef = 40599F001DEE1B2400182B5D /* api_mapbox_staging.der */; }; - 40599F0D1DEE1B7A00182B5D /* api_mapbox_com-digicert.der in Resources */ = {isa = PBXBuildFile; fileRef = 40599F011DEE1B2400182B5D /* api_mapbox_com-digicert.der */; }; - 40599F0E1DEE1B7E00182B5D /* api_mapbox_com-geotrust.der in Resources */ = {isa = PBXBuildFile; fileRef = 40599F021DEE1B2400182B5D /* api_mapbox_com-geotrust.der */; }; + 40599F0D1DEE1B7A00182B5D /* api_mapbox_com-digicert_2016.der in Resources */ = {isa = PBXBuildFile; fileRef = 40599F011DEE1B2400182B5D /* api_mapbox_com-digicert_2016.der */; }; + 40599F0E1DEE1B7E00182B5D /* api_mapbox_com-geotrust_2016.der in Resources */ = {isa = PBXBuildFile; fileRef = 40599F021DEE1B2400182B5D /* api_mapbox_com-geotrust_2016.der */; }; 4085AF091D933DEA00F11B22 /* MGLTileSetTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4085AF081D933DEA00F11B22 /* MGLTileSetTests.mm */; }; 408982E91DEE208200754016 /* api_mapbox_staging.der in Resources */ = {isa = PBXBuildFile; fileRef = 40599F001DEE1B2400182B5D /* api_mapbox_staging.der */; }; - 408982EA1DEE208B00754016 /* api_mapbox_com-digicert.der in Resources */ = {isa = PBXBuildFile; fileRef = 40599F011DEE1B2400182B5D /* api_mapbox_com-digicert.der */; }; - 408982EB1DEE209100754016 /* api_mapbox_com-geotrust.der in Resources */ = {isa = PBXBuildFile; fileRef = 40599F021DEE1B2400182B5D /* api_mapbox_com-geotrust.der */; }; + 408982EA1DEE208B00754016 /* api_mapbox_com-digicert_2016.der in Resources */ = {isa = PBXBuildFile; fileRef = 40599F011DEE1B2400182B5D /* api_mapbox_com-digicert_2016.der */; }; + 408982EB1DEE209100754016 /* api_mapbox_com-geotrust_2016.der in Resources */ = {isa = PBXBuildFile; fileRef = 40599F021DEE1B2400182B5D /* api_mapbox_com-geotrust_2016.der */; }; 408AA8571DAEDA1700022900 /* NSDictionary+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 408AA8551DAEDA0800022900 /* NSDictionary+MGLAdditions.h */; }; 408AA8581DAEDA1E00022900 /* NSDictionary+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 408AA8561DAEDA0800022900 /* NSDictionary+MGLAdditions.mm */; }; 408AA8591DAEDA1E00022900 /* NSDictionary+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 408AA8561DAEDA0800022900 /* NSDictionary+MGLAdditions.mm */; }; @@ -176,6 +176,10 @@ 409F43FD1E9E781C0048729D /* MGLMapViewDelegateIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 409F43FC1E9E781C0048729D /* MGLMapViewDelegateIntegrationTests.swift */; }; 40CF6DBB1DAC3C6600A4D18B /* MGLShape_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 40CF6DBA1DAC3C1800A4D18B /* MGLShape_Private.h */; }; 40CFA6511D7875BB008103BD /* MGLShapeSourceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 40CFA6501D787579008103BD /* MGLShapeSourceTests.mm */; }; + 40EA6BC11EF4599600FCCDA2 /* api_mapbox_com-digicert_2017.der in Resources */ = {isa = PBXBuildFile; fileRef = 40EA6BBD1EF4598900FCCDA2 /* api_mapbox_com-digicert_2017.der */; }; + 40EA6BC21EF4599700FCCDA2 /* api_mapbox_com-digicert_2017.der in Resources */ = {isa = PBXBuildFile; fileRef = 40EA6BBD1EF4598900FCCDA2 /* api_mapbox_com-digicert_2017.der */; }; + 40EA6BC31EF4599D00FCCDA2 /* api_mapbox_com-geotrust_2017.der in Resources */ = {isa = PBXBuildFile; fileRef = 40EA6BBE1EF4598900FCCDA2 /* api_mapbox_com-geotrust_2017.der */; }; + 40EA6BC41EF4599D00FCCDA2 /* api_mapbox_com-geotrust_2017.der in Resources */ = {isa = PBXBuildFile; fileRef = 40EA6BBE1EF4598900FCCDA2 /* api_mapbox_com-geotrust_2017.der */; }; 40EDA1C01CFE0E0200D9EA68 /* MGLAnnotationContainerView.h in Headers */ = {isa = PBXBuildFile; fileRef = 40EDA1BD1CFE0D4A00D9EA68 /* MGLAnnotationContainerView.h */; }; 40EDA1C11CFE0E0500D9EA68 /* MGLAnnotationContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 40EDA1BE1CFE0D4A00D9EA68 /* MGLAnnotationContainerView.m */; }; 40EDA1C21CFE0E0500D9EA68 /* MGLAnnotationContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 40EDA1BE1CFE0D4A00D9EA68 /* MGLAnnotationContainerView.m */; }; @@ -635,8 +639,8 @@ 404C26E11D89B877000AA13D /* MGLTileSource.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLTileSource.mm; sourceTree = ""; }; 404C26E61D89C515000AA13D /* MGLTileSource_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLTileSource_Private.h; sourceTree = ""; }; 40599F001DEE1B2400182B5D /* api_mapbox_staging.der */ = {isa = PBXFileReference; lastKnownFileType = file; path = api_mapbox_staging.der; sourceTree = ""; }; - 40599F011DEE1B2400182B5D /* api_mapbox_com-digicert.der */ = {isa = PBXFileReference; lastKnownFileType = file; path = "api_mapbox_com-digicert.der"; sourceTree = ""; }; - 40599F021DEE1B2400182B5D /* api_mapbox_com-geotrust.der */ = {isa = PBXFileReference; lastKnownFileType = file; path = "api_mapbox_com-geotrust.der"; sourceTree = ""; }; + 40599F011DEE1B2400182B5D /* api_mapbox_com-digicert_2016.der */ = {isa = PBXFileReference; lastKnownFileType = file; path = "api_mapbox_com-digicert_2016.der"; sourceTree = ""; }; + 40599F021DEE1B2400182B5D /* api_mapbox_com-geotrust_2016.der */ = {isa = PBXFileReference; lastKnownFileType = file; path = "api_mapbox_com-geotrust_2016.der"; sourceTree = ""; }; 4085AF081D933DEA00F11B22 /* MGLTileSetTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLTileSetTests.mm; path = ../../darwin/test/MGLTileSetTests.mm; sourceTree = ""; }; 408AA8551DAEDA0800022900 /* NSDictionary+MGLAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+MGLAdditions.h"; sourceTree = ""; }; 408AA8561DAEDA0800022900 /* NSDictionary+MGLAdditions.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSDictionary+MGLAdditions.mm"; sourceTree = ""; }; @@ -644,6 +648,8 @@ 409F43FC1E9E781C0048729D /* MGLMapViewDelegateIntegrationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MGLMapViewDelegateIntegrationTests.swift; sourceTree = ""; }; 40CF6DBA1DAC3C1800A4D18B /* MGLShape_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLShape_Private.h; sourceTree = ""; }; 40CFA6501D787579008103BD /* MGLShapeSourceTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLShapeSourceTests.mm; path = ../../darwin/test/MGLShapeSourceTests.mm; sourceTree = ""; }; + 40EA6BBD1EF4598900FCCDA2 /* api_mapbox_com-digicert_2017.der */ = {isa = PBXFileReference; lastKnownFileType = file; path = "api_mapbox_com-digicert_2017.der"; sourceTree = ""; }; + 40EA6BBE1EF4598900FCCDA2 /* api_mapbox_com-geotrust_2017.der */ = {isa = PBXFileReference; lastKnownFileType = file; path = "api_mapbox_com-geotrust_2017.der"; sourceTree = ""; }; 40EDA1BD1CFE0D4A00D9EA68 /* MGLAnnotationContainerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationContainerView.h; sourceTree = ""; }; 40EDA1BE1CFE0D4A00D9EA68 /* MGLAnnotationContainerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLAnnotationContainerView.m; sourceTree = ""; }; 40F8876F1D7A1DB8008ECB67 /* MGLShapeSource_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLShapeSource_Private.h; sourceTree = ""; }; @@ -1347,8 +1353,10 @@ DAC49C5F1CD02BC9009E1AA3 /* Localizable.stringsdict */, DA8933EF1CCD387900E68420 /* strip-frameworks.sh */, 40599F001DEE1B2400182B5D /* api_mapbox_staging.der */, - 40599F011DEE1B2400182B5D /* api_mapbox_com-digicert.der */, - 40599F021DEE1B2400182B5D /* api_mapbox_com-geotrust.der */, + 40599F011DEE1B2400182B5D /* api_mapbox_com-digicert_2016.der */, + 40599F021DEE1B2400182B5D /* api_mapbox_com-geotrust_2016.der */, + 40EA6BBD1EF4598900FCCDA2 /* api_mapbox_com-digicert_2017.der */, + 40EA6BBE1EF4598900FCCDA2 /* api_mapbox_com-geotrust_2017.der */, ); name = "Kit Resources"; path = resources; @@ -2069,9 +2077,11 @@ DA8933F01CCD387900E68420 /* strip-frameworks.sh in Resources */, DAC49C5C1CD02BC9009E1AA3 /* Localizable.stringsdict in Resources */, DA8933BF1CCD2CAD00E68420 /* Foundation.stringsdict in Resources */, + 40EA6BC11EF4599600FCCDA2 /* api_mapbox_com-digicert_2017.der in Resources */, 408982E91DEE208200754016 /* api_mapbox_staging.der in Resources */, - 408982EA1DEE208B00754016 /* api_mapbox_com-digicert.der in Resources */, - 408982EB1DEE209100754016 /* api_mapbox_com-geotrust.der in Resources */, + 408982EA1DEE208B00754016 /* api_mapbox_com-digicert_2016.der in Resources */, + 40EA6BC31EF4599D00FCCDA2 /* api_mapbox_com-geotrust_2017.der in Resources */, + 408982EB1DEE209100754016 /* api_mapbox_com-geotrust_2016.der in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2083,10 +2093,12 @@ DA8933DB1CCD31D400E68420 /* Foundation.strings in Resources */, 960D0C371ECF5AAF008E151F /* Images.xcassets in Resources */, DA8933DC1CCD31D400E68420 /* Foundation.stringsdict in Resources */, + 40EA6BC41EF4599D00FCCDA2 /* api_mapbox_com-geotrust_2017.der in Resources */, DAC49C5D1CD02BC9009E1AA3 /* Localizable.stringsdict in Resources */, 40599F0C1DEE1B7600182B5D /* api_mapbox_staging.der in Resources */, - 40599F0D1DEE1B7A00182B5D /* api_mapbox_com-digicert.der in Resources */, - 40599F0E1DEE1B7E00182B5D /* api_mapbox_com-geotrust.der in Resources */, + 40599F0D1DEE1B7A00182B5D /* api_mapbox_com-digicert_2016.der in Resources */, + 40599F0E1DEE1B7E00182B5D /* api_mapbox_com-geotrust_2016.der in Resources */, + 40EA6BC21EF4599700FCCDA2 /* api_mapbox_com-digicert_2017.der in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/platform/ios/resources/api_mapbox_com-digicert.der b/platform/ios/resources/api_mapbox_com-digicert.der deleted file mode 100644 index e8ef427f33..0000000000 Binary files a/platform/ios/resources/api_mapbox_com-digicert.der and /dev/null differ diff --git a/platform/ios/resources/api_mapbox_com-digicert_2016.der b/platform/ios/resources/api_mapbox_com-digicert_2016.der new file mode 100644 index 0000000000..e8ef427f33 Binary files /dev/null and b/platform/ios/resources/api_mapbox_com-digicert_2016.der differ diff --git a/platform/ios/resources/api_mapbox_com-digicert_2017.der b/platform/ios/resources/api_mapbox_com-digicert_2017.der new file mode 100644 index 0000000000..4a190085ab Binary files /dev/null and b/platform/ios/resources/api_mapbox_com-digicert_2017.der differ diff --git a/platform/ios/resources/api_mapbox_com-geotrust.der b/platform/ios/resources/api_mapbox_com-geotrust.der deleted file mode 100644 index 1c7331dedc..0000000000 Binary files a/platform/ios/resources/api_mapbox_com-geotrust.der and /dev/null differ diff --git a/platform/ios/resources/api_mapbox_com-geotrust_2016.der b/platform/ios/resources/api_mapbox_com-geotrust_2016.der new file mode 100644 index 0000000000..1c7331dedc Binary files /dev/null and b/platform/ios/resources/api_mapbox_com-geotrust_2016.der differ diff --git a/platform/ios/resources/api_mapbox_com-geotrust_2017.der b/platform/ios/resources/api_mapbox_com-geotrust_2017.der new file mode 100644 index 0000000000..7bb9befbbf Binary files /dev/null and b/platform/ios/resources/api_mapbox_com-geotrust_2017.der differ diff --git a/platform/ios/src/MGLAPIClient.m b/platform/ios/src/MGLAPIClient.m index 124d436197..8a987d76d8 100644 --- a/platform/ios/src/MGLAPIClient.m +++ b/platform/ios/src/MGLAPIClient.m @@ -17,8 +17,10 @@ static NSString * const MGLAPIClientHTTPMethodPost = @"POST"; @property (nonatomic, copy) NSURLSession *session; @property (nonatomic, copy) NSURL *baseURL; -@property (nonatomic, copy) NSData *digicertCert; -@property (nonatomic, copy) NSData *geoTrustCert; +@property (nonatomic, copy) NSData *digicertCert_2016; +@property (nonatomic, copy) NSData *geoTrustCert_2016; +@property (nonatomic, copy) NSData *digicertCert_2017; +@property (nonatomic, copy) NSData *geoTrustCert_2017; @property (nonatomic, copy) NSData *testServerCert; @property (nonatomic, copy) NSString *userAgent; @property (nonatomic) BOOL usesTestServer; @@ -107,10 +109,14 @@ static NSString * const MGLAPIClientHTTPMethodPost = @"POST"; - (void)loadCertificates { NSData *certificate; - [self loadCertificate:&certificate withResource:@"api_mapbox_com-geotrust"]; - self.geoTrustCert = certificate; - [self loadCertificate:&certificate withResource:@"api_mapbox_com-digicert"]; - self.digicertCert = certificate; + [self loadCertificate:&certificate withResource:@"api_mapbox_com-geotrust_2016"]; + self.geoTrustCert_2016 = certificate; + [self loadCertificate:&certificate withResource:@"api_mapbox_com-digicert_2016"]; + self.digicertCert_2016 = certificate; + [self loadCertificate:&certificate withResource:@"api_mapbox_com-geotrust_2017"]; + self.geoTrustCert_2017 = certificate; + [self loadCertificate:&certificate withResource:@"api_mapbox_com-digicert_2017"]; + self.digicertCert_2017 = certificate; [self loadCertificate:&certificate withResource:@"api_mapbox_staging"]; self.testServerCert = certificate; } @@ -141,75 +147,53 @@ static NSString * const MGLAPIClientHTTPMethodPost = @"POST"; #pragma mark NSURLSessionDelegate +- (BOOL)evaluateCertificateWithCertificateData:(NSData *)certificateData keyCount:(CFIndex)keyCount serverTrust:(SecTrustRef)serverTrust challenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^) (NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { + for (int lc = 0; lc < keyCount; lc++) { + SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, lc); + NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate)); + if ([remoteCertificateData isEqualToData:certificateData]) { + completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); + return YES; + } + } + return NO; +} + - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^) (NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { + if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { - SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust]; SecTrustResultType trustResult; - - // Validate the certificate chain with the device's trust store anyway - // This *might* give use revocation checking + + // Validate the certificate chain with the device's trust store anyway this *might* use revocation checking SecTrustEvaluate(serverTrust, &trustResult); - if (trustResult == kSecTrustResultUnspecified) - { + + BOOL found = NO; // For clarity; we start in a state where the challange has not been completed and no certificate has been found + + if (trustResult == kSecTrustResultUnspecified) { // Look for a pinned certificate in the server's certificate chain - long numKeys = SecTrustGetCertificateCount(serverTrust); - - BOOL found = NO; - // Try GeoTrust Cert First - for (int lc = 0; lc < numKeys; lc++) { - SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, lc); - NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate)); - - // Compare Remote Key With Local Version - if ([remoteCertificateData isEqualToData:_geoTrustCert]) { - // Found the certificate; continue connecting - completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); - found = YES; - break; - } + CFIndex numKeys = SecTrustGetCertificateCount(serverTrust); + + // Check certs in the following order: digicert 2016, digicert 2017, geotrust 2016, geotrust 2017 + found = [self evaluateCertificateWithCertificateData:self.digicertCert_2016 keyCount:numKeys serverTrust:serverTrust challenge:challenge completionHandler:completionHandler]; + if (!found) { + found = [self evaluateCertificateWithCertificateData:self.digicertCert_2017 keyCount:numKeys serverTrust:serverTrust challenge:challenge completionHandler:completionHandler]; } - if (!found) { - // Fallback to Digicert Cert - for (int lc = 0; lc < numKeys; lc++) { - SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, lc); - NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate)); - - // Compare Remote Key With Local Version - if ([remoteCertificateData isEqualToData:_digicertCert]) { - // Found the certificate; continue connecting - completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); - found = YES; - break; - } - } - - if (!found && _usesTestServer) { - // See if this is test server - for (int lc = 0; lc < numKeys; lc++) { - SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, lc); - NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate)); - - // Compare Remote Key With Local Version - if ([remoteCertificateData isEqualToData:_testServerCert]) { - // Found the certificate; continue connecting - completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); - found = YES; - break; - } - } - } - - if (!found) { - // The certificate wasn't found in GeoTrust nor Digicert. Cancel the connection. - completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); - } + found = [self evaluateCertificateWithCertificateData:self.geoTrustCert_2016 keyCount:numKeys serverTrust:serverTrust challenge:challenge completionHandler:completionHandler]; + } + if (!found) { + found = [self evaluateCertificateWithCertificateData:self.geoTrustCert_2017 keyCount:numKeys serverTrust:serverTrust challenge:challenge completionHandler:completionHandler]; + } + + // If challenge can't be completed with any of the above certs, then try the test server if the app is configured to use the test server + if (!found && _usesTestServer) { + found = [self evaluateCertificateWithCertificateData:self.testServerCert keyCount:numKeys serverTrust:serverTrust challenge:challenge completionHandler:completionHandler]; } } - else - { - // Certificate chain validation failed; cancel the connection + + if (!found) { + // No certificate was found so cancel the connection. completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); } } -- cgit v1.2.1 From f6bfa078af45701d4c62e6993cf83147636cede5 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 19 Jun 2017 12:26:58 -0700 Subject: [core] Trigger repaint on source changes --- src/mbgl/style/sources/geojson_source.cpp | 2 ++ src/mbgl/style/style.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/src/mbgl/style/sources/geojson_source.cpp b/src/mbgl/style/sources/geojson_source.cpp index 110c1cd63c..992f82b1e7 100644 --- a/src/mbgl/style/sources/geojson_source.cpp +++ b/src/mbgl/style/sources/geojson_source.cpp @@ -1,5 +1,6 @@ #include #include +#include namespace mbgl { namespace style { @@ -16,6 +17,7 @@ void GeoJSONSource::setURL(const std::string& url) { void GeoJSONSource::setGeoJSON(const mapbox::geojson::geojson& geoJSON) { impl->setGeoJSON(geoJSON); + impl->observer->onSourceChanged(*this); } optional GeoJSONSource::getURL() const { diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index 568b575dfa..f1ac22082b 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -725,6 +725,7 @@ void Style::onSourceLoaded(Source& source) { void Style::onSourceChanged(Source& source) { observer->onSourceChanged(source); + observer->onUpdate(Update::Repaint); } void Style::onSourceError(Source& source, std::exception_ptr error) { -- cgit v1.2.1 From 78322a3f16ba996dfbcb3acc74d9db31d4d0cd69 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Tue, 20 Jun 2017 09:16:55 +0200 Subject: [android] - update activity test generation with newest classes, make FillExtrusionActivity conform to generated activity test setup. (#9276) --- .../mapboxsdk/testapp/activity/style/FillExtrusionActivity.java | 9 +++++---- platform/android/scripts/generate-test-code.js | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/FillExtrusionActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/FillExtrusionActivity.java index 9a7790c6e5..52ba8d7c7b 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/FillExtrusionActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/FillExtrusionActivity.java @@ -26,6 +26,7 @@ import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionOpa public class FillExtrusionActivity extends AppCompatActivity { private MapView mapView; + private MapboxMap mapboxMap; @Override public void onCreate(Bundle savedInstanceState) { @@ -36,8 +37,8 @@ public class FillExtrusionActivity extends AppCompatActivity { mapView.onCreate(savedInstanceState); mapView.getMapAsync(new OnMapReadyCallback() { @Override - public void onMapReady(@NonNull - final MapboxMap map) { + public void onMapReady(@NonNull final MapboxMap map) { + mapboxMap = map; Polygon domTower = Polygon.fromCoordinates(new double[][][] { new double[][] { new double[] { @@ -66,7 +67,7 @@ public class FillExtrusionActivity extends AppCompatActivity { GeoJsonSource source = new GeoJsonSource("extrusion-source", domTower); map.addSource(source); - map.addLayer( + mapboxMap.addLayer( new FillExtrusionLayer("extrusion-layer", source.getId()) .withProperties( fillExtrusionHeight(40f), @@ -75,7 +76,7 @@ public class FillExtrusionActivity extends AppCompatActivity { ) ); - map.animateCamera( + mapboxMap.animateCamera( CameraUpdateFactory.newCameraPosition( new CameraPosition.Builder() .target(new LatLng(52.09071040847704, 5.12112557888031)) diff --git a/platform/android/scripts/generate-test-code.js b/platform/android/scripts/generate-test-code.js index b054e4a2e7..01a294a301 100644 --- a/platform/android/scripts/generate-test-code.js +++ b/platform/android/scripts/generate-test-code.js @@ -14,7 +14,7 @@ global.camelize = function (str) { } -const excludeActivities = ["DeleteRegionActivity","RealTimeGeoJsonActivity","UpdateMetadataActivity","CarDrivingActivity","MyLocationTrackingModeActivity","MyLocationToggleActivity","MyLocationTintActivity","MyLocationDrawableActivity","DoubleMapActivity", "LocationPickerActivity","GeoJsonClusteringActivity","RuntimeStyleTestActivity", "AnimatedMarkerActivity", "ViewPagerActivity","MapFragmentActivity","SupportMapFragmentActivity","SnapshotActivity","NavigationDrawerActivity", "QueryRenderedFeaturesBoxHighlightActivity", "MultiMapActivity", "MapInDialogActivity", "SimpleMapActivity"]; +const excludeActivities = ["BaseLocationActivity","MockLocationEngine","DeleteRegionActivity","RealTimeGeoJsonActivity","UpdateMetadataActivity","CarDrivingActivity","MyLocationTrackingModeActivity","MyLocationToggleActivity","MyLocationTintActivity","MyLocationDrawableActivity","DoubleMapActivity", "LocationPickerActivity","GeoJsonClusteringActivity","RuntimeStyleTestActivity", "AnimatedMarkerActivity", "ViewPagerActivity","MapFragmentActivity","SupportMapFragmentActivity","SnapshotActivity","NavigationDrawerActivity", "QueryRenderedFeaturesBoxHighlightActivity", "MultiMapActivity", "MapInDialogActivity", "SimpleMapActivity"]; const appBasePath = 'platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity'; const testBasePath = 'platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen'; const subPackages = fs.readdirSync(appBasePath); -- cgit v1.2.1 From 399c0071f856ad162905f32aa6516516ee59c7b1 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Tue, 20 Jun 2017 09:17:09 +0200 Subject: Validate camera position before transforming (#9275) * [android] - add camera position validation before transforming * annotate CameraUpdate with nullability --- .../main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java | 2 ++ .../src/main/java/com/mapbox/mapboxsdk/maps/Transform.java | 10 +++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java index 7e0dbf08fb..498aa8343b 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java @@ -1,6 +1,7 @@ package com.mapbox.mapboxsdk.camera; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import com.mapbox.mapboxsdk.maps.MapboxMap; @@ -9,6 +10,7 @@ import com.mapbox.mapboxsdk.maps.MapboxMap; */ public interface CameraUpdate { + @Nullable CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java index 505e440dcb..89fbb79504 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java @@ -93,7 +93,7 @@ final class Transform implements MapView.OnMapChangedListener { @UiThread final void moveCamera(MapboxMap mapboxMap, CameraUpdate update, MapboxMap.CancelableCallback callback) { CameraPosition cameraPosition = update.getCameraPosition(mapboxMap); - if (!cameraPosition.equals(this.cameraPosition)) { + if (isValidCameraPosition(cameraPosition)) { trackingSettings.resetTrackingModesIfRequired(this.cameraPosition, cameraPosition, false); cancelTransitions(); cameraChangeDispatcher.onCameraMoveStarted(OnCameraMoveStartedListener.REASON_API_ANIMATION); @@ -109,7 +109,7 @@ final class Transform implements MapView.OnMapChangedListener { final void easeCamera(MapboxMap mapboxMap, CameraUpdate update, int durationMs, boolean easingInterpolator, final MapboxMap.CancelableCallback callback, boolean isDismissable) { CameraPosition cameraPosition = update.getCameraPosition(mapboxMap); - if (!cameraPosition.equals(this.cameraPosition)) { + if (isValidCameraPosition(cameraPosition)) { trackingSettings.resetTrackingModesIfRequired(this.cameraPosition, cameraPosition, isDismissable); cancelTransitions(); cameraChangeDispatcher.onCameraMoveStarted(OnCameraMoveStartedListener.REASON_API_ANIMATION); @@ -127,7 +127,7 @@ final class Transform implements MapView.OnMapChangedListener { final void animateCamera(MapboxMap mapboxMap, CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) { CameraPosition cameraPosition = update.getCameraPosition(mapboxMap); - if (!cameraPosition.equals(this.cameraPosition)) { + if (isValidCameraPosition(cameraPosition)) { trackingSettings.resetTrackingModesIfRequired(this.cameraPosition, cameraPosition, false); cancelTransitions(); cameraChangeDispatcher.onCameraMoveStarted(OnCameraMoveStartedListener.REASON_API_ANIMATION); @@ -141,6 +141,10 @@ final class Transform implements MapView.OnMapChangedListener { } } + private boolean isValidCameraPosition(@Nullable CameraPosition cameraPosition) { + return cameraPosition != null && !cameraPosition.equals(this.cameraPosition); + } + @UiThread @Nullable CameraPosition invalidateCameraPosition() { -- cgit v1.2.1 From 20cb791b4ca1b449157d8ea02f256807dd7bc9f3 Mon Sep 17 00:00:00 2001 From: Pablo Guardiola Date: Tue, 20 Jun 2017 09:24:07 +0200 Subject: [android] fix custom marker views anchor issue (#9282) --- .../mapboxsdk/annotations/MarkerViewManager.java | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java index bb51f3bfc2..b9e9bea4ed 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java @@ -10,6 +10,7 @@ import android.support.v4.util.LongSparseArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.ViewTreeObserver; import android.widget.ImageView; import com.mapbox.mapboxsdk.R; @@ -33,6 +34,15 @@ import java.util.Map; public class MarkerViewManager implements MapView.OnMapChangedListener { private final ViewGroup markerViewContainer; + private final ViewTreeObserver.OnPreDrawListener markerViewPreDrawObserver = + new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + invalidateViewMarkersInVisibleRegion(); + markerViewContainer.getViewTreeObserver().removeOnPreDrawListener(markerViewPreDrawObserver); + return false; + } + }; private final Map markerViewMap = new HashMap<>(); private final LongSparseArray markerViewAddedListenerMap = new LongSparseArray<>(); private final List markerViewAdapters = new ArrayList<>(); @@ -180,14 +190,16 @@ public class MarkerViewManager implements MapView.OnMapChangedListener { PointF point = mapboxMap.getProjection().toScreenLocation(marker.getPosition()); if (marker.getOffsetX() == MapboxConstants.UNMEASURED) { // ensure view is measured first + // #6805 invalidate marker views to ensure convertView width and height + // values are properly measured and up to date if (marker.getWidth() == 0) { - convertView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); - if (convertView.getMeasuredWidth() != 0) { - marker.setWidth(convertView.getMeasuredWidth()); - marker.setHeight(convertView.getMeasuredHeight()); - } + convertView.getViewTreeObserver().addOnPreDrawListener(markerViewPreDrawObserver); } } + + marker.setWidth(convertView.getWidth()); + marker.setHeight(convertView.getHeight()); + if (marker.getWidth() != 0) { int x = (int) (marker.getAnchorU() * marker.getWidth()); int y = (int) (marker.getAnchorV() * marker.getHeight()); -- cgit v1.2.1 From 985ff4cc1883d606b3770a34d384ade71f71bbdc Mon Sep 17 00:00:00 2001 From: Pablo Guardiola Date: Tue, 20 Jun 2017 09:24:43 +0200 Subject: [android] fix pulse marker view options parcelable creator (#9283) --- .../testapp/model/annotations/PulseMarkerViewOptions.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/PulseMarkerViewOptions.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/PulseMarkerViewOptions.java index d9c6357774..d752e5d0ef 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/PulseMarkerViewOptions.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/PulseMarkerViewOptions.java @@ -66,14 +66,14 @@ public class PulseMarkerViewOptions extends BaseMarkerViewOptions CREATOR - = new Parcelable.Creator() { - public CountryMarkerViewOptions createFromParcel(Parcel in) { - return new CountryMarkerViewOptions(in); + public static final Parcelable.Creator CREATOR + = new Parcelable.Creator() { + public PulseMarkerViewOptions createFromParcel(Parcel in) { + return new PulseMarkerViewOptions(in); } - public CountryMarkerViewOptions[] newArray(int size) { - return new CountryMarkerViewOptions[size]; + public PulseMarkerViewOptions[] newArray(int size) { + return new PulseMarkerViewOptions[size]; } }; } -- cgit v1.2.1 From 78426f1423ad3b739d7f7fa1fd7f248146281fa2 Mon Sep 17 00:00:00 2001 From: Pablo Guardiola Date: Tue, 20 Jun 2017 10:01:02 +0200 Subject: fix trackball long press timeout calling the main thread method on a background thread (#9305) --- .../src/main/java/com/mapbox/mapboxsdk/maps/MapKeyListener.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapKeyListener.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapKeyListener.java index 7175242282..d1f01a30f7 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapKeyListener.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapKeyListener.java @@ -2,6 +2,7 @@ package com.mapbox.mapboxsdk.maps; import android.graphics.PointF; import android.os.Handler; +import android.os.Looper; import android.support.annotation.NonNull; import android.view.KeyEvent; import android.view.MotionEvent; @@ -204,7 +205,7 @@ final class MapKeyListener { currentTrackballLongPressTimeOut = null; } currentTrackballLongPressTimeOut = new TrackballLongPressTimeOut(); - new Handler().postDelayed(currentTrackballLongPressTimeOut, + new Handler(Looper.getMainLooper()).postDelayed(currentTrackballLongPressTimeOut, ViewConfiguration.getLongPressTimeout()); return true; -- cgit v1.2.1 From 899d2b0de931ca1a7295cce35dc7cfb177a5d14b Mon Sep 17 00:00:00 2001 From: Antonio Zugaldia Date: Tue, 20 Jun 2017 08:59:15 -0400 Subject: [android] Update to LOST 3.0.1 (#9302) --- platform/android/dependencies.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/android/dependencies.gradle b/platform/android/dependencies.gradle index e71e077104..9c40e72bf6 100644 --- a/platform/android/dependencies.gradle +++ b/platform/android/dependencies.gradle @@ -21,7 +21,7 @@ ext { mapboxAndroidTelemetry : "com.mapbox.mapboxsdk:mapbox-android-telemetry:${mapboxServicesVersion}@aar", // mapzen lost - lost : 'com.mapzen.android:lost:3.0.1-20170607.212149-4', + lost : 'com.mapzen.android:lost:3.0.1', // unit test junit : 'junit:junit:4.12', -- cgit v1.2.1 From a9f52e24e63af6d322b3f4744a38aab395344b1d Mon Sep 17 00:00:00 2001 From: Tobrun Date: Tue, 20 Jun 2017 15:48:24 +0200 Subject: Revisit Javadoc for 5.1.0 (#9266) * [android] - revisit public API javadoc * [android] fix javadoc minor mistakes and typos * grammar tweak * add missing public javadoc --- .../src/main/java/com/mapbox/mapboxsdk/Mapbox.java | 7 +- .../mapbox/mapboxsdk/annotations/BubbleLayout.java | 106 +++++++++++++++ .../mapbox/mapboxsdk/annotations/IconFactory.java | 46 ++++--- .../mapboxsdk/annotations/MarkerViewManager.java | 19 ++- .../mapbox/mapboxsdk/camera/CameraPosition.java | 60 +++++---- .../com/mapbox/mapboxsdk/camera/CameraUpdate.java | 8 +- .../mapboxsdk/camera/CameraUpdateFactory.java | 4 +- .../mapboxsdk/constants/MyBearingTracking.java | 14 +- .../mapboxsdk/constants/MyLocationTracking.java | 19 ++- .../java/com/mapbox/mapboxsdk/constants/Style.java | 1 - .../exceptions/IconBitmapChangedException.java | 6 +- .../exceptions/InvalidLatLngBoundsException.java | 4 +- .../exceptions/InvalidMarkerPositionException.java | 3 + .../exceptions/MapboxConfigurationException.java | 4 + .../exceptions/TooManyIconsException.java | 5 +- .../com/mapbox/mapboxsdk/geometry/ILatLng.java | 18 ++- .../mapboxsdk/geometry/IProjectedMeters.java | 12 ++ .../java/com/mapbox/mapboxsdk/geometry/LatLng.java | 116 ++++++++++++++-- .../mapbox/mapboxsdk/geometry/LatLngBounds.java | 148 +++++++++++++------- .../com/mapbox/mapboxsdk/geometry/LatLngSpan.java | 46 ++++++- .../mapbox/mapboxsdk/geometry/ProjectedMeters.java | 45 ++++++- .../mapbox/mapboxsdk/geometry/VisibleRegion.java | 31 ++++- .../mapbox/mapboxsdk/location/LocationSource.java | 8 +- .../java/com/mapbox/mapboxsdk/maps/MapView.java | 30 ++--- .../java/com/mapbox/mapboxsdk/maps/MapboxMap.java | 30 +++-- .../mapbox/mapboxsdk/maps/MapboxMapOptions.java | 6 +- .../java/com/mapbox/mapboxsdk/maps/UiSettings.java | 12 +- .../mapboxsdk/maps/widgets/MyLocationView.java | 150 ++++++++++++++++++++- .../maps/widgets/MyLocationViewSettings.java | 7 +- .../mapbox/mapboxsdk/net/ConnectivityReceiver.java | 7 +- .../mapbox/mapboxsdk/offline/OfflineManager.java | 6 + .../mapbox/mapboxsdk/offline/OfflineRegion.java | 1 + .../mapboxsdk/offline/OfflineRegionStatus.java | 60 ++++++++- .../com/mapbox/mapboxsdk/storage/FileSource.java | 19 ++- .../mapboxsdk/style/layers/PropertyValue.java | 30 +++++ .../com/mapbox/mapboxsdk/style/light/Light.java | 22 ++- .../com/mapbox/mapboxsdk/style/light/Position.java | 4 +- .../mapbox/mapboxsdk/style/light/light.java.ejs | 2 +- .../com/mapbox/mapboxsdk/utils/BitmapUtils.java | 16 +++ .../com/mapbox/mapboxsdk/utils/ColorUtils.java | 10 +- .../mapbox/mapboxsdk/utils/MapFragmentUtils.java | 13 ++ 41 files changed, 940 insertions(+), 215 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java index 17cd4e0dce..6722000be7 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java @@ -1,6 +1,5 @@ package com.mapbox.mapboxsdk; -import android.app.Application; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; @@ -17,10 +16,10 @@ import com.mapbox.services.android.telemetry.location.LocationEngine; import com.mapbox.services.android.telemetry.location.LocationEnginePriority; /** - * The entry point of the Mapbox Android SDK. + * The entry point to initialize the Mapbox Android SDK. *

      * Obtain a reference by calling {@link #getInstance(Context, String)}. Usually this class is configured in - * {@link Application#onCreate()} and is responsible for the active access token, application context, and + * Application#onCreate() and is responsible for the active access token, application context, and * connectivity state. *

      */ @@ -97,6 +96,8 @@ public final class Mapbox { /** * Application context + * + * @return the application context */ public static Context getApplicationContext() { return INSTANCE.context; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BubbleLayout.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BubbleLayout.java index 07e038c08c..c58cc310a8 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BubbleLayout.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BubbleLayout.java @@ -27,14 +27,32 @@ public class BubbleLayout extends LinearLayout { private float strokeWidth; private int strokeColor; + /** + * Creates an instance of bubble layout. + * + * @param context The context used to inflate this bubble layout + */ public BubbleLayout(Context context) { this(context, null, 0); } + /** + * Creates an instance of bubble layout. + * + * @param context The context used to inflate this bubble layout + * @param attrs The attribute set to initialise this bubble layout from + */ public BubbleLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } + /** + * Creates an instance of bubble layout. + * + * @param context The context used to inflate this bubble layout + * @param attrs The attribute set to initialise this bubble layout from + * @param defStyleAttr The default style to apply this bubble layout with + */ public BubbleLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); @@ -78,10 +96,21 @@ public class BubbleLayout extends LinearLayout { return dp * (metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT); } + /** + * Get the arrow direction. + * + * @return the arrow direction + */ public ArrowDirection getArrowDirection() { return arrowDirection; } + /** + * Set the arrow direction. + * + * @param arrowDirection The direction of the arrow + * @return this + */ public BubbleLayout setArrowDirection(ArrowDirection arrowDirection) { resetPadding(); this.arrowDirection = arrowDirection; @@ -89,10 +118,21 @@ public class BubbleLayout extends LinearLayout { return this; } + /** + * Get the arrow width. + * + * @return the width of the arrow + */ public float getArrowWidth() { return arrowWidth; } + /** + * Set the arrow width. + * + * @param arrowWidth The width of the arrow + * @return this + */ public BubbleLayout setArrowWidth(float arrowWidth) { resetPadding(); this.arrowWidth = arrowWidth; @@ -100,10 +140,21 @@ public class BubbleLayout extends LinearLayout { return this; } + /** + * Get the arrow height + * + * @return the height of the arrow + */ public float getArrowHeight() { return arrowHeight; } + /** + * Set the arrow height. + * + * @param arrowHeight The height of the arrow + * @return this + */ public BubbleLayout setArrowHeight(float arrowHeight) { resetPadding(); this.arrowHeight = arrowHeight; @@ -111,10 +162,21 @@ public class BubbleLayout extends LinearLayout { return this; } + /** + * Get the arrow position. + * + * @return the arrow position + */ public float getArrowPosition() { return arrowPosition; } + /** + * Get the arrow position. + * + * @param arrowPosition The arrow position + * @return this + */ public BubbleLayout setArrowPosition(float arrowPosition) { resetPadding(); this.arrowPosition = arrowPosition; @@ -122,30 +184,63 @@ public class BubbleLayout extends LinearLayout { return this; } + /** + * Get the corner radius + * + * @return the corner radius + */ public float getCornersRadius() { return cornersRadius; } + /** + * Set the corner radius + * + * @param cornersRadius The corner radius + * @return this + */ public BubbleLayout setCornersRadius(float cornersRadius) { this.cornersRadius = cornersRadius; requestLayout(); return this; } + /** + * Get the bubble color. + * + * @return the bubble color + */ public int getBubbleColor() { return bubbleColor; } + /** + * Set the bubble color. + * + * @param bubbleColor The buble color + * @return this + */ public BubbleLayout setBubbleColor(int bubbleColor) { this.bubbleColor = bubbleColor; requestLayout(); return this; } + /** + * Get stroke width. + * + * @return the stroke width + */ public float getStrokeWidth() { return strokeWidth; } + /** + * Set the stroke width. + * + * @param strokeWidth The stroke width + * @return this + */ public BubbleLayout setStrokeWidth(float strokeWidth) { resetPadding(); this.strokeWidth = strokeWidth; @@ -153,10 +248,21 @@ public class BubbleLayout extends LinearLayout { return this; } + /** + * Get the stroke color. + * + * @return the stroke color + */ public int getStrokeColor() { return strokeColor; } + /** + * Set the stroke color. + * + * @param strokeColor The stroke color + * @return this + */ public BubbleLayout setStrokeColor(int strokeColor) { this.strokeColor = strokeColor; requestLayout(); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java index 57aa512401..f9ca9bf4cc 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java @@ -23,7 +23,7 @@ import java.io.InputStream; /** * Factory for creating Icons from bitmap images. *

      - * {@link Icon} is used to display bitmaps on top of the map using {@link Marker} and {@link MarkerView}. + * icon is used to display bitmaps on top of the map using {@link Marker} and {@link MarkerView}. *

      * * @see Icon @@ -42,6 +42,12 @@ public final class IconFactory { private int nextId = 0; + /** + * Get a single instance of IconFactory. + * + * @param context the context to derive the application context from + * @return the single instance of IconFactory + */ public static synchronized IconFactory getInstance(@NonNull Context context) { if (instance == null) { instance = new IconFactory(context.getApplicationContext()); @@ -71,10 +77,10 @@ public final class IconFactory { } /** - * Creates an {@link Icon} from a given Bitmap image. + * Creates an icon from a given Bitmap image. * * @param bitmap image used for creating the Icon. - * @return The {@link Icon} using the given Bitmap image. + * @return The icon using the given Bitmap image. */ public Icon fromBitmap(@NonNull Bitmap bitmap) { if (nextId < 0) { @@ -85,10 +91,10 @@ public final class IconFactory { } /** - * Create an {@link Icon} using the resource ID of a Bitmap image. + * Creates an icon using the resource ID of a Bitmap image. * * @param resourceId The resource ID of a Bitmap image. - * @return The {@link Icon} that was loaded from the asset or {@code null} if failed to load. + * @return The icon that was loaded from the asset or {@code null} if failed to load. */ public Icon fromResource(@DrawableRes int resourceId) { Drawable drawable = ContextCompat.getDrawable(context, resourceId); @@ -101,9 +107,9 @@ public final class IconFactory { } /** - * Provides an {@link Icon} using the default marker icon used for {@link Marker}. + * Provides an icon using the default marker icon used for {@link Marker}. * - * @return An {@link Icon} with the default {@link Marker} icon. + * @return An icon with the default {@link Marker} icon. */ public Icon defaultMarker() { if (defaultMarker == null) { @@ -113,9 +119,9 @@ public final class IconFactory { } /** - * Provides an {@link Icon} using the default marker icon used for {@link MarkerView}. + * Provides an icon using the default marker icon used for {@link MarkerView}. * - * @return An {@link Icon} with the default {@link MarkerView} icon. + * @return An icon with the default {@link MarkerView} icon. */ public Icon defaultMarkerView() { if (defaultMarkerView == null) { @@ -130,10 +136,10 @@ public final class IconFactory { } /** - * Creates an {@link Icon} using the name of a Bitmap image in the assets directory. + * Creates an Icon using the name of a Bitmap image in the assets directory. * * @param assetName The name of a Bitmap image in the assets directory. - * @return The {@link Icon} that was loaded from the asset or {@code null} if failed to load. + * @return The Icon that was loaded from the asset or null if failed to load. */ public Icon fromAsset(@NonNull String assetName) { InputStream is; @@ -146,11 +152,10 @@ public final class IconFactory { } /** - * Creates an {@link Icon} using the absolute file path of a Bitmap image. + * Creates an Icon using the absolute file path of a Bitmap image. * * @param absolutePath The absolute path of the Bitmap image. - * @return The {@link Icon} that was loaded from the absolute path or {@code null} if failed to - * load. + * @return The Icon that was loaded from the absolute path or null if failed to load. */ public Icon fromPath(@NonNull String absolutePath) { Bitmap bitmap = BitmapFactory.decodeFile(absolutePath, options); @@ -158,11 +163,11 @@ public final class IconFactory { } /** - * Create an {@link Icon} using the name of a Bitmap image file located in the internal storage. - * In particular, this calls {@link Context#openFileInput(String)}. + * Create an Icon using the name of a Bitmap image file located in the internal storage. + * In particular, this calls Context#openFileInput(String). * * @param fileName The name of the Bitmap image file. - * @return The {@link Icon} that was loaded from the asset or {@code null} if failed to load. + * @return The Icon that was loaded from the asset or null if failed to load. * @see * Using the Internal Storage */ @@ -177,12 +182,11 @@ public final class IconFactory { } /** - * Create an {@link Icon} using a previously created icon identifier along with a provided - * Bitmap. + * Create an Icon using a previously created icon identifier along with a provided Bitmap. * - * @param iconId The {@link Icon} identifier you'd like to recreate. + * @param iconId The Icon identifier you'd like to recreate. * @param bitmap a Bitmap used to replace the current one. - * @return The {@link Icon} using the new Bitmap. + * @return The Icon using the new Bitmap. */ public static Icon recreate(@NonNull String iconId, @NonNull Bitmap bitmap) { return new Icon(iconId, bitmap); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java index b9e9bea4ed..6d42842b7d 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java @@ -135,6 +135,12 @@ public class MarkerViewManager implements MapView.OnMapChangedListener { } } + /** + * Set the rotation of a MarkerView to a given rotation value. + * + * @param marker The MarkerView to change its rotation value + * @param rotation The rotation value + */ public void setRotation(@NonNull MarkerView marker, float rotation) { View convertView = markerViewMap.get(marker); if (convertView != null) { @@ -544,10 +550,11 @@ public class MarkerViewManager implements MapView.OnMapChangedListener { } /** - * When the provided {@link MarkerView} is clicked on by a user, we check if a custom click - * event has been created and if not, display a {@link InfoWindow}. + * When the provided MarkerView is clicked on by a user, we check if a custom click + * event has been created and if not, display a InfoWindow. * - * @param markerView that the click event occurred. + * @param markerView that the click event occurred + * @return true if the marker view click has been handled, false if not */ public boolean onClickMarkerView(MarkerView markerView) { boolean clickHandled = false; @@ -572,9 +579,9 @@ public class MarkerViewManager implements MapView.OnMapChangedListener { } /** - * Handles the {@link MarkerView}'s info window offset. + * Handles the MarkerView info window offset. * - * @param marker that we are ensuring info window offset. + * @param marker that we are ensuring info window offset */ public void ensureInfoWindowOffset(MarkerView marker) { View view = null; @@ -624,7 +631,7 @@ public class MarkerViewManager implements MapView.OnMapChangedListener { } /** - * Default MarkerViewAdapter used for base class of {@link MarkerView} to adapt a MarkerView to + * Default MarkerViewAdapter used for base class of MarkerView to adapt a MarkerView to * an ImageView. */ private static class ImageMarkerViewAdapter extends MapboxMap.MarkerViewAdapter { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java index 66c261f1d0..c2f19072db 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java @@ -3,6 +3,7 @@ package com.mapbox.mapboxsdk.camera; import android.content.res.TypedArray; import android.os.Parcel; import android.os.Parcelable; +import android.support.annotation.FloatRange; import com.mapbox.mapboxsdk.R; import com.mapbox.mapboxsdk.constants.MapboxConstants; @@ -166,14 +167,14 @@ public final class CameraPosition implements Parcelable { private double zoom = -1; /** - * Creates an empty builder. + * Create an empty builder. */ public Builder() { super(); } /** - * Create Builder with an existing CameraPosition data. + * Create a builder with an existing CameraPosition data. * * @param previous Existing CameraPosition values to use */ @@ -188,7 +189,7 @@ public final class CameraPosition implements Parcelable { } /** - * Create Builder with an existing CameraPosition data. + * Create a builder with an existing CameraPosition data. * * @param typedArray TypedArray containing attribute values */ @@ -205,7 +206,7 @@ public final class CameraPosition implements Parcelable { } /** - * Create Builder from an existing CameraPositionUpdate update. + * Create a builder from an existing CameraPositionUpdate update. * * @param update Update containing camera options */ @@ -220,7 +221,7 @@ public final class CameraPosition implements Parcelable { } /** - * Create Builder from an existing CameraPositionUpdate update. + * Create builder from an existing CameraPositionUpdate update. * * @param update Update containing camera options */ @@ -235,7 +236,7 @@ public final class CameraPosition implements Parcelable { * Sets the direction that the camera is pointing in, in degrees clockwise from north. * * @param bearing Bearing - * @return Builder + * @return this */ public Builder bearing(double bearing) { double direction = bearing; @@ -252,19 +253,10 @@ public final class CameraPosition implements Parcelable { } /** - * Builds a CameraPosition. + * Sets the location where the camera is pointing at. * - * @return CameraPosition - */ - public CameraPosition build() { - return new CameraPosition(target, zoom, tilt, bearing); - } - - /** - * Sets the location that the camera is pointing at. - * - * @param location Location - * @return Builder + * @param location target of the camera + * @return this */ public Builder target(LatLng location) { this.target = location; @@ -272,28 +264,42 @@ public final class CameraPosition implements Parcelable { } /** - * Set the tilt in degrees + * Set the tilt of the camera in degrees *

      - * value is clamped to 0 and 60. + * value is clamped to {@link MapboxConstants#MINIMUM_TILT} and {@link MapboxConstants#MAXIMUM_TILT}. *

      * - * @param tilt Tilt value - * @return Builder + * @param tilt Tilt value of the camera + * @return this */ - public Builder tilt(double tilt) { + public Builder tilt(@FloatRange(from = MapboxConstants.MINIMUM_TILT, + to = MapboxConstants.MAXIMUM_TILT) double tilt) { this.tilt = MathUtils.clamp(tilt, MapboxConstants.MINIMUM_TILT, MapboxConstants.MAXIMUM_TILT); return this; } /** - * Set the zoom + * Set the zoom of the camera + *

      + * Zoom ranges from {@link MapboxConstants#MINIMUM_ZOOM} to {@link MapboxConstants#MAXIMUM_ZOOM} + *

      * - * @param zoom Zoom value - * @return Builder + * @param zoom Zoom value of the camera + * @return this */ - public Builder zoom(double zoom) { + public Builder zoom(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM, + to = MapboxConstants.MAXIMUM_ZOOM) double zoom) { this.zoom = zoom; return this; } + + /** + * Builds the CameraPosition. + * + * @return CameraPosition + */ + public CameraPosition build() { + return new CameraPosition(target, zoom, tilt, bearing); + } } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java index 498aa8343b..31f13cbcff 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java @@ -6,10 +6,16 @@ import android.support.annotation.Nullable; import com.mapbox.mapboxsdk.maps.MapboxMap; /** - * Interface definition for camera position changes. + * Interface definition for camera updates. */ public interface CameraUpdate { + /** + * Get the camera position from the camera update. + * + * @param mapboxMap Map object to build the position from + * @return the camera position from the implementing camera update + */ @Nullable CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java index 8e1411e273..50e33f4f9f 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java @@ -42,7 +42,7 @@ public final class CameraUpdateFactory { } /** - * Returns a {@link CameraUpdate} that transforms the camera such that the specified + * Returns a CameraUpdate that transforms the camera such that the specified * latitude/longitude bounds are centered on screen at the greatest possible zoom level. * You can specify padding, in order to inset the bounding box from the map view's edges. * The returned CameraUpdate has a bearing of 0 and a tilt of 0. @@ -56,7 +56,7 @@ public final class CameraUpdateFactory { } /** - * Returns a {@link CameraUpdate} that transforms the camera such that the specified + * Returns a CameraUpdate that transforms the camera such that the specified * latitude/longitude bounds are centered on screen at the greatest possible zoom level. * You can specify padding, in order to inset the bounding box from the map view's edges. * The returned CameraUpdate has a bearing of 0 and a tilt of 0. diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java index 88c3bef673..ceac862f39 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java @@ -2,23 +2,27 @@ package com.mapbox.mapboxsdk.constants; import android.support.annotation.IntDef; +import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.widgets.MyLocationView; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** - * MyBearingTracking exposes different types bearing tracking modes. + * MyBearingTracking exposes different types of bearing tracking modes. + *

      + * These modes visualise the user direction by extracting the direction from either sensor or location data. + *

      + *

      + * Required to enable showing the user location first through {@link MapboxMap#setMyLocationEnabled(boolean)}. + *

      * * @see com.mapbox.mapboxsdk.maps.TrackingSettings#setMyBearingTrackingMode(int) * @see MyLocationView#setMyBearingTrackingMode(int) */ public class MyBearingTracking { - /** - * Indicates that the parameter accepts one of the values from MyBearingTracking. - */ - @IntDef( {NONE, COMPASS, GPS, /**COMBINED**/}) + @IntDef( {NONE, COMPASS, GPS}) @Retention(RetentionPolicy.SOURCE) public @interface Mode { } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java index a1744d701f..1283283fa5 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java @@ -3,29 +3,34 @@ package com.mapbox.mapboxsdk.constants; import android.support.annotation.IntDef; import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.TrackingSettings; import com.mapbox.mapboxsdk.maps.widgets.MyLocationView; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** - * MyLocationTracking exposes different types of locational tracking modes. + * MyLocationTracking exposes types of location tracking modes. + * *

      + * This allows tracking the user location on screen by updating the camera position when a location update occurs. + *

      + *

      + * Required to enable showing the user location first through {@link MapboxMap#setMyLocationEnabled(boolean)}. + *

      * - * @see com.mapbox.mapboxsdk.maps.TrackingSettings#setMyLocationTrackingMode(int) - * @see MyLocationView#setMyLocationTrackingMode(int) + * @see MapboxMap#setMyLocationEnabled(boolean) + * @see TrackingSettings#setMyLocationTrackingMode(int) */ public class MyLocationTracking { - /** - * Indicates the parameter accepts one of the values from MyLocationTracking. - */ @IntDef( {TRACKING_NONE, TRACKING_FOLLOW}) @Retention(RetentionPolicy.SOURCE) public @interface Mode { } /** - * Location tracking is disabled. + * Tracking the location of the user is disabled. */ public static final int TRACKING_NONE = 0x00000000; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java index 31e6313509..9943a72e06 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java @@ -17,7 +17,6 @@ import java.lang.annotation.RetentionPolicy; */ public class Style { - /** * Indicates the parameter accepts one of the values from Style. Using one of these * constants means your map style will always use the latest version and may change as we diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/IconBitmapChangedException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/IconBitmapChangedException.java index 7154049bd7..1f6b0efc4d 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/IconBitmapChangedException.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/IconBitmapChangedException.java @@ -1,15 +1,13 @@ package com.mapbox.mapboxsdk.exceptions; -import android.graphics.Bitmap; - import com.mapbox.mapboxsdk.annotations.Icon; import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.maps.MapView; /** *

      - * A {@code IconBitmapChangedException} is thrown by {@link MapView} when a {@link Marker} is added - * that has a {@link Icon} with a {@link Bitmap} that has been modified since the creation of the Icon. + * An IconBitmapChangedException is thrown by MapView when a Marker is added + * that has an Icon with a Bitmap that has been modified since the creation of the Icon. *

      * You cannot modify a {@code Icon} after it has been added to the map in a {@code Marker} * diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidLatLngBoundsException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidLatLngBoundsException.java index 08a23a7373..c1d0385815 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidLatLngBoundsException.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidLatLngBoundsException.java @@ -1,8 +1,8 @@ package com.mapbox.mapboxsdk.exceptions; /** - * A InvalidLatLngBoundsException is thrown by {@link com.mapbox.mapboxsdk.geometry.LatLngBounds} - * when there aren't enough {@link com.mapbox.mapboxsdk.geometry.LatLng} to create a bounds. + * An InvalidLatLngBoundsException is thrown by LatLngBounds + * when there aren't enough LatLng to create a bounds. */ public class InvalidLatLngBoundsException extends RuntimeException { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidMarkerPositionException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidMarkerPositionException.java index f0f9b9236b..44ee83265d 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidMarkerPositionException.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidMarkerPositionException.java @@ -5,6 +5,9 @@ package com.mapbox.mapboxsdk.exceptions; */ public class InvalidMarkerPositionException extends RuntimeException { + /** + * Creates a invalid marker position exception thrown when a Marker object is created with an invalid LatLng position. + */ public InvalidMarkerPositionException() { super("Adding an invalid Marker to a Map. " + "Missing the required position field. " diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/MapboxConfigurationException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/MapboxConfigurationException.java index 74bceb196c..e9a0261d85 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/MapboxConfigurationException.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/MapboxConfigurationException.java @@ -8,10 +8,14 @@ import android.content.Context; * This occurs either when {@link com.mapbox.mapboxsdk.Mapbox} is not correctly initialised or the provided access token * through {@link com.mapbox.mapboxsdk.Mapbox#getInstance(Context, String)} isn't valid. *

      + * * @see com.mapbox.mapboxsdk.Mapbox#getInstance(Context, String) */ public class MapboxConfigurationException extends RuntimeException { + /** + * Creates a Mapbox configuration exception thrown by MapboxMap when the SDK hasn't been properly initialised. + */ public MapboxConfigurationException() { super("\nUsing MapView requires setting a valid access token. Use Mapbox.getInstance(Context context, " + "String accessToken) to provide one. " diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TooManyIconsException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TooManyIconsException.java index 8923d822f2..bffc10dc04 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TooManyIconsException.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TooManyIconsException.java @@ -1,12 +1,11 @@ package com.mapbox.mapboxsdk.exceptions; -import com.mapbox.mapboxsdk.annotations.Icon; import com.mapbox.mapboxsdk.annotations.IconFactory; /** *

      - * A {@code TooManyIconsException} is thrown by {@link IconFactory} when it - * cannot create a {@link Icon} because there are already too many icons created. + * A TooManyIconsException is thrown by IconFactory when it + * cannot create a Icon because there are already too many icons created. *

      * You should try to reuse Icon objects whenever possible. * diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ILatLng.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ILatLng.java index 1af8e7cfc7..07df87af3a 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ILatLng.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ILatLng.java @@ -1,12 +1,28 @@ package com.mapbox.mapboxsdk.geometry; /** - * Describes a latitude, longitude point. + * Describes a latitude, longitude, and altitude tuple. */ public interface ILatLng { + + /** + * Get the latitude, in degrees. + * + * @return the latitude value in degrees + */ double getLatitude(); + /** + * Get the longitude, in degrees. + * + * @return the longitude value in degrees + */ double getLongitude(); + /** + * Get the altitude, in meters. + * + * @return the altitude value in meters + */ double getAltitude(); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/IProjectedMeters.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/IProjectedMeters.java index 694c935143..db459d7cbb 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/IProjectedMeters.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/IProjectedMeters.java @@ -4,7 +4,19 @@ package com.mapbox.mapboxsdk.geometry; * Describes a projection in Mercator meters. */ public interface IProjectedMeters { + + /** + * Get the north projection, in meters. + * + * @return the projected meters in north direction + */ double getNorthing(); + /** + * Get the east projection, in meters. + * + * @return the projected meters in east direction + */ double getEasting(); + } 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 ca2d3673b2..eb57241196 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 @@ -3,6 +3,7 @@ package com.mapbox.mapboxsdk.geometry; import android.location.Location; import android.os.Parcel; import android.os.Parcelable; +import android.support.annotation.FloatRange; import com.mapbox.services.android.telemetry.constants.GeoConstants; import com.mapbox.services.android.telemetry.utils.MathUtils; @@ -21,6 +22,9 @@ import com.mapbox.services.android.telemetry.utils.MathUtils; */ public class LatLng implements ILatLng, Parcelable { + /** + * Inner class responsible for recreating Parcels into objects. + */ public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { public LatLng createFromParcel(Parcel in) { return new LatLng(in); @@ -44,7 +48,7 @@ public class LatLng implements ILatLng, Parcelable { } /** - * Construct a new latitude, longitude point given float arguments + * Construct a new latitude, longitude point given double arguments * * @param latitude Latitude in degrees * @param longitude Longitude in degrees @@ -55,7 +59,7 @@ public class LatLng implements ILatLng, Parcelable { } /** - * Construct a new latitude, longitude, altitude point given float arguments + * Construct a new latitude, longitude, altitude point given double arguments * * @param latitude Latitude in degrees * @param longitude Longitude in degress @@ -68,7 +72,7 @@ public class LatLng implements ILatLng, Parcelable { } /** - * Transform a Location into a LatLng point + * Construct a new latitude, longitude, altitude point given location argument * * @param location Android Location */ @@ -77,23 +81,40 @@ public class LatLng implements ILatLng, Parcelable { } /** - * Clone an existing latitude longitude point + * Construct a new latitude, longitude, altitude point given another latitude, longitude, altitude point. * - * @param aLatLng LatLng + * @param latLng LatLng to be cloned. */ - public LatLng(LatLng aLatLng) { - this.latitude = aLatLng.latitude; - this.longitude = aLatLng.longitude; - this.altitude = aLatLng.altitude; + public LatLng(LatLng latLng) { + this.latitude = latLng.latitude; + this.longitude = latLng.longitude; + this.altitude = latLng.altitude; } + /** + * Constructs a new latitude, longitude, altitude tuple given a parcel. + * + * @param in the parcel containing the latitude, longitude, altitude values + */ protected LatLng(Parcel in) { setLatitude(in.readDouble()); setLongitude(in.readDouble()); setAltitude(in.readDouble()); } - public void setLatitude(double latitude) { + /** + * Set the latitude, in degrees. + *

      + * This value is in the range of [-85.05112878, 85.05112878], see {@link GeoConstants#MIN_LATITUDE} and + * {@link GeoConstants#MAX_LATITUDE} + *

      + * + * @param latitude the latitude value in degrees + * @see GeoConstants#MIN_LATITUDE + * @see GeoConstants#MAX_LATITUDE + */ + public void setLatitude( + @FloatRange(from = GeoConstants.MIN_LATITUDE, to = GeoConstants.MAX_LATITUDE) double latitude) { if (Double.isNaN(latitude)) { throw new IllegalArgumentException("latitude must not be NaN"); } @@ -103,12 +124,35 @@ public class LatLng implements ILatLng, Parcelable { this.latitude = latitude; } + /** + * Get the latitude, in degrees. + *

      + * This value is in the range of [-85.05112878, 85.05112878], see {@link GeoConstants#MIN_LATITUDE} and + * {@link GeoConstants#MAX_LATITUDE} + *

      + * + * @return the latitude value in degrees + * @see GeoConstants#MIN_LATITUDE + * @see GeoConstants#MAX_LATITUDE + */ @Override public double getLatitude() { return latitude; } - public void setLongitude(double longitude) { + /** + * Set the longitude, in degrees. + *

      + * This value is in the range of [-180, 180], see {@link GeoConstants#MIN_LONGITUDE} and + * {@link GeoConstants#MAX_LONGITUDE} + *

      + * + * @param longitude the longitude value in degrees + * @see GeoConstants#MIN_LONGITUDE + * @see GeoConstants#MAX_LONGITUDE + */ + public void setLongitude(@FloatRange(from = GeoConstants.MIN_LONGITUDE, to = GeoConstants.MAX_LONGITUDE) + double longitude) { if (Double.isNaN(longitude)) { throw new IllegalArgumentException("longitude must not be NaN"); } @@ -118,15 +162,36 @@ public class LatLng implements ILatLng, Parcelable { this.longitude = longitude; } + /** + * Get the longitude, in degrees. + *

      + * This value is in the range of [-180, 180], see {@link GeoConstants#MIN_LONGITUDE} and + * {@link GeoConstants#MAX_LONGITUDE} + *

      + * + * @return the longitude value in degrees + * @see GeoConstants#MIN_LONGITUDE + * @see GeoConstants#MAX_LONGITUDE + */ @Override public double getLongitude() { return longitude; } + /** + * Set the altitude, in meters. + * + * @param altitude the altitude in meters + */ public void setAltitude(double altitude) { this.altitude = altitude; } + /** + * Get the altitude, in meters. + * + * @return the altitude value in meters + */ @Override public double getAltitude() { return altitude; @@ -136,13 +201,19 @@ public class LatLng implements ILatLng, Parcelable { * Return a new LatLng object with a wrapped Longitude. This allows original data object * to remain unchanged. * - * @return New LatLng object with wrapped Longitude + * @return new LatLng object with wrapped Longitude */ public LatLng wrap() { longitude = MathUtils.wrap(longitude, GeoConstants.MIN_LONGITUDE, GeoConstants.MAX_LONGITUDE); return this; } + /** + * Indicates whether some other object is "equal to" this one. + * + * @param object The object to compare + * @return True if equal, false if not + */ @Override public boolean equals(Object object) { if (this == object) { @@ -158,6 +229,11 @@ public class LatLng implements ILatLng, Parcelable { && Double.compare(latLng.longitude, longitude) == 0; } + /** + * Returns a hash code value for the object. + * + * @return the hash code value + */ @Override public int hashCode() { int result; @@ -171,16 +247,32 @@ public class LatLng implements ILatLng, Parcelable { return result; } + /** + * Returns a string representation of the object. + * + * @return the string representation + */ @Override public String toString() { return "LatLng [latitude=" + latitude + ", longitude=" + longitude + ", altitude=" + altitude + "]"; } + /** + * Describe the kinds of special objects contained in this Parcelable instance's marshaled representation. + * + * @return a bitmask indicating the set of special object types marshaled by this Parcelable object instance. + */ @Override public int describeContents() { return 0; } + /** + * Flatten this object in to a Parcel. + * + * @param out The Parcel in which the object should be written. + * @param flags Additional flags about how the object should be written + */ @Override public void writeToParcel(Parcel out, int flags) { out.writeDouble(latitude); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java index 4a4e2a30aa..505b2db192 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java @@ -3,6 +3,7 @@ package com.mapbox.mapboxsdk.geometry; import android.os.Parcel; import android.os.Parcelable; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import com.mapbox.mapboxsdk.exceptions.InvalidLatLngBoundsException; import com.mapbox.services.android.telemetry.constants.GeoConstants; @@ -18,10 +19,10 @@ import java.util.List; */ public class LatLngBounds implements Parcelable { - private final double mLatNorth; - private final double mLatSouth; - private final double mLonEast; - private final double mLonWest; + private final double latitudeNorth; + private final double latitudeSouth; + private final double longitudeEast; + private final double longitudeWest; /** * Construct a new LatLngBounds based on its corners, given in NESW @@ -34,10 +35,10 @@ public class LatLngBounds implements Parcelable { */ LatLngBounds(final double northLatitude, final double eastLongitude, final double southLatitude, final double westLongitude) { - this.mLatNorth = northLatitude; - this.mLonEast = eastLongitude; - this.mLatSouth = southLatitude; - this.mLonWest = westLongitude; + this.latitudeNorth = northLatitude; + this.longitudeEast = eastLongitude; + this.latitudeSouth = southLatitude; + this.longitudeWest = westLongitude; } /** @@ -59,8 +60,8 @@ public class LatLngBounds implements Parcelable { * @return LatLng center of this LatLngBounds */ public LatLng getCenter() { - return new LatLng((this.mLatNorth + this.mLatSouth) / 2, - (this.mLonEast + this.mLonWest) / 2); + return new LatLng((this.latitudeNorth + this.latitudeSouth) / 2, + (this.longitudeEast + this.longitudeWest) / 2); } /** @@ -69,7 +70,7 @@ public class LatLngBounds implements Parcelable { * @return double latitude value for north */ public double getLatNorth() { - return this.mLatNorth; + return this.latitudeNorth; } /** @@ -78,7 +79,7 @@ public class LatLngBounds implements Parcelable { * @return double latitude value for south */ public double getLatSouth() { - return this.mLatSouth; + return this.latitudeSouth; } /** @@ -87,7 +88,7 @@ public class LatLngBounds implements Parcelable { * @return double longitude value for east */ public double getLonEast() { - return this.mLonEast; + return this.longitudeEast; } /** @@ -96,7 +97,7 @@ public class LatLngBounds implements Parcelable { * @return double longitude value for west */ public double getLonWest() { - return this.mLonWest; + return this.longitudeWest; } /** @@ -105,7 +106,7 @@ public class LatLngBounds implements Parcelable { * @return LatLng of the south west corner */ public LatLng getSouthWest() { - return new LatLng(mLatSouth, mLonWest); + return new LatLng(latitudeSouth, longitudeWest); } /** @@ -114,7 +115,7 @@ public class LatLngBounds implements Parcelable { * @return LatLng of the north east corner */ public LatLng getNorthEast() { - return new LatLng(mLatNorth, mLonEast); + return new LatLng(latitudeNorth, longitudeEast); } /** @@ -123,7 +124,7 @@ public class LatLngBounds implements Parcelable { * @return LatLng of the south east corner */ public LatLng getSouthEast() { - return new LatLng(mLatSouth, mLonEast); + return new LatLng(latitudeSouth, longitudeEast); } /** @@ -132,7 +133,7 @@ public class LatLngBounds implements Parcelable { * @return LatLng of the north west corner */ public LatLng getNorthWest() { - return new LatLng(mLatNorth, mLonWest); + return new LatLng(latitudeNorth, longitudeWest); } /** @@ -151,7 +152,7 @@ public class LatLngBounds implements Parcelable { * @return Span distance */ public double getLatitudeSpan() { - return Math.abs(this.mLatNorth - this.mLatSouth); + return Math.abs(this.latitudeNorth - this.latitudeSouth); } /** @@ -161,7 +162,7 @@ public class LatLngBounds implements Parcelable { * @return Span distance */ public double getLongitudeSpan() { - return Math.abs(this.mLonEast - this.mLonWest); + return Math.abs(this.longitudeEast - this.longitudeWest); } @@ -174,9 +175,15 @@ public class LatLngBounds implements Parcelable { return getLongitudeSpan() == 0.0 || getLatitudeSpan() == 0.0; } + /** + * Returns a string representaton of the object. + * + * @return the string representation + */ @Override public String toString() { - return "N:" + this.mLatNorth + "; E:" + this.mLonEast + "; S:" + this.mLatSouth + "; W:" + this.mLonWest; + return "N:" + this.latitudeNorth + "; E:" + this.longitudeEast + "; S:" + this.latitudeSouth + + "; W:" + this.longitudeWest; } /** @@ -241,10 +248,10 @@ public class LatLngBounds implements Parcelable { } if (o instanceof LatLngBounds) { LatLngBounds other = (LatLngBounds) o; - return mLatNorth == other.getLatNorth() - && mLatSouth == other.getLatSouth() - && mLonEast == other.getLonEast() - && mLonWest == other.getLonWest(); + return latitudeNorth == other.getLatNorth() + && latitudeSouth == other.getLatSouth() + && longitudeEast == other.getLonEast() + && longitudeWest == other.getLonWest(); } return false; } @@ -258,10 +265,10 @@ public class LatLngBounds implements Parcelable { public boolean contains(final ILatLng latLng) { final double latitude = latLng.getLatitude(); final double longitude = latLng.getLongitude(); - return ((latitude <= this.mLatNorth) - && (latitude >= this.mLatSouth)) - && ((longitude <= this.mLonEast) - && (longitude >= this.mLonWest)); + return ((latitude <= this.latitudeNorth) + && (latitude >= this.latitudeSouth)) + && ((longitude <= this.longitudeEast) + && (longitude >= this.longitudeWest)); } /** @@ -295,10 +302,10 @@ public class LatLngBounds implements Parcelable { * @return BoundingBox */ public LatLngBounds union(final double lonNorth, final double latEast, final double lonSouth, final double latWest) { - return new LatLngBounds((this.mLatNorth < lonNorth) ? lonNorth : this.mLatNorth, - (this.mLonEast < latEast) ? latEast : this.mLonEast, - (this.mLatSouth > lonSouth) ? lonSouth : this.mLatSouth, - (this.mLonWest > latWest) ? latWest : this.mLonWest); + return new LatLngBounds((this.latitudeNorth < lonNorth) ? lonNorth : this.latitudeNorth, + (this.longitudeEast < latEast) ? latEast : this.longitudeEast, + (this.latitudeSouth > lonSouth) ? lonSouth : this.latitudeSouth, + (this.longitudeWest > latWest) ? latWest : this.longitudeWest); } /** @@ -307,6 +314,7 @@ public class LatLngBounds implements Parcelable { * @param box LatLngBounds to intersect with * @return LatLngBounds */ + @Nullable public LatLngBounds intersect(LatLngBounds box) { double minLatWest = Math.max(getLonWest(), box.getLonWest()); double maxLatEast = Math.min(getLonEast(), box.getLonEast()); @@ -334,6 +342,9 @@ public class LatLngBounds implements Parcelable { return intersect(new LatLngBounds(northLatitude, eastLongitude, southLatitude, westLongitude)); } + /** + * Inner class responsible for recreating Parcels into objects. + */ public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { @Override @@ -347,25 +358,41 @@ public class LatLngBounds implements Parcelable { } }; + /** + * Returns a hash code value for the object. + * + * @return the hash code + */ @Override public int hashCode() { - return (int) ((mLatNorth + 90) - + ((mLatSouth + 90) * 1000) - + ((mLonEast + 180) * 1000000) - + ((mLonEast + 180) * 1000000000)); + return (int) ((latitudeNorth + 90) + + ((latitudeSouth + 90) * 1000) + + ((longitudeEast + 180) * 1000000) + + ((longitudeEast + 180) * 1000000000)); } + /** + * Describe the kinds of special objects contained in this Parcelable instance's marshaled representation. + * + * @return a bitmask indicating the set of special object types marshaled by this Parcelable object instance. + */ @Override public int describeContents() { return 0; } + /** + * Flatten this object in to a Parcel. + * + * @param out The Parcel in which the object should be written. + * @param flags Additional flags about how the object should be written + */ @Override - public void writeToParcel(final Parcel out, final int arg1) { - out.writeDouble(this.mLatNorth); - out.writeDouble(this.mLonEast); - out.writeDouble(this.mLatSouth); - out.writeDouble(this.mLonWest); + public void writeToParcel(final Parcel out, final int flags) { + out.writeDouble(this.latitudeNorth); + out.writeDouble(this.longitudeEast); + out.writeDouble(this.latitudeSouth); + out.writeDouble(this.longitudeWest); } private static LatLngBounds readFromParcel(final Parcel in) { @@ -381,28 +408,51 @@ public class LatLngBounds implements Parcelable { */ public static final class Builder { - private List mLatLngList; + private List latLngList; + /** + * Constructs a builder to compose LatLng objects to a LatLngBounds. + */ public Builder() { - mLatLngList = new ArrayList<>(); + latLngList = new ArrayList<>(); } + /** + * Builds a new LatLngBounds. + *

      + * Throws an {@link InvalidLatLngBoundsException} when no LatLngBounds can be created. + *

      + * + * @return the build LatLngBounds + */ public LatLngBounds build() { - if (mLatLngList.size() < 2) { - throw new InvalidLatLngBoundsException(mLatLngList.size()); + if (latLngList.size() < 2) { + throw new InvalidLatLngBoundsException(latLngList.size()); } - return LatLngBounds.fromLatLngs(mLatLngList); + return LatLngBounds.fromLatLngs(latLngList); } + /** + * Adds a LatLng object to the LatLngBounds.Builder. + * + * @param latLngs the List of LatLng objects to be added + * @return this + */ public Builder includes(List latLngs) { for (LatLng point : latLngs) { - mLatLngList.add(point); + latLngList.add(point); } return this; } + /** + * Adds a LatLng object to the LatLngBounds.Builder. + * + * @param latLng the LatLng to be added + * @return this + */ public Builder include(@NonNull LatLng latLng) { - mLatLngList.add(latLng); + latLngList.add(latLng); return this; } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngSpan.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngSpan.java index d00ccdb9b8..322c7dfb74 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngSpan.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngSpan.java @@ -64,19 +64,28 @@ public class LatLngSpan implements Parcelable { mLongitudeSpan = longitudeSpan; } + /** + * Indicates whether some other object is "equal to" this one. + * + * @param object The object to compare + * @return True if equal, false if not + */ @Override - public boolean equals(Object o) { - if (this == o) { + public boolean equals(Object object) { + if (this == object) { return true; } - if (o instanceof LatLngSpan) { - LatLngSpan other = (LatLngSpan) o; + if (object instanceof LatLngSpan) { + LatLngSpan other = (LatLngSpan) object; return mLongitudeSpan == other.getLongitudeSpan() && mLatitudeSpan == other.getLatitudeSpan(); } return false; } + /** + * Inner class responsible for recreating Parcels into objects. + */ public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { @Override @@ -90,14 +99,41 @@ public class LatLngSpan implements Parcelable { } }; + /** + * Describe the kinds of special objects contained in this Parcelable instance's marshaled representation. + * + * @return a bitmask indicating the set of special object types marshaled by this Parcelable object instance. + */ @Override public int describeContents() { return 0; } + /** + * Flatten this object in to a Parcel. + * + * @param out Parcel in which the object should be written + * @param flags Additional flags about how the object should be written + */ @Override - public void writeToParcel(Parcel out, int arg1) { + public void writeToParcel(Parcel out, int flags) { out.writeDouble(mLatitudeSpan); out.writeDouble(mLongitudeSpan); } + + /** + * Returns a hash code value for the object. + * + * @return hash code value of this + */ + @Override + public int hashCode() { + int result; + long temp; + temp = Double.doubleToLongBits(mLatitudeSpan); + result = (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(mLongitudeSpan); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + return result; + } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java index 761d8f2a8b..fa84c33b2b 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java @@ -13,6 +13,9 @@ import android.os.Parcelable; */ public class ProjectedMeters implements IProjectedMeters, Parcelable { + /** + * Inner class responsible for recreating Parcels into objects. + */ public static final Creator CREATOR = new Creator() { public ProjectedMeters createFromParcel(Parcel in) { return new ProjectedMeters(in); @@ -47,6 +50,12 @@ public class ProjectedMeters implements IProjectedMeters, Parcelable { this.easting = projectedMeters.easting; } + /** + * Creates a ProjectedMeters from a Parcel. + * + * @param in The parcel to create from + * @return a bitmask indicating the set of special object types marshaled by this Parcelable object instance. + */ private ProjectedMeters(Parcel in) { northing = in.readDouble(); easting = in.readDouble(); @@ -72,22 +81,32 @@ public class ProjectedMeters implements IProjectedMeters, Parcelable { return easting; } + /** + * Indicates whether some other object is "equal to" this one. + * + * @param other The object to compare this to + * @return true if equal, false if not + */ @Override - public boolean equals(Object o) { - if (this == o) { + public boolean equals(Object other) { + if (this == other) { return true; } - if (o == null || getClass() != o.getClass()) { + if (other == null || getClass() != other.getClass()) { return false; } - ProjectedMeters projectedMeters = (ProjectedMeters) o; + ProjectedMeters projectedMeters = (ProjectedMeters) other; return Double.compare(projectedMeters.easting, easting) == 0 && Double.compare(projectedMeters.northing, northing) == 0; - } + /** + * Returns a hash code value for the object. + * + * @return the hash code of this + */ @Override public int hashCode() { int result; @@ -99,16 +118,32 @@ public class ProjectedMeters implements IProjectedMeters, Parcelable { return result; } + /** + * Returns a string representation of the object. + * + * @return the string representation of this + */ @Override public String toString() { return "ProjectedMeters [northing=" + northing + ", easting=" + easting + "]"; } + /** + * Describe the kinds of special objects contained in this Parcelable instance's marshaled representation. + * + * @return a bitmask indicating the set of special object types marshaled by this Parcelable object instance. + */ @Override public int describeContents() { return 0; } + /** + * Flatten this object in to a Parcel. + * + * @param out The Parcel in which the object should be written. + * @param flags Additional flags about how the object should be written + */ @Override public void writeToParcel(Parcel out, int flags) { out.writeDouble(northing); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java index c5b8ad3077..c09c00fced 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java @@ -37,6 +37,11 @@ public class VisibleRegion implements Parcelable { */ public final LatLngBounds latLngBounds; + /** + * Creates a VisibleRegion from a Parcel. + * + * @param in The Parcel to create this from + */ private VisibleRegion(Parcel in) { this.farLeft = in.readParcelable(LatLng.class.getClassLoader()); this.farRight = in.readParcelable(LatLng.class.getClassLoader()); @@ -46,7 +51,7 @@ public class VisibleRegion implements Parcelable { } /** - * Creates a new VisibleRegion given the four corners of the camera. + * Creates a VisibleRegion given the four corners of the camera. * * @param farLeft A LatLng object containing the latitude and longitude of the near left corner of the region. * @param farRight A LatLng object containing the latitude and longitude of the near left corner of the region. @@ -88,12 +93,22 @@ public class VisibleRegion implements Parcelable { && latLngBounds.equals(visibleRegion.latLngBounds); } + /** + * The string representation of the object. + * + * @return the string representation of this + */ @Override public String toString() { return "[farLeft [" + farLeft + "], farRight [" + farRight + "], nearLeft [" + nearLeft + "], nearRight [" + nearRight + "], latLngBounds [" + latLngBounds + "]]"; } + /** + * Returns a hash code value for the object. + * + * @return the hash code + */ @Override public int hashCode() { return ((farLeft.hashCode() + 90) @@ -102,11 +117,22 @@ public class VisibleRegion implements Parcelable { + ((nearRight.hashCode() + 180) * 1000000000)); } + /** + * Describe the kinds of special objects contained in this Parcelable instance's marshaled representation. + * + * @return a bitmask indicating the set of special object types marshaled by this Parcelable object instance. + */ @Override public int describeContents() { return 0; } + /** + * Flatten this object in to a Parcel. + * + * @param out The Parcel in which the object should be written. + * @param flags Additional flags about how the object should be written + */ @Override public void writeToParcel(Parcel out, int flags) { out.writeParcelable(farLeft, flags); @@ -116,6 +142,9 @@ public class VisibleRegion implements Parcelable { out.writeParcelable(latLngBounds, flags); } + /** + * Inner class responsible for recreating Parcels into objects. + */ public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { public VisibleRegion createFromParcel(Parcel in) { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java index 8416bd5b6c..12e3300429 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java @@ -28,12 +28,16 @@ import com.mapzen.android.lost.api.LostApiClient; * in the history stack. *

      */ -public class LocationSource extends LocationEngine implements - LostApiClient.ConnectionCallbacks, LocationListener { +public class LocationSource extends LocationEngine implements LostApiClient.ConnectionCallbacks, LocationListener { private Context context; private LostApiClient lostApiClient; + /** + * Constructs a location source instance. + * + * @param context the context from which the Application context will be derived. + */ public LocationSource(Context context) { super(); this.context = context.getApplicationContext(); 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 098c701e03..c51d9327d2 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 @@ -1,7 +1,5 @@ package com.mapbox.mapboxsdk.maps; -import android.app.Activity; -import android.app.Fragment; import android.content.Context; import android.graphics.Canvas; import android.graphics.PointF; @@ -27,7 +25,6 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ZoomButtonsController; -import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.R; import com.mapbox.mapboxsdk.annotations.MarkerViewManager; import com.mapbox.mapboxsdk.constants.MapboxConstants; @@ -178,14 +175,14 @@ public class MapView extends FrameLayout { /** *

      - * You must call this method from the parent's {@link android.app.Activity#onCreate(Bundle)} or - * {@link android.app.Fragment#onCreate(Bundle)}. + * You must call this method from the parent's Activity#onCreate(Bundle)} or + * Fragment#onCreate(Bundle). *

      - * You must set a valid access token with {@link Mapbox#getInstance(Context, String)}) before you call this method - * or an exception will be thrown. + * You must set a valid access token with {@link com.mapbox.mapboxsdk.Mapbox#getInstance(Context, String)} + * before you call this method or an exception will be thrown. * * @param savedInstanceState Pass in the parent's savedInstanceState. - * @see Mapbox#getInstance(Context, String) + * @see com.mapbox.mapboxsdk.Mapbox#getInstance(Context, String) */ @UiThread public void onCreate(@Nullable Bundle savedInstanceState) { @@ -214,12 +211,11 @@ public class MapView extends FrameLayout { } /** - * You must call this method from the parent's {@link android.app.Activity#onSaveInstanceState(Bundle)} - * or {@link android.app.Fragment#onSaveInstanceState(Bundle)}. + * You must call this method from the parent's Activity#onSaveInstanceState(Bundle) + * or Fragment#onSaveInstanceState(Bundle). * * @param outState Pass in the parent's outState. */ - @UiThread public void onSaveInstanceState(@NonNull Bundle outState) { outState.putBoolean(MapboxConstants.STATE_HAS_SAVED_STATE, true); @@ -227,7 +223,7 @@ public class MapView extends FrameLayout { } /** - * You must call this method from the parent's {@link Activity#onStart()} or {@link Fragment#onStart()} + * You must call this method from the parent's Activity#onStart() or Fragment#onStart() */ @UiThread public void onStart() { @@ -236,7 +232,7 @@ public class MapView extends FrameLayout { } /** - * You must call this method from the parent's {@link Activity#onResume()} or {@link Fragment#onResume()}. + * You must call this method from the parent's Activity#onResume() or Fragment#onResume(). */ @UiThread public void onResume() { @@ -244,7 +240,7 @@ public class MapView extends FrameLayout { } /** - * You must call this method from the parent's {@link Activity#onPause()} or {@link Fragment#onPause()}. + * You must call this method from the parent's Activity#onPause() or Fragment#onPause(). */ @UiThread public void onPause() { @@ -252,7 +248,7 @@ public class MapView extends FrameLayout { } /** - * You must call this method from the parent's {@link Activity#onStop()} or {@link Fragment#onStop()}. + * You must call this method from the parent's Activity#onStop() or Fragment#onStop(). */ @UiThread public void onStop() { @@ -261,7 +257,7 @@ public class MapView extends FrameLayout { } /** - * You must call this method from the parent's {@link Activity#onDestroy()} or {@link Fragment#onDestroy()}. + * You must call this method from the parent's Activity#onDestroy() or Fragment#onDestroy(). */ @UiThread public void onDestroy() { @@ -325,7 +321,7 @@ public class MapView extends FrameLayout { } /** - * You must call this method from the parent's {@link Activity#onLowMemory()} or {@link Fragment#onLowMemory()}. + * You must call this method from the parent's Activity#onLowMemory() or Fragment#onLowMemory(). */ @UiThread public void onLowMemory() { 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 8a708cb186..d672ab37c3 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 @@ -736,8 +736,8 @@ public final class MapboxMap { * will return the current location of the camera in flight. *

      * Note that this will cancel location tracking mode if enabled. You can change this behaviour by calling - * {@link TrackingSettings#setDismissTrackingModeForCameraPositionChange(boolean)} with false before invoking this - * method and calling it with true in the {@link CancelableCallback#onFinish()}. + * {@link com.mapbox.mapboxsdk.maps.TrackingSettings#setDismissLocationTrackingOnGesture(boolean)} with false before + * invoking this method and calling it with true in the {@link CancelableCallback#onFinish()}. *

      * * @param update The change that should be applied to the camera. @@ -763,8 +763,8 @@ public final class MapboxMap { * will return the current location of the camera in flight. *

      * Note that this will cancel location tracking mode if enabled. You can change this behaviour by calling - * {@link TrackingSettings#setDismissTrackingModeForCameraPositionChange(boolean)} with false before invoking this - * method and calling it with true in the {@link CancelableCallback#onFinish()}. + * {@link com.mapbox.mapboxsdk.maps.TrackingSettings#setDismissLocationTrackingOnGesture(boolean)} with false before + * invoking this method and calling it with true in the {@link CancelableCallback#onFinish()}. *

      * * @param update The change that should be applied to the camera. @@ -887,7 +887,12 @@ public final class MapboxMap { } /** - * Set focal bearing. + * Transform the map bearing given a bearing, focal point coordinates, and a duration. + * + * @param bearing The bearing of the Map to be transformed to + * @param focalX The x coordinate of the focal point + * @param focalY The y coordinate of the focal point + * @param duration The duration of the transformation */ public void setFocalBearing(double bearing, float focalX, float focalY, long duration) { transform.setBearing(bearing, focalX, focalY, duration); @@ -1059,7 +1064,7 @@ public final class MapboxMap { * An error message will be logged in the Android logcat and {@link MapView#DID_FAIL_LOADING_MAP} event will be * sent. * - * @param style The bundled style. Accepts one of the values from {@link Style}. + * @param style The bundled style. * @see Style */ @UiThread @@ -1075,7 +1080,8 @@ public final class MapboxMap { * An error message will be logged in the Android logcat and {@link MapView#DID_FAIL_LOADING_MAP} event will be * sent. * - * @param style The bundled style. Accepts one of the values from {@link Style}. + * @param style The bundled style. + * @param callback The callback to be invoked when the style has finished loading * @see Style */ @UiThread @@ -1576,9 +1582,11 @@ public final class MapboxMap { } /** - * Gets a camera position that would fit a bounds. + * Get a camera position that fits a provided bounds and padding. * * @param latLngBounds the bounds to constrain the map with + * @param padding the padding to apply to the bounds + * @return the camera position that fits the bounds and padding */ public CameraPosition getCameraForLatLngBounds(@Nullable LatLngBounds latLngBounds, int[] padding) { // calculate and set additional bounds padding @@ -2410,11 +2418,13 @@ public final class MapboxMap { } /** - * Interface definintion for a callback to be invoked when the style has finished loading. + * Interface definition for a callback to be invoked when the style has finished loading. */ public interface OnStyleLoadedListener { /** - * Invoked when the style has finished loading. + * Invoked when the style has finished loading + * + * @param style the style that has been loaded */ void onStyleLoaded(String style); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java index 98f94ddb39..2efed1b322 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java @@ -378,7 +378,7 @@ public class MapboxMapOptions implements Parcelable { /** * Specifies the gravity state of mapbox_compass_icon for a map view. * - * @param gravity see {@link android.view.Gravity} + * @param gravity Android SDK Gravity. * @return This */ public MapboxMapOptions compassGravity(int gravity) { @@ -439,7 +439,7 @@ public class MapboxMapOptions implements Parcelable { /** * Specifies the gravity state of logo for a map view. * - * @param gravity see {@link android.view.Gravity} + * @param gravity Android SDK Gravity. * @return This */ public MapboxMapOptions logoGravity(int gravity) { @@ -472,7 +472,7 @@ public class MapboxMapOptions implements Parcelable { /** * Specifies the gravity state of attribution for a map view. * - * @param gravity see {@link android.view.Gravity} + * @param gravity Android SDK Gravity. * @return This */ public MapboxMapOptions attributionGravity(int gravity) { 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 accecf232b..7f8ba21e3e 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 @@ -16,7 +16,6 @@ import android.support.annotation.Nullable; import android.support.annotation.UiThread; import android.support.v4.content.ContextCompat; import android.support.v4.content.res.ResourcesCompat; -import android.view.Gravity; import android.view.View; import android.widget.FrameLayout; import android.widget.ImageView; @@ -196,7 +195,7 @@ public final class UiSettings { setLogoMargins(resources, options.getLogoMargins()); } - private void setLogoMargins(Resources resources, int[]logoMargins) { + private void setLogoMargins(Resources resources, int[] logoMargins) { if (logoMargins != null) { setLogoMargins(logoMargins[0], logoMargins[1], logoMargins[2], logoMargins[3]); } else { @@ -309,8 +308,7 @@ public final class UiSettings { *

      * By default, the compass is in the top right corner. * - * @param gravity One of the values from {@link Gravity}. - * @see Gravity + * @param gravity Android SDK Gravity. */ @UiThread public void setCompassGravity(int gravity) { @@ -454,8 +452,7 @@ public final class UiSettings { *

      * By default, the logo is in the bottom left corner. * - * @param gravity One of the values from {@link Gravity}. - * @see Gravity + * @param gravity Android SDK Gravity. */ public void setLogoGravity(int gravity) { setWidgetGravity(logoView, gravity); @@ -546,8 +543,7 @@ public final class UiSettings { *

      * By default, the attribution is in the bottom left corner next to the Mapbox logo. * - * @param gravity One of the values from {@link Gravity}. - * @see Gravity + * @param gravity Android SDK Gravity. */ public void setAttributionGravity(int gravity) { setWidgetGravity(attributionsView, gravity); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java index 9740679cf5..72868a91d8 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java @@ -45,6 +45,9 @@ import timber.log.Timber; /** * UI element overlaid on a map to show the user's location. + *

      + * Use {@link MyLocationViewSettings} to manipulate the state of this view. + *

      */ public class MyLocationView extends View { @@ -155,6 +158,12 @@ public class MyLocationView extends View { this.locationSource = locationSource; } + /** + * Set the foreground drawable, for internal use only. + * + * @param defaultDrawable The drawable shown when showing this view + * @param bearingDrawable The drawable shown when tracking of bearing is enabled + */ public final void setForegroundDrawables(Drawable defaultDrawable, Drawable bearingDrawable) { if (defaultDrawable == null) { return; @@ -183,6 +192,11 @@ public class MyLocationView extends View { invalidateBounds(); } + /** + * Set the foreground drawable tint, for internal use only. + * + * @param color The color to tint the drawable with + */ public final void setForegroundDrawableTint(@ColorInt int color) { if (foregroundDrawable != null) { foregroundDrawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN); @@ -193,10 +207,24 @@ public class MyLocationView extends View { invalidate(); } + /** + * Set the shadow drawable, for internal use only. + * + * @param drawable The drawable shown as shadow + */ public final void setShadowDrawable(Drawable drawable) { setShadowDrawable(drawable, 0, 0, 0, 0); } + /** + * Set the shadow drawable with some additional offset. + * + * @param drawable The drawable shown as shadow + * @param left The left offset margin + * @param top The top offset margin + * @param right The right offset margin + * @param bottom The bottom offset margin + */ public final void setShadowDrawable(Drawable drawable, int left, int top, int right, int bottom) { if (drawable != null) { backgroundDrawable = drawable; @@ -210,6 +238,11 @@ public class MyLocationView extends View { invalidateBounds(); } + /** + * Set the shadow drawable tint color, for internal use only. + * + * @param color The tint color to apply + */ public final void setShadowDrawableTint(@ColorInt int color) { if (backgroundDrawable == null) { return; @@ -218,6 +251,11 @@ public class MyLocationView extends View { invalidate(); } + /** + * Set the accuracy tint color, for internal use only. + * + * @param color The tint color to apply + */ public final void setAccuracyTint(@ColorInt int color) { int alpha = accuracyPaint.getAlpha(); accuracyPaint.setColor(color); @@ -225,6 +263,11 @@ public class MyLocationView extends View { invalidate(); } + /** + * Set the accuracy alpha value, for internal use only. + * + * @param alpha The alpha accuracy value to apply + */ public final void setAccuracyAlpha(@IntRange(from = 0, to = 255) int alpha) { accuracyPaint.setAlpha(alpha); invalidate(); @@ -314,6 +357,11 @@ public class MyLocationView extends View { } } + /** + * Set the tilt value, for internal use only. + * + * @param tilt The tilt to apply + */ public void setTilt(@FloatRange(from = 0, to = 60.0f) double tilt) { this.tilt = tilt; if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) { @@ -322,6 +370,11 @@ public class MyLocationView extends View { invalidate(); } + /** + * Set the bearing value, for internal use only. + * + * @param bearing The bearing to apply + */ public void setBearing(double bearing) { this.bearing = bearing; if (myLocationTrackingMode == MyLocationTracking.TRACKING_NONE) { @@ -335,6 +388,11 @@ public class MyLocationView extends View { } } + /** + * Set the bearing and tilt from a camera position, for internal use only. + * + * @param position The camera position to extract bearing and tilt from + */ public void setCameraPosition(CameraPosition position) { if (position != null) { setBearing(position.bearing); @@ -342,6 +400,9 @@ public class MyLocationView extends View { } } + /** + * Called when the hosting activity is starting, for internal use only. + */ public void onStart() { if (myBearingTrackingMode == MyBearingTracking.COMPASS && compassListener.isSensorAvailable()) { compassListener.onResume(); @@ -351,6 +412,9 @@ public class MyLocationView extends View { } } + /** + * Called when the hosting activity is stopping, for internal use only. + */ public void onStop() { compassListener.onPause(); toggleGps(false); @@ -382,6 +446,9 @@ public class MyLocationView extends View { } } + /** + * Update current locationstate. + */ public void update() { if (isEnabled()) { myLocationBehavior.invalidate(); @@ -396,17 +463,33 @@ public class MyLocationView extends View { this.projection = mapboxMap.getProjection(); } + /** + * Set the enabled state, for internal use only. + * + * @param enabled The value to set the state to + */ @Override public void setEnabled(boolean enabled) { setEnabled(enabled, false); } + /** + * Set the enabled state, for internal use only. + * + * @param enabled The value to set the state to + * @param isCustomLocationSource Flag handling for handling user provided custom location source + */ public void setEnabled(boolean enabled, boolean isCustomLocationSource) { super.setEnabled(enabled); setVisibility(enabled ? View.VISIBLE : View.INVISIBLE); toggleGps(enabled, isCustomLocationSource); } + /** + * Save the view instance state, for internal use only. + * + * @return the marshaled representation of the view state + */ @Override protected Parcelable onSaveInstanceState() { Bundle bundle = new Bundle(); @@ -415,6 +498,11 @@ public class MyLocationView extends View { return bundle; } + /** + * Restore the view instance state, for internal use only. + * + * @param state the marshalled representation of the state to restore + */ @Override public void onRestoreInstanceState(Parcelable state) { if (state instanceof Bundle) { @@ -430,7 +518,7 @@ public class MyLocationView extends View { } /** - * Enabled / Disable GPS location updates along with updating the UI + * Enabled / Disable GPS location updates along with updating the UI, for internal use only. * * @param enableGps true if GPS is to be enabled, false if GPS is to be disabled */ @@ -463,10 +551,20 @@ public class MyLocationView extends View { } } + /** + * Get the current location. + * + * @return the current location + */ public Location getLocation() { return location; } + /** + * Set the current location, for internal use only. + * + * @param location The current location + */ public void setLocation(Location location) { if (location == null) { this.location = null; @@ -482,10 +580,20 @@ public class MyLocationView extends View { } } + /** + * Set location change animation enabled, for internal use only. + * + * @param locationChangeAnimationEnabled True if location changes are animated + */ public void setLocationChangeAnimationEnabled(boolean locationChangeAnimationEnabled) { this.locationChangeAnimationEnabled = locationChangeAnimationEnabled; } + /** + * Set the bearing tracking mode, for internal use only. + * + * @param myBearingTrackingMode The bearing tracking mode + */ public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) { this.myBearingTrackingMode = myBearingTrackingMode; if (myBearingTrackingMode == MyBearingTracking.COMPASS && compassListener.isSensorAvailable()) { @@ -502,6 +610,11 @@ public class MyLocationView extends View { invalidate(); } + /** + * Set the location tracking mode, for internla use only. + * + * @param myLocationTrackingMode The location tracking mode + */ public void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) { MyLocationBehaviorFactory factory = new MyLocationBehaviorFactory(); myLocationBehavior = factory.getBehavioralModel(myLocationTrackingMode); @@ -522,17 +635,32 @@ public class MyLocationView extends View { invalidate(); } + /** + * Get the location tracking mode, for internal use only. + * + * @return The location tracking mode + */ @MyLocationTracking.Mode public int getMyLocationTrackingMode() { return myLocationTrackingMode; } + /** + * Get the bearing tracking mode, for internal use only. + * + * @return the bearing tracking mode + */ @MyBearingTracking.Mode public int getMyBearingTrackingMode() { return myBearingTrackingMode; } + /** + * Set the compass bearing value, for internal use only. + * + * @param bearing The compas bearing value + */ private void setCompass(double bearing) { setCompass(bearing, 0 /* no animation */); } @@ -560,14 +688,29 @@ public class MyLocationView extends View { directionAnimator.start(); } + /** + * Get the center of this view in screen coordinates. + * + * @return the center of the view + */ public PointF getCenter() { return new PointF(getCenterX(), getCenterY()); } + /** + * Get the x value of the center of this view. + * + * @return the x value of the center of the view + */ private float getCenterX() { return (getX() + getMeasuredWidth()) / 2 + contentPaddingX - projectedX; } + /** + * Get the y value of the center of this view. + * + * @return the y value of the center of the view + */ private float getCenterY() { return (getY() + getMeasuredHeight()) / 2 + contentPaddingY - projectedY; } @@ -577,6 +720,11 @@ public class MyLocationView extends View { contentPaddingY = (padding[1] - padding[3]) / 2; } + /** + * Set the location source from which location updates are received, for internal use only. + * + * @param locationSource The location source to receive updates from + */ public void setLocationSource(LocationEngine locationSource) { toggleGps(false); this.locationSource = locationSource; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java index e9d823ebda..2ad1bf7ebc 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java @@ -5,9 +5,9 @@ import android.support.annotation.ColorInt; import android.support.annotation.IntRange; import android.support.annotation.NonNull; +import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.constants.MyLocationTracking; import com.mapbox.mapboxsdk.maps.FocalPointChangeListener; -import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.maps.MapboxMapOptions; import com.mapbox.mapboxsdk.maps.Projection; @@ -77,6 +77,11 @@ public class MyLocationViewSettings { this.focalPointChangeListener = focalPointChangedListener; } + /** + * Initialise this with MapboxMapOptions. + * + * @param options the options to initialise this class from + */ public void initialise(@NonNull MapboxMapOptions options) { CameraPosition position = options.getCamera(); if (position != null && !position.equals(CameraPosition.DEFAULT)) { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityReceiver.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityReceiver.java index 7be56fa694..a1bd98b780 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityReceiver.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityReceiver.java @@ -24,7 +24,10 @@ public class ConnectivityReceiver extends BroadcastReceiver { private static ConnectivityReceiver INSTANCE; /** - * Get or create the singleton instance + * Get a single instance of ConnectivityReceiver. + * + * @param context the context to extract the application context from + * @return single instance of ConnectivityReceiver */ public static synchronized ConnectivityReceiver instance(Context context) { if (INSTANCE == null) { @@ -74,7 +77,7 @@ public class ConnectivityReceiver extends BroadcastReceiver { } /** - * @see BroadcastReceiver#onReceive(Context, Intent) + * {@inheritDoc} */ @Override public void onReceive(Context context, Intent intent) { 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 95cb7d66c4..d572d696db 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 @@ -115,6 +115,12 @@ public class OfflineManager { }).start(); } + /** + * Get the single instance of offline manager. + * + * @param context the context used to host the offline manager + * @return the single instance of offline manager + */ public static synchronized OfflineManager getInstance(Context context) { if (instance == null) { instance = new OfflineManager(context); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java index baa815491f..1c78d5979e 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java @@ -393,6 +393,7 @@ public class OfflineRegion { * After you call this method, you may not call any additional methods on this object. *

      * + * @param bytes the metadata in bytes * @param callback the callback to be invoked */ public void updateMetadata(@NonNull final byte[] bytes, @NonNull final OfflineRegionUpdateMetadataCallback callback) { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionStatus.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionStatus.java index 9c3655fbec..fe12dd46c4 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionStatus.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionStatus.java @@ -7,6 +7,7 @@ package com.mapbox.mapboxsdk.offline; *

      * Note that the total required size in bytes is not currently available. A * future API release may provide an estimate of this number. + *

      */ public class OfflineRegionStatus { @@ -51,6 +52,7 @@ public class OfflineRegionStatus { * Specifically, it is false during early phases of an offline download. Once * style and tile sources have been downloaded, it is possible to calculate the * precise number of required resources, at which point it is set to true. + *

      */ private boolean requiredResourceCountIsPrecise = true; @@ -73,37 +75,93 @@ public class OfflineRegionStatus { } /** - * Is the region complete? + * Validates if the region download has completed + * + * @return true if download is complete, false if not */ public boolean isComplete() { return (completedResourceCount == requiredResourceCount); } + /** + * Returns the download state. + *

      + * State is defined as + *

      + *
        + *
      • {@link OfflineRegion#STATE_ACTIVE}
      • + *
      • {@link OfflineRegion#STATE_INACTIVE}
      • + *
      + * + * @return the download state. + */ @OfflineRegion.DownloadState public int getDownloadState() { return downloadState; } + /** + * Get the number of resources (inclusive of tiles) that have been fully downloaded + * and are ready for offline access. + * + * @return the amount of resources that have finished downloading. + */ public long getCompletedResourceCount() { return completedResourceCount; } + /** + * The cumulative size, in bytes, of all resources (inclusive of tiles) that have + * been fully downloaded. + * + * @return the size of the resources that have finished downloading + */ public long getCompletedResourceSize() { return completedResourceSize; } + /** + * Get the number of tiles that have been fully downloaded and are ready for + * offline access. + * + * @return the completed tile count + */ public long getCompletedTileCount() { return completedTileCount; } + /** + * Get the cumulative size, in bytes, of all tiles that have been fully downloaded. + * + * @return the completed tile size + */ public long getCompletedTileSize() { return completedTileSize; } + /** + * Get the number of resources that are known to be required for this region. See the + * documentation for `requiredResourceCountIsPrecise` for an important caveat + * about this number. + * + * @return the amount of resources that are required + */ public long getRequiredResourceCount() { return requiredResourceCount; } + /** + * Returns when the value of requiredResourceCount is a precise + * count of the number of required resources, and false when it is merely a lower + * bound. + *

      + * Specifically, it is false during early phases of an offline download. Once + * style and tile sources have been downloaded, it is possible to calculate the + * precise number of required resources, at which point it is set to true. + *

      + * + * @return True if the required resource count is precise, false if not + */ public boolean isRequiredResourceCountPrecise() { return requiredResourceCountIsPrecise; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java index 06676d76a1..eafef80e8d 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java @@ -3,9 +3,9 @@ package com.mapbox.mapboxsdk.storage; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.content.res.AssetManager; import android.os.Environment; import android.support.annotation.NonNull; -import android.content.res.AssetManager; import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.constants.MapboxConstants; @@ -28,8 +28,9 @@ public class FileSource { /** * Called whenever a URL needs to be transformed. * - * @param kind The kind of URL to be transformed. - * @return A URL that will now be downloaded. + * @param kind the kind of URL to be transformed. + * @param url the URL to be transformed + * @return a URL that will now be downloaded. */ String onURL(@Resource.Kind int kind, String url); @@ -38,6 +39,12 @@ public class FileSource { // File source instance is kept alive after initialization private static FileSource INSTANCE; + /** + * Get the single instance of FileSource. + * + * @param context the context to derive the cache path from + * @return the single instance of FileSource + */ public static synchronized FileSource getInstance(Context context) { if (INSTANCE == null) { String cachePath = getCachePath(context); @@ -47,6 +54,12 @@ public class FileSource { return INSTANCE; } + /** + * Get the cache path for a context. + * + * @param context the context to derive the cache path from + * @return the cache path + */ public static String getCachePath(Context context) { // Default value boolean setStorageExternal = MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java index 68727c8a4f..a57c440df4 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java @@ -30,14 +30,29 @@ public class PropertyValue { this.value = value; } + /** + * Returns if this is null + * + * @return true if this is null, false if not + */ public boolean isNull() { return value == null; } + /** + * Returns if this is a function. + * + * @return true if is a function, false if not + */ public boolean isFunction() { return !isNull() && value instanceof Function; } + /** + * Returns if this is a value. + * + * @return true if is a value, false if not + */ public boolean isValue() { return !isNull() && !isFunction(); } @@ -53,6 +68,11 @@ public class PropertyValue { } } + /** + * Get the value of the property. + * + * @return the property value + */ @Nullable public T getValue() { if (isValue()) { @@ -64,6 +84,11 @@ public class PropertyValue { } } + /** + * Get the color int value of the property if the value is a color. + * + * @return the color int value of the property, null if not a color value + */ @ColorInt @Nullable public Integer getColorInt() { @@ -80,6 +105,11 @@ public class PropertyValue { } } + /** + * Get the string representation of a property value. + * + * @return the string representation + */ @Override public String toString() { return String.format("%s: %s", name, value); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Light.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Light.java index b66a50b8a4..cb6465a6b1 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Light.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Light.java @@ -13,7 +13,7 @@ import com.mapbox.mapboxsdk.style.layers.TransitionOptions; /** * The global light source. * - * @see The online documentation + * @see The online documentation */ @UiThread public class Light { @@ -43,7 +43,8 @@ public class Light { * * @return anchor as String */ - @Property.ANCHOR public String getAnchor() { + @Property.ANCHOR + public String getAnchor() { return nativeGetAnchor(); } @@ -106,7 +107,7 @@ public class Light { * * @return color as String */ - public String getColor() { + public String getColor() { return nativeGetColor(); } @@ -142,7 +143,7 @@ public class Light { * * @return intensity as Float */ - public float getIntensity() { + public float getIntensity() { return nativeGetIntensity(); } @@ -165,17 +166,30 @@ public class Light { } private native void nativeSetAnchor(String anchor); + private native String nativeGetAnchor(); + private native void nativeSetPosition(Position position); + private native Position nativeGetPosition(); + private native TransitionOptions nativeGetPositionTransition(); + private native void nativeSetPositionTransition(long duration, long delay); + private native void nativeSetColor(String color); + private native String nativeGetColor(); + private native TransitionOptions nativeGetColorTransition(); + private native void nativeSetColorTransition(long duration, long delay); + private native void nativeSetIntensity(float intensity); + private native float nativeGetIntensity(); + private native TransitionOptions nativeGetIntensityTransition(); + private native void nativeSetIntensityTransition(long duration, long delay); } \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Position.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Position.java index 215db03ad2..cd6218d3e2 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Position.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Position.java @@ -18,7 +18,7 @@ public class Position { private float polarAngle; /** - * Creates a Position from a radial coordinate, an azimuthal angle & a polar angle. + * Creates a Position from a radial coordinate, an azimuthal angle and a polar angle. * * @param radialCoordinate the distance from the center of the base of an object to its light * @param azimuthalAngle the position of the light relative to 0° @@ -31,7 +31,7 @@ public class Position { } /** - * Returns a Position from a radial coordinate, an azimuthal angle & a polar angle + * Returns a Position from a radial coordinate, an azimuthal angle and a polar angle * * @param radialCoordinate the radial coordinate * @param azimuthalAngle the azimuthal angle diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/light.java.ejs b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/light.java.ejs index 067efe1092..80d927128d 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/light.java.ejs +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/light.java.ejs @@ -17,7 +17,7 @@ import com.mapbox.mapboxsdk.style.layers.TransitionOptions; /** * The global light source. * - * @see The online documentation + * @see The online documentation */ @UiThread public class Light { 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 e3fc765734..af3a79539f 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 @@ -5,8 +5,17 @@ import android.graphics.Canvas; import android.support.annotation.NonNull; import android.view.View; +/** + * Utility class for creating bitmaps + */ public class BitmapUtils { + /** + * Convert a view to a bitmap. + * + * @param view the view to convert + * @return the converted bitmap + */ public static Bitmap createBitmapFromView(@NonNull View view) { view.setDrawingCacheEnabled(true); view.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_LOW); @@ -22,6 +31,13 @@ public class BitmapUtils { return snapshot; } + /** + * Create a bitmap from a background and a foreground bitmap + * + * @param background The bitmap placed in the background + * @param foreground The bitmap placed in the foreground + * @return the merged bitmap + */ public static Bitmap mergeBitmap(@NonNull Bitmap background, @NonNull Bitmap foreground) { Bitmap result = Bitmap.createBitmap(background.getWidth(), background.getHeight(), background.getConfig()); Canvas canvas = new Canvas(result); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ColorUtils.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ColorUtils.java index 24c76243d9..14b18b00dc 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ColorUtils.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ColorUtils.java @@ -23,7 +23,7 @@ import java.util.regex.Pattern; public class ColorUtils { /** - * Returns a color integer associated as primary color from a theme based on a {@link Context}. + * Returns a color integer associated as primary color from a theme based on a Context. * * @param context The context used to style the color attributes. * @return The primary color value of current theme in the form 0xAARRGGBB. @@ -37,7 +37,7 @@ public class ColorUtils { } /** - * Returns a color integer associated as primary dark color from a theme based on a {@link Context}. + * Returns a color integer associated as primary dark color from a theme based on a Context. * * @param context The context used to style the color attributes. * @return The primary dark color value of current theme in the form 0xAARRGGBB. @@ -51,7 +51,7 @@ public class ColorUtils { } /** - * Returns a color integer associated as accent color from a theme based on a {@link Context}. + * Returns a color integer associated as accent color from a theme based on a Context. * * @param context The context used to style the color attributes. * @return The accent color value of current theme in the form 0xAARRGGBB. @@ -65,7 +65,7 @@ public class ColorUtils { } /** - * Returns a color state list associated with a theme based on a {@link Context} + * Returns a color state list associated with a theme based on a Context. * * @param color The color used for tinting. * @return A ColorStateList object containing the primary color of a theme @@ -85,7 +85,7 @@ public class ColorUtils { } /** - * Set a color tint list to the {@link Drawable} of an {@link ImageView}. + * Set a color tint list to the Drawable of an ImageView. * * @param imageView The view to set the default tint list. * @param tintColor The color to tint. diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MapFragmentUtils.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MapFragmentUtils.java index f810d6231d..007880acd1 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MapFragmentUtils.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MapFragmentUtils.java @@ -18,12 +18,25 @@ import com.mapbox.mapboxsdk.maps.MapboxMapOptions; */ public class MapFragmentUtils { + /** + * Convert MapboxMapOptions to a bundle of fragment arguments. + * + * @param options The MapboxMapOptions to convert + * @return a bundle of converted fragment arguments + */ public static Bundle createFragmentArgs(MapboxMapOptions options) { Bundle bundle = new Bundle(); bundle.putParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS, options); return bundle; } + /** + * Convert a bundle of fragment arguments to MapboxMapOptions. + * + * @param context The context of the activity hosting the fragment + * @param args The fragment arguments + * @return converted MapboxMapOptions + */ public static MapboxMapOptions resolveArgs(Context context, Bundle args) { MapboxMapOptions options; if (args != null && args.containsKey(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS)) { -- cgit v1.2.1 From 584bfb77333b5de8522c94a1ce117ad42fe4a07c Mon Sep 17 00:00:00 2001 From: Antonio Zugaldia Date: Tue, 20 Jun 2017 16:21:31 -0400 Subject: [android] update mapboxServicesVersion to 2.1.2 (#9311) --- platform/android/dependencies.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/android/dependencies.gradle b/platform/android/dependencies.gradle index 9c40e72bf6..2172d6a536 100644 --- a/platform/android/dependencies.gradle +++ b/platform/android/dependencies.gradle @@ -7,7 +7,7 @@ ext { versionCode = 11 versionName = "5.0.0" - mapboxServicesVersion = "2.1.1" + mapboxServicesVersion = "2.1.2" supportLibVersion = "25.3.1" wearableVersion = '2.0.0' espressoVersion = '2.2.2' -- cgit v1.2.1 From 651e70aec790381aa4fc4b4a7b2ad553f6184dce Mon Sep 17 00:00:00 2001 From: Tobrun Date: Wed, 21 Jun 2017 09:14:11 +0200 Subject: [android] - update CHANGELOG for release 5.1.0-beta.5 (#9316) --- platform/android/CHANGELOG.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md index eb2fd0554c..1e37717d8b 100644 --- a/platform/android/CHANGELOG.md +++ b/platform/android/CHANGELOG.md @@ -4,6 +4,21 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to ## 5.1.0 - TBA +## 5.1.0-beta.5 - June 21, 2017 + +* Update MAS dependency to 2.1.2 [#9311](https://github.com/mapbox/mapbox-gl-native/pull/9311) +* Update LOST dependency to 3.0.1 [#9302](https://github.com/mapbox/mapbox-gl-native/pull/9302) +* Fix Pulse example Parcelable creator [#9283](https://github.com/mapbox/mapbox-gl-native/pull/9283) +* Custom marker view anchoring [#9282](https://github.com/mapbox/mapbox-gl-native/pull/9282) +* Update Activity test generation [#9276](https://github.com/mapbox/mapbox-gl-native/pull/9276) +* Validate camera position before transforming [#9275](https://github.com/mapbox/mapbox-gl-native/pull/9275) +* Revisit javadoc [#9266](https://github.com/mapbox/mapbox-gl-native/pull/9266) +* Build with NDK 15 [#9263](https://github.com/mapbox/mapbox-gl-native/pull/9263) +* Snapshot with view content [#9263](https://github.com/mapbox/mapbox-gl-native/pull/9263) +* Update source changed javadoc [#9243](https://github.com/mapbox/mapbox-gl-native/pull/9243) +* Run tests on UI-thread [#9198](https://github.com/mapbox/mapbox-gl-native/pull/9198) +* Fix trackball on worker thread [#9305](https://github.com/mapbox/mapbox-gl-native/pull/9305) + ## 5.1.0-beta.4 - June 9, 2017 * Option to disable location change animation [#9210](https://github.com/mapbox/mapbox-gl-native/pull/9210) -- cgit v1.2.1 From d47eab05f66d7f7aed0e833a250f6be060c46441 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Wed, 21 Jun 2017 15:43:02 +0200 Subject: [android] - restore LatLngBounds conversion, add regression test (#9324) --- .../testapp/geometry/LatLngBoundsTest.java | 40 ++++++++++++++++++++++ platform/android/src/geometry/lat_lng_bounds.cpp | 8 ++--- 2 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/geometry/LatLngBoundsTest.java diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/geometry/LatLngBoundsTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/geometry/LatLngBoundsTest.java new file mode 100644 index 0000000000..f3ce9994a3 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/geometry/LatLngBoundsTest.java @@ -0,0 +1,40 @@ +package com.mapbox.mapboxsdk.testapp.geometry; + +import android.support.test.espresso.UiController; + +import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.geometry.LatLngBounds; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; +import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; +import com.mapbox.mapboxsdk.testapp.activity.feature.QueryRenderedFeaturesBoxHighlightActivity; + +import org.junit.Test; + +/** + * Instrumentation test to validate integration of LatLngBounds + */ +public class LatLngBoundsTest extends BaseActivityTest { + + @Override + protected Class getActivityClass() { + return QueryRenderedFeaturesBoxHighlightActivity.class; + } + + @Test + public void testLatLngBounds() { + // regression test for #9322 + validateTestSetup(); + MapboxMapAction.invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + LatLngBounds bounds = new LatLngBounds.Builder() + .include(new LatLng(48.8589506, 2.2773457)) + .include(new LatLng(47.2383171, -1.6309316)) + .build(); + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0)); + } + }); + } +} \ No newline at end of file diff --git a/platform/android/src/geometry/lat_lng_bounds.cpp b/platform/android/src/geometry/lat_lng_bounds.cpp index 9efacde120..ec1a32fed5 100644 --- a/platform/android/src/geometry/lat_lng_bounds.cpp +++ b/platform/android/src/geometry/lat_lng_bounds.cpp @@ -9,10 +9,10 @@ jni::Object LatLngBounds::New(jni::JNIEnv& env, mbgl::LatLngBounds } mbgl::LatLngBounds LatLngBounds::getLatLngBounds(jni::JNIEnv& env, jni::Object bounds) { - static auto swLat = LatLngBounds::javaClass.GetField(env, "mLatSouth"); - static auto swLon = LatLngBounds::javaClass.GetField(env, "mLonWest"); - static auto neLat = LatLngBounds::javaClass.GetField(env, "mLatNorth"); - static auto neLon = LatLngBounds::javaClass.GetField(env, "mLonEast"); + static auto swLat = LatLngBounds::javaClass.GetField(env, "latitudeSouth"); + static auto swLon = LatLngBounds::javaClass.GetField(env, "longitudeWest"); + static auto neLat = LatLngBounds::javaClass.GetField(env, "latitudeNorth"); + static auto neLon = LatLngBounds::javaClass.GetField(env, "longitudeEast"); return mbgl::LatLngBounds::hull( { bounds.Get(env, swLat), bounds.Get(env, swLon) }, { bounds.Get(env, neLat), bounds.Get(env, neLon) } -- cgit v1.2.1 From 72e71658bc5bc2fefdf5e551e119a4cfda42fd95 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 21 Jun 2017 12:23:17 -0700 Subject: [build] Unbreak Travis --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 5c9d29f3b2..ac563289fc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,5 @@ +group: deprecated-2017Q2 + git: submodules: false -- cgit v1.2.1 From d3730241bbc98ec9a44295e3d3f1e7318d4cf73e Mon Sep 17 00:00:00 2001 From: Romain Quidet Date: Thu, 22 Jun 2017 15:50:09 +0200 Subject: 7910: cancel tracking if ongoing animation is stopped manually (#7916) * 7910: cancel tracking if ongoing animation is stopped manually * 7910 updating change log * [ios] Fix map camera animation when a significant change occurs * [ios] Update cancel tracking documentation. --- platform/ios/CHANGELOG.md | 1 + platform/ios/src/MGLMapView.mm | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 83a8e08ae9..351876215a 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -42,6 +42,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Fixed an issue preventing the Mapbox Telemetry confirmation dialog from appearing when opened from within a map view in a modal view controller. ([#9027](https://github.com/mapbox/mapbox-gl-native/pull/9027)) * Corrected the size of MGLMapView’s compass. ([#9060](https://github.com/mapbox/mapbox-gl-native/pull/9060)) * The Improve This Map button in the attribution action sheet now leads to a feedback tool that matches MGLMapView’s rotation and pitch. `-[MGLAttributionInfo feedbackURLAtCenterCoordinate:zoomLevel:]` no longer respects the feedback URL specified in TileJSON. ([#9078](https://github.com/mapbox/mapbox-gl-native/pull/9078)) +* Fixed an issue when user starts tracking position and stops manually the animation. ([#7916](https://github.com/mapbox/mapbox-gl-native/pull/7916)) ### Other changes diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 9d4c295d62..459eda19c8 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -84,6 +84,8 @@ typedef NS_ENUM(NSUInteger, MGLUserTrackingState) { MGLUserTrackingStatePossible = 0, /// The map view has begun to move to the first reported user location. MGLUserTrackingStateBegan, + /// The map view begins a significant transition. + MGLUserTrackingStateBeginSignificantTransition, /// The map view has finished moving to the first reported user location. MGLUserTrackingStateChanged, }; @@ -112,6 +114,9 @@ const NSUInteger MGLTargetFrameInterval = 1; // Target FPS will be 60 divided b /// Tolerance for snapping to true north, measured in degrees in either direction. const CLLocationDirection MGLToleranceForSnappingToNorth = 7; +/// Distance threshold to stop the camera while animating. +const CLLocationDistance MGLDistanceThresholdForCameraPause = 500; + /// Reuse identifier and file name of the default point annotation image. static NSString * const MGLDefaultStyleMarkerSymbolName = @"default_marker"; @@ -309,6 +314,8 @@ public: /// Center coordinate of the pinch gesture on the previous iteration of the gesture. CLLocationCoordinate2D _previousPinchCenterCoordinate; NSUInteger _previousPinchNumberOfTouches; + + CLLocationDistance _distanceFromOldUserLocation; BOOL _delegateHasAlphasForShapeAnnotations; BOOL _delegateHasStrokeColorsForShapeAnnotations; @@ -1166,6 +1173,10 @@ public: { _changeDelimiterSuppressionDepth = 0; _mbglMap->setGestureInProgress(false); + if (self.userTrackingState == MGLUserTrackingStateBegan) + { + [self setUserTrackingMode:MGLUserTrackingModeNone animated:NO]; + } _mbglMap->cancelTransitions(); } @@ -4385,6 +4396,7 @@ public: { CLLocation *oldLocation = self.userLocation.location; CLLocation *newLocation = locations.lastObject; + _distanceFromOldUserLocation = [newLocation distanceFromLocation:oldLocation]; if ( ! _showsUserLocation || ! newLocation || ! CLLocationCoordinate2DIsValid(newLocation.coordinate)) return; @@ -4478,7 +4490,12 @@ public: /// first location update. - (void)didUpdateLocationSignificantlyAnimated:(BOOL)animated { - self.userTrackingState = MGLUserTrackingStateBegan; + + if (_distanceFromOldUserLocation >= MGLDistanceThresholdForCameraPause) { + self.userTrackingState = MGLUserTrackingStateBeginSignificantTransition; + } else { + self.userTrackingState = MGLUserTrackingStateBegan; + } MGLMapCamera *camera = self.camera; camera.centerCoordinate = self.userLocation.location.coordinate; @@ -4498,7 +4515,8 @@ public: peakAltitude:-1 completionHandler:^{ MGLMapView *strongSelf = weakSelf; - if (strongSelf.userTrackingState == MGLUserTrackingStateBegan) + if (strongSelf.userTrackingState == MGLUserTrackingStateBegan || + strongSelf.userTrackingState == MGLDistanceThresholdForCameraPause) { strongSelf.userTrackingState = MGLUserTrackingStateChanged; } -- cgit v1.2.1 From 2a5dc2d55b759541ed7e807a7b889a283b0c8372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Wed, 14 Jun 2017 17:35:08 -0700 Subject: [ios, macos] Rewrote MGLStyle class documentation The documentation comment now provides a high-level overview of the runtime styling API and its components, as well as the main workflow for using a style. --- platform/darwin/src/MGLStyle.h | 53 +++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/platform/darwin/src/MGLStyle.h b/platform/darwin/src/MGLStyle.h index 08c6c047f1..8ffd7db2b2 100644 --- a/platform/darwin/src/MGLStyle.h +++ b/platform/darwin/src/MGLStyle.h @@ -32,14 +32,51 @@ NS_ASSUME_NONNULL_BEGIN static MGL_EXPORT const NSInteger MGLStyleDefaultVersion = 10; /** - The proxy object for the current map style. - - MGLStyle provides a set of convenience methods for changing Mapbox - default styles using `-[MGLMapView styleURL]`. - Learn more about Mapbox default styles. - - It is also possible to directly manipulate the current map style - via `-[MGLMapView style]` by updating the style's data sources or layers. + An `MGLStyle` object represents the active map style of an `MGLMapView`. A + style defines both the map’s content and every aspect of its appearance. Styles + can be designed in + Mapbox Studio and hosted on + mapbox.com. `MGLStyle` provides methods for inspecting and manipulating a style + dynamically, with classes and properties that parallel the style JSON format + defined by the + Mapbox Style Specification. + + You set a map view’s active style using the `MGLMapView.styleURL` property. + `MGLStyle` provides a set of convenience methods that return the URLs of + popular Mapbox-designed styles. + Once the `-[MGLMapViewDelegate mapView:didFinishLoadingStyle:]` or + `-[MGLMapViewDelegate mapViewDidFinishLoadingMap:]` method is called, signaling + that the style has finished loading, you can use the `MGLMapView.style` + property to obtain the map view’s `MGLStyle`. + + A style primarily consists of the following components: + + * _Content sources_ supply content to be shown on the map. Use methods such as + `-sourceWithIdentifier:` and `-addSource:` to configure the style’s content + sources, which are represented by `MGLSource` objects. + * _Style layers_ manage the layout and appearance of content at specific + z-indices in the style. Most kinds of style layers display content provided + by a content source. Use methods such as `-layerWithIdentifier:` and + `-addLayer:` to configure the style’s layers, which are represented by + `MGLStyleLayer` objects. + * _Style images_ are used as icons and patterns in style layers. Use the + `-setImage:forName:` method to register an image as a style image. + (Annotations are represented by annotation images rather than style images. + To configure an annotation’s appearance, use the + `-[MGLMapViewDelegate mapView:imageForAnnotation:]` method.) + * The style’s _light_ is the light source affecting any 3D extruded fills. + Use the `light` property to configure the style’s light, which is represented + by an `MGLLight` object. + + The `MGLStyle`, `MGLSource`, `MGLStyleLayer`, and `MGLLight` classes are + collectively known as the _runtime styling API_. The active style influences a + related API, visible feature querying, which is available through methods such + as `-[MGLMapView visibleFeaturesInRect:]`. + + Some terminology differs between the Mapbox Style Specification and the various + classes associated with `MGLStyle`. Consult the + “[Information for Style Authors](../for-style-authors.html)” guide for an + overview of these differences. @note Wait until the map style has finished loading before modifying a map's style via any of the `MGLStyle` instance methods below. You can use the -- cgit v1.2.1 From b7ec96d352c78172b6df4afedd6fc0e7db142a54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Fri, 16 Jun 2017 10:28:02 -0700 Subject: [ios, macos] Corrected MGLSource subclassing documentation --- platform/darwin/src/MGLSource.h | 4 ++-- platform/darwin/src/MGLVectorStyleLayer.h | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/platform/darwin/src/MGLSource.h b/platform/darwin/src/MGLSource.h index 151363104e..a504a01791 100644 --- a/platform/darwin/src/MGLSource.h +++ b/platform/darwin/src/MGLSource.h @@ -17,8 +17,8 @@ NS_ASSUME_NONNULL_BEGIN `-[MGLStyle addSource:]` and `-[MGLStyle sourceWithIdentifier:]`. Create instances of `MGLShapeSource` and the concrete subclasses of - `MGLTileSource`, `MGLVectorSource` and `MGLRasterSource` in order to use - `MGLMultiPoint`'s properties and methods. Do not create instances of `MGLSource` + `MGLTileSource` (`MGLVectorSource` and `MGLRasterSource`) in order to use + `MGLSource`'s properties and methods. Do not create instances of `MGLSource` directly, and do not create your own subclasses of this class. */ MGL_EXPORT diff --git a/platform/darwin/src/MGLVectorStyleLayer.h b/platform/darwin/src/MGLVectorStyleLayer.h index e54a580aed..6603570e25 100644 --- a/platform/darwin/src/MGLVectorStyleLayer.h +++ b/platform/darwin/src/MGLVectorStyleLayer.h @@ -9,10 +9,11 @@ NS_ASSUME_NONNULL_BEGIN `MGLVectorStyleLayer` is an abstract superclass for style layers whose content is defined by an `MGLShapeSource` or `MGLVectorSource` object. - Create instances of `MGLCircleStyleLayer`, `MGLFillStyleLayer`, `MGLLineStyleLayer`, - and `MGLSymbolStyleLayer` in order to use `MGLVectorStyleLayer`'s properties and - methods. Do not create instances of `MGLVectorStyleLayer` directly, and do not - create your own subclasses of this class. + Create instances of `MGLCircleStyleLayer`, `MGLFillStyleLayer`, + `MGLFillExtrusionStyleLayer`, `MGLLineStyleLayer`, and `MGLSymbolStyleLayer` in + order to use `MGLVectorStyleLayer`'s properties and methods. Do not create + instances of `MGLVectorStyleLayer` directly, and do not create your own + subclasses of this class. */ MGL_EXPORT @interface MGLVectorStyleLayer : MGLForegroundStyleLayer -- cgit v1.2.1 From a1c5b32da66a32e52e24163f826dabbc1e4d38bf Mon Sep 17 00:00:00 2001 From: Fabian Guerra Soto Date: Thu, 22 Jun 2017 14:36:21 -0400 Subject: Boxing ObjC structs (#9343) * [ios, macos] Make structs boxable * [ios, macos] Update changelogs. --- platform/darwin/src/MGLGeometry.h | 4 ++-- platform/darwin/src/MGLLight.h | 2 +- platform/darwin/src/MGLOfflinePack.h | 2 +- platform/darwin/src/MGLTypes.h | 2 +- platform/darwin/test/MGLLightTest.mm | 6 +++--- platform/ios/CHANGELOG.md | 1 + platform/macos/CHANGELOG.md | 1 + 7 files changed, 10 insertions(+), 8 deletions(-) diff --git a/platform/darwin/src/MGLGeometry.h b/platform/darwin/src/MGLGeometry.h index 9fcb9dd37c..d37741cde5 100644 --- a/platform/darwin/src/MGLGeometry.h +++ b/platform/darwin/src/MGLGeometry.h @@ -7,7 +7,7 @@ NS_ASSUME_NONNULL_BEGIN /** Defines the area spanned by an `MGLCoordinateBounds`. */ -typedef struct MGLCoordinateSpan { +typedef struct __attribute__((objc_boxable)) MGLCoordinateSpan { /** Latitudes spanned by an `MGLCoordinateBounds`. */ CLLocationDegrees latitudeDelta; /** Longitudes spanned by an `MGLCoordinateBounds`. */ @@ -38,7 +38,7 @@ NS_INLINE BOOL MGLCoordinateSpanEqualToCoordinateSpan(MGLCoordinateSpan span1, M extern MGL_EXPORT const MGLCoordinateSpan MGLCoordinateSpanZero; /** A rectangular area as measured on a two-dimensional map projection. */ -typedef struct MGLCoordinateBounds { +typedef struct __attribute__((objc_boxable)) MGLCoordinateBounds { /** Coordinate at the southwest corner. */ CLLocationCoordinate2D sw; /** Coordinate at the northeast corner. */ diff --git a/platform/darwin/src/MGLLight.h b/platform/darwin/src/MGLLight.h index 55b789f043..50db3f45fd 100644 --- a/platform/darwin/src/MGLLight.h +++ b/platform/darwin/src/MGLLight.h @@ -27,7 +27,7 @@ typedef NS_ENUM(NSUInteger, MGLLightAnchor) { A structure containing information about the position of the light source relative to lit geometries. */ -typedef struct MGLSphericalPosition { +typedef struct __attribute__((objc_boxable)) MGLSphericalPosition { /** Distance from the center of the base of an object to its light. */ CGFloat radial; /** Position of the light relative to 0° (0° when `MGLLight.anchor` is set to viewport corresponds diff --git a/platform/darwin/src/MGLOfflinePack.h b/platform/darwin/src/MGLOfflinePack.h index 0b2db35b1a..dfc47bf1c8 100644 --- a/platform/darwin/src/MGLOfflinePack.h +++ b/platform/darwin/src/MGLOfflinePack.h @@ -54,7 +54,7 @@ typedef NS_ENUM (NSInteger, MGLOfflinePackState) { A structure containing information about an offline pack’s current download progress. */ -typedef struct MGLOfflinePackProgress { +typedef struct __attribute__((objc_boxable)) MGLOfflinePackProgress { /** The number of resources, including tiles, that have been completely downloaded and are ready to use offline. diff --git a/platform/darwin/src/MGLTypes.h b/platform/darwin/src/MGLTypes.h index 16f510b5a6..b3227e1cdf 100644 --- a/platform/darwin/src/MGLTypes.h +++ b/platform/darwin/src/MGLTypes.h @@ -78,7 +78,7 @@ typedef NS_OPTIONS(NSUInteger, MGLMapDebugMaskOptions) { /** A structure containing information about a transition. */ -typedef struct MGLTransition { +typedef struct __attribute__((objc_boxable)) MGLTransition { /** The amount of time the animation should take, not including the delay. */ diff --git a/platform/darwin/test/MGLLightTest.mm b/platform/darwin/test/MGLLightTest.mm index b021bd1b73..8f901cbb72 100644 --- a/platform/darwin/test/MGLLightTest.mm +++ b/platform/darwin/test/MGLLightTest.mm @@ -132,9 +132,9 @@ - (void)testValueAdditions { MGLSphericalPosition position = MGLSphericalPositionMake(1.15, 210, 30); - XCTAssertEqual([NSValue valueWithMGLSphericalPosition:position].MGLSphericalPositionValue.radial, position.radial); - XCTAssertEqual([NSValue valueWithMGLSphericalPosition:position].MGLSphericalPositionValue.azimuthal, position.azimuthal); - XCTAssertEqual([NSValue valueWithMGLSphericalPosition:position].MGLSphericalPositionValue.polar, position.polar); + XCTAssertEqual(@(position).MGLSphericalPositionValue.radial, position.radial); + XCTAssertEqual(@(position).MGLSphericalPositionValue.azimuthal, position.azimuthal); + XCTAssertEqual(@(position).MGLSphericalPositionValue.polar, position.polar); XCTAssertEqual([NSValue valueWithMGLLightAnchor:MGLLightAnchorMap].MGLLightAnchorValue, MGLLightAnchorMap); XCTAssertEqual([NSValue valueWithMGLLightAnchor:MGLLightAnchorViewport].MGLLightAnchorValue, MGLLightAnchorViewport); } diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 351876215a..2a85186765 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -52,6 +52,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * The error passed into `-[MGLMapViewDelegate mapViewDidFailLoadingMap:withError:]` now includes a more specific description and failure reason. ([#8418](https://github.com/mapbox/mapbox-gl-native/pull/8418)) * Improved CPU and battery performance while animating a tilted map’s camera in an area with many labels. ([#9031](https://github.com/mapbox/mapbox-gl-native/pull/9031)) * Fixed an issue rendering polylines that contain duplicate vertices. ([#8808](https://github.com/mapbox/mapbox-gl-native/pull/8808)) +* Added struct boxing to `MGLCoordinateSpan`, `MGLCoordinateBounds`, `MGLOfflinePackProgress`, and `MGLTransition`. ([#9343](https://github.com/mapbox/mapbox-gl-native/pull/9343) ## 3.5.4 - May 9, 2017 diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index 5afdd32180..fa912125ec 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -33,6 +33,7 @@ * The `MGLPolyline.coordinate` and `MGLPolygon.coordinate` properties now return the midpoint and centroid, respectively, instead of the first coordinate. ([#8713](https://github.com/mapbox/mapbox-gl-native/pull/8713)) * Improved CPU and battery performance while animating a tilted map’s camera in an area with many labels. ([#9031](https://github.com/mapbox/mapbox-gl-native/pull/9031)) * Fixed an issue rendering polylines that contain duplicate vertices. ([#8808](https://github.com/mapbox/mapbox-gl-native/pull/8808)) +* Added struct boxing to `MGLCoordinateSpan`, `MGLCoordinateBounds`, `MGLOfflinePackProgress`, and `MGLTransition`. ([#9343](https://github.com/mapbox/mapbox-gl-native/pull/9343) ## 0.4.1 - April 8, 2017 -- cgit v1.2.1 From eedd0553b467bb82d5e2e928943beb12522d056c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Thu, 22 Jun 2017 11:09:09 -0700 Subject: [ios] Allow delegate to keep wandering pinch from panning map MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MGLMapView consults MGLMapViewDelegate about whether to zoom the map in response to a pinch gesture, but it should also account for the delegate’s response when panning the map due to the pinch’s center point wandering. Fixes #9168. --- platform/ios/CHANGELOG.md | 1 + platform/ios/src/MGLMapView.mm | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 2a85186765..6cd7d7ead5 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -43,6 +43,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Corrected the size of MGLMapView’s compass. ([#9060](https://github.com/mapbox/mapbox-gl-native/pull/9060)) * The Improve This Map button in the attribution action sheet now leads to a feedback tool that matches MGLMapView’s rotation and pitch. `-[MGLAttributionInfo feedbackURLAtCenterCoordinate:zoomLevel:]` no longer respects the feedback URL specified in TileJSON. ([#9078](https://github.com/mapbox/mapbox-gl-native/pull/9078)) * Fixed an issue when user starts tracking position and stops manually the animation. ([#7916](https://github.com/mapbox/mapbox-gl-native/pull/7916)) +* `-[MGLMapViewDelegate mapView:shouldChangeFromCamera:toCamera:]` can now block any panning caused by a pinch gesture. ([#9344](https://github.com/mapbox/mapbox-gl-native/pull/9344)) ### Other changes diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 459eda19c8..ba37dc3d31 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -1306,16 +1306,16 @@ public: [self.delegate mapView:self shouldChangeFromCamera:oldCamera toCamera:toCamera]) { _mbglMap->setZoom(zoom, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }); - } - // The gesture recognizer only reports the gesture’s current center - // point, so use the previous center point to anchor the transition. - // If the number of touches has changed, the remembered center point is - // meaningless. - if (self.userTrackingMode == MGLUserTrackingModeNone && pinch.numberOfTouches == _previousPinchNumberOfTouches) - { - CLLocationCoordinate2D centerCoordinate = _previousPinchCenterCoordinate; - _mbglMap->setLatLng(MGLLatLngFromLocationCoordinate2D(centerCoordinate), - mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }); + // The gesture recognizer only reports the gesture’s current center + // point, so use the previous center point to anchor the transition. + // If the number of touches has changed, the remembered center point is + // meaningless. + if (self.userTrackingMode == MGLUserTrackingModeNone && pinch.numberOfTouches == _previousPinchNumberOfTouches) + { + CLLocationCoordinate2D centerCoordinate = _previousPinchCenterCoordinate; + _mbglMap->setLatLng(MGLLatLngFromLocationCoordinate2D(centerCoordinate), + mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }); + } } [self cameraIsChanging]; } -- cgit v1.2.1 From 9436eca1d45738ab316b89e9812b2a913ec70117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Thu, 22 Jun 2017 11:54:41 -0700 Subject: [ios] Added Hungarian localization from Transifex --- platform/ios/CHANGELOG.md | 1 + platform/ios/app/hu.lproj/Localizable.strings | 0 platform/ios/ios.xcodeproj/project.pbxproj | 5 ++ .../ios/resources/hu.lproj/Localizable.strings | 93 ++++++++++++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 platform/ios/app/hu.lproj/Localizable.strings create mode 100644 platform/ios/resources/hu.lproj/Localizable.strings diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 6cd7d7ead5..df7ccb12d3 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -9,6 +9,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Xcode 8.0 or higher is now recommended for using this SDK. ([#8775](https://github.com/mapbox/mapbox-gl-native/pull/8775)) * Fixed an issue in the static framework where localizations would never load. ([#9074](https://github.com/mapbox/mapbox-gl-native/pull/9074)) * Updated MGLMapView’s logo view to display [the new Mapbox logo](https://www.mapbox.com/blog/new-mapbox-logo/). ([#8771](https://github.com/mapbox/mapbox-gl-native/pull/8771), [#8773](https://github.com/mapbox/mapbox-gl-native/pull/8773)) +* Added a Hungarian localization. ([#9347](https://github.com/mapbox/mapbox-gl-native/pull/9347)) ### Styles diff --git a/platform/ios/app/hu.lproj/Localizable.strings b/platform/ios/app/hu.lproj/Localizable.strings new file mode 100644 index 0000000000..e69de29bb2 diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index 5120d63f20..ab110bca5c 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -745,6 +745,8 @@ DA57D4AA1EBA8ED300793288 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = es; path = es.lproj/Localizable.stringsdict; sourceTree = ""; }; DA57D4AB1EBA909900793288 /* lt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = lt; path = lt.lproj/Localizable.stringsdict; sourceTree = ""; }; DA57D4AC1EBA922A00793288 /* vi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = vi; path = vi.lproj/Localizable.stringsdict; sourceTree = ""; }; + DA5C09BA1EFC48550056B178 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Localizable.strings; sourceTree = ""; }; + DA5C09BB1EFC486C0056B178 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Localizable.strings; sourceTree = ""; }; DA6023F11E4CE94300DBFF23 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Foundation.strings; sourceTree = ""; }; DA6023F21E4CE94800DBFF23 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sv; path = sv.lproj/Foundation.stringsdict; sourceTree = ""; }; DA618B111E68823600CB7F44 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ru; path = ru.lproj/Localizable.stringsdict; sourceTree = ""; }; @@ -2010,6 +2012,7 @@ ca, fi, nl, + hu, ); mainGroup = DA1DC9411CB6C1C2006E619F; productRefGroup = DA1DC94B1CB6C1C2006E619F /* Products */; @@ -2409,6 +2412,7 @@ DA618B1A1E68883900CB7F44 /* ca */, DA618B2B1E68932D00CB7F44 /* fi */, DAE8CCAD1E6E8C70009B5CB0 /* nl */, + DA5C09BA1EFC48550056B178 /* hu */, ); name = Localizable.strings; sourceTree = ""; @@ -2453,6 +2457,7 @@ DA737AE91E5917C300AD2CDE /* uk */, DA1AC01B1E5B8774006DF1D6 /* lt */, DA618B1B1E68884E00CB7F44 /* ca */, + DA5C09BB1EFC486C0056B178 /* hu */, ); name = Localizable.strings; sourceTree = ""; diff --git a/platform/ios/resources/hu.lproj/Localizable.strings b/platform/ios/resources/hu.lproj/Localizable.strings new file mode 100644 index 0000000000..a4d1b1c3ae --- /dev/null +++ b/platform/ios/resources/hu.lproj/Localizable.strings @@ -0,0 +1,93 @@ +/* Accessibility hint */ +"ANNOTATION_A11Y_HINT" = "Több infót mutat"; + +/* No comment provided by engineer. */ +"API_CLIENT_400_DESC" = "The session data task failed. Original request was: %@"; + +/* No comment provided by engineer. */ +"API_CLIENT_400_REASON" = "A státuszkód %ld volt"; + +/* No comment provided by engineer. */ +"CANCEL" = "Mégse"; + +/* Accessibility hint for closing the selected annotation’s callout view and returning to the map */ +"CLOSE_CALLOUT_A11Y_HINT" = "Visszatér a térképhez"; + +/* Accessibility hint */ +"COMPASS_A11Y_HINT" = "Elforgatja a térképet, hogy észak felé nézzen"; + +/* Accessibility label */ +"COMPASS_A11Y_LABEL" = "Iránytű"; + +/* Compass abbreviation for north */ +"COMPASS_NORTH" = "É"; + +/* Instructions in Interface Builder designable; {key}, {plist file name} */ +"DESIGNABLE" = "To display a Mapbox-hosted map here, set %1$@ to your access token in %2$@\n\nFor detailed instructions, see:"; + +/* Setup documentation URL display string; keep as short as possible */ +"FIRST_STEPS_URL" = "mapbox.com/help/first-steps-ios-sdk"; + +/* Accessibility hint */ +"INFO_A11Y_HINT" = "Shows credits, a feedback form, and more"; + +/* Accessibility label */ +"INFO_A11Y_LABEL" = "Erről a térképről"; + +/* User-friendly error description */ +"LOAD_MAP_FAILED_DESC" = "Nem sikerült betölteni a térképet, mert ismeretlen hiba történt."; + +/* User-friendly error description */ +"LOAD_STYLE_FAILED_DESC" = "Nem sikerült betölteni a térképet, mert a stílust nem lehetett betölteni."; + +/* Accessibility label */ +"LOGO_A11Y_LABEL" = "Mapbox"; + +/* Accessibility label */ +"MAP_A11Y_LABEL" = "Térkép"; + +/* Map accessibility value */ +"MAP_A11Y_VALUE" = "Zoom %1$dx\n%2$ld annotation(s) visible"; + +/* User-friendly error description */ +"PARSE_STYLE_FAILED_DESC" = "Nem sikerült betölteni a térképet, mert a stílus sérült."; + +/* Action sheet title */ +"SDK_NAME" = "Mapbox iOS SDK"; + +/* Developer-only SDK update notification; {latest version, in format x.x.x} */ +"SDK_UPDATE_AVAILABLE" = "Mapbox iOS SDK %@ mostantól elérhető:"; + +/* User-friendly error description */ +"STYLE_NOT_FOUND_DESC" = "Nem sikerült betölteni a térképet, mert a stílus nem található vagy inkompatibilis."; + +/* Telemetry prompt message */ +"TELEMETRY_DISABLED_MSG" = "You can help make OpenStreetMap and Mapbox maps better by contributing anonymous usage data."; + +/* Telemetry prompt button */ +"TELEMETRY_DISABLED_OFF" = "Nem veszek részt"; + +/* Telemetry prompt button */ +"TELEMETRY_DISABLED_ON" = "Részt veszek"; + +/* Telemetry prompt message */ +"TELEMETRY_ENABLED_MSG" = "You are helping to make OpenStreetMap and Mapbox maps better by contributing anonymous usage data."; + +/* Telemetry prompt button */ +"TELEMETRY_ENABLED_OFF" = "Részvétel befejezése"; + +/* Telemetry prompt button */ +"TELEMETRY_ENABLED_ON" = "Részvétel folytatása"; + +/* Telemetry prompt button */ +"TELEMETRY_MORE" = "Többet akarok tudni"; + +/* Action in attribution sheet */ +"TELEMETRY_NAME" = "Mapbox telemetria"; + +/* Telemetry prompt title */ +"TELEMETRY_TITLE" = "Tedd jobbá a Mapbox térképeket"; + +/* Default user location annotation title */ +"USER_DOT_TITLE" = "Itt vagy"; + -- cgit v1.2.1 From 5b4f8fd822f216d203e238134e7a64ee3af174ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Thu, 22 Jun 2017 11:55:40 -0700 Subject: [ios] Updated German localization --- platform/ios/resources/de.lproj/Localizable.strings | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/platform/ios/resources/de.lproj/Localizable.strings b/platform/ios/resources/de.lproj/Localizable.strings index 1ea03e7d61..e8180ea17c 100644 --- a/platform/ios/resources/de.lproj/Localizable.strings +++ b/platform/ios/resources/de.lproj/Localizable.strings @@ -10,6 +10,9 @@ /* No comment provided by engineer. */ "CANCEL" = "Abbrechen"; +/* Accessibility hint for closing the selected annotation’s callout view and returning to the map */ +"CLOSE_CALLOUT_A11Y_HINT" = "Zurück zur Karte "; + /* Accessibility hint */ "COMPASS_A11Y_HINT" = "Dreht die Karte nach Norden"; @@ -31,6 +34,12 @@ /* Accessibility label */ "INFO_A11Y_LABEL" = "Über diese Karte"; +/* User-friendly error description */ +"LOAD_MAP_FAILED_DESC" = "Die Karte konnte nicht geladen werden, da ein unbekannter Fehler aufgetreten ist."; + +/* User-friendly error description */ +"LOAD_STYLE_FAILED_DESC" = "Die Karte konnte nicht geladen werden, da diese Form nicht geladen werden kann"; + /* Accessibility label */ "LOGO_A11Y_LABEL" = "Mapbox"; @@ -40,9 +49,18 @@ /* Map accessibility value */ "MAP_A11Y_VALUE" = "Zoomstufe %1$d\n%2$ld Anmerkung(en) sichtbar"; +/* User-friendly error description */ +"PARSE_STYLE_FAILED_DESC" = "Die Karte konnte nicht geladen werden, da diese Form beschädigt ist."; + /* Action sheet title */ "SDK_NAME" = "Mapbox iOS SDK"; +/* Developer-only SDK update notification; {latest version, in format x.x.x} */ +"SDK_UPDATE_AVAILABLE" = "Mapbox iOS SDK Version %@ ist ab sofort verfügbar."; + +/* User-friendly error description */ +"STYLE_NOT_FOUND_DESC" = "Die Karte konnte nicht geladen werden, da diese Form nicht gefunden werden kann oder nicht kompatibel ist."; + /* Telemetry prompt message */ "TELEMETRY_DISABLED_MSG" = "Durch anonymisierte Nutzungsdaten können Sie helfen, OpenStreetMap- und Mapbox-Karten zu verbessern."; -- cgit v1.2.1 From 50922433cd688a8167a31bda41eb90f017392233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Thu, 22 Jun 2017 11:42:08 -0700 Subject: [ios, macos] Updated changelogs Also corrected the version number in the macOS changelog. --- platform/ios/CHANGELOG.md | 5 +++-- platform/macos/CHANGELOG.md | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index df7ccb12d3..113d277806 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -23,6 +23,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Fixed an issue where re-adding a layer that had been previously removed from a style would reset its paint properties. Moved initializers for `MGLTileSource`, `MGLStyleLayer`, and `MGLForegroundStyleLayer` to their concrete subclasses; because these classes were already intended for initialization only via concrete subclasses, this should have no developer impact. ([#8626](https://github.com/mapbox/mapbox-gl-native/pull/8626)) * Fixed a crash that occurred when removing a source that was still being used by one or more style layers. Since this is a programming error, a warning is logged to the console instead. ([#9129](https://github.com/mapbox/mapbox-gl-native/pull/9129)) * Feature querying results now account for any changes to a feature’s size caused by a source or composite style function. ([#8665](https://github.com/mapbox/mapbox-gl-native/pull/8665)) +* Fixed the behavior of composite functions that specify fractional zoom level stops. ([#9289](https://github.com/mapbox/mapbox-gl-native/pull/9289)) * Letter spacing is now disabled in Arabic text so that ligatures are drawn correctly. ([#9062](https://github.com/mapbox/mapbox-gl-native/pull/9062)) * Improved the performance of styles using source and composite style functions. ([#9185](https://github.com/mapbox/mapbox-gl-native/pull/9185), [#9257](https://github.com/mapbox/mapbox-gl-native/pull/9257)) @@ -43,8 +44,8 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Fixed an issue preventing the Mapbox Telemetry confirmation dialog from appearing when opened from within a map view in a modal view controller. ([#9027](https://github.com/mapbox/mapbox-gl-native/pull/9027)) * Corrected the size of MGLMapView’s compass. ([#9060](https://github.com/mapbox/mapbox-gl-native/pull/9060)) * The Improve This Map button in the attribution action sheet now leads to a feedback tool that matches MGLMapView’s rotation and pitch. `-[MGLAttributionInfo feedbackURLAtCenterCoordinate:zoomLevel:]` no longer respects the feedback URL specified in TileJSON. ([#9078](https://github.com/mapbox/mapbox-gl-native/pull/9078)) -* Fixed an issue when user starts tracking position and stops manually the animation. ([#7916](https://github.com/mapbox/mapbox-gl-native/pull/7916)) * `-[MGLMapViewDelegate mapView:shouldChangeFromCamera:toCamera:]` can now block any panning caused by a pinch gesture. ([#9344](https://github.com/mapbox/mapbox-gl-native/pull/9344)) +* If the user taps on the map while it is flying to the user’s location, the user dot no longer appears in the incorrect location. ([#7916](https://github.com/mapbox/mapbox-gl-native/pull/7916)) ### Other changes @@ -54,7 +55,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * The error passed into `-[MGLMapViewDelegate mapViewDidFailLoadingMap:withError:]` now includes a more specific description and failure reason. ([#8418](https://github.com/mapbox/mapbox-gl-native/pull/8418)) * Improved CPU and battery performance while animating a tilted map’s camera in an area with many labels. ([#9031](https://github.com/mapbox/mapbox-gl-native/pull/9031)) * Fixed an issue rendering polylines that contain duplicate vertices. ([#8808](https://github.com/mapbox/mapbox-gl-native/pull/8808)) -* Added struct boxing to `MGLCoordinateSpan`, `MGLCoordinateBounds`, `MGLOfflinePackProgress`, and `MGLTransition`. ([#9343](https://github.com/mapbox/mapbox-gl-native/pull/9343) +* Added struct boxing to `MGLCoordinateSpan`, `MGLCoordinateBounds`, `MGLOfflinePackProgress`, and `MGLTransition`. ([#9343](https://github.com/mapbox/mapbox-gl-native/pull/9343)) ## 3.5.4 - May 9, 2017 diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index fa912125ec..356a44bf89 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog for Mapbox macOS SDK -## 3.6.0 +## 0.5.0 ### Packaging @@ -19,6 +19,7 @@ * Fixed an issue where re-adding a layer that had been previously removed from a style would reset its paint properties. Moved initializers for `MGLTileSource`, `MGLStyleLayer`, and `MGLForegroundStyleLayer` to their concrete subclasses; because these classes were already intended for initialization only via concrete subclasses, this should have no developer impact. ([#8626](https://github.com/mapbox/mapbox-gl-native/pull/8626)) * Fixed a crash that occurred when removing a source that was still being used by one or more style layers. Since this is a programming error, a warning is logged to the console instead. ([#9129](https://github.com/mapbox/mapbox-gl-native/pull/9129)) * Feature querying results now account for any changes to a feature’s size caused by a source or composite style function. ([#8665](https://github.com/mapbox/mapbox-gl-native/pull/8665)) +* Fixed the behavior of composite functions that specify fractional zoom level stops. ([#9289](https://github.com/mapbox/mapbox-gl-native/pull/9289)) * Letter spacing is now disabled in Arabic text so that ligatures are drawn correctly. ([#9062](https://github.com/mapbox/mapbox-gl-native/pull/9062)) * Improved the performance of styles using source and composite style functions. ([#9185](https://github.com/mapbox/mapbox-gl-native/pull/9185), [#9257](https://github.com/mapbox/mapbox-gl-native/pull/9257)) @@ -33,7 +34,7 @@ * The `MGLPolyline.coordinate` and `MGLPolygon.coordinate` properties now return the midpoint and centroid, respectively, instead of the first coordinate. ([#8713](https://github.com/mapbox/mapbox-gl-native/pull/8713)) * Improved CPU and battery performance while animating a tilted map’s camera in an area with many labels. ([#9031](https://github.com/mapbox/mapbox-gl-native/pull/9031)) * Fixed an issue rendering polylines that contain duplicate vertices. ([#8808](https://github.com/mapbox/mapbox-gl-native/pull/8808)) -* Added struct boxing to `MGLCoordinateSpan`, `MGLCoordinateBounds`, `MGLOfflinePackProgress`, and `MGLTransition`. ([#9343](https://github.com/mapbox/mapbox-gl-native/pull/9343) +* Added struct boxing to `MGLCoordinateSpan`, `MGLCoordinateBounds`, `MGLOfflinePackProgress`, and `MGLTransition`. ([#9343](https://github.com/mapbox/mapbox-gl-native/pull/9343)) ## 0.4.1 - April 8, 2017 -- cgit v1.2.1 From 3e40cab22dbf31f5575009a5e2841185c0868062 Mon Sep 17 00:00:00 2001 From: Fabian Guerra Date: Thu, 22 Jun 2017 15:58:22 -0400 Subject: [ios] Update pods spec for iOS v3.6.0-rc.1 --- platform/ios/Mapbox-iOS-SDK-symbols.podspec | 2 +- platform/ios/Mapbox-iOS-SDK.podspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/ios/Mapbox-iOS-SDK-symbols.podspec b/platform/ios/Mapbox-iOS-SDK-symbols.podspec index 18a8837d80..382acb13a4 100644 --- a/platform/ios/Mapbox-iOS-SDK-symbols.podspec +++ b/platform/ios/Mapbox-iOS-SDK-symbols.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |m| - version = '3.6.0-beta.3' + version = '3.6.0-rc.1' m.name = 'Mapbox-iOS-SDK-symbols' m.version = "#{version}-symbols" diff --git a/platform/ios/Mapbox-iOS-SDK.podspec b/platform/ios/Mapbox-iOS-SDK.podspec index 07a725922b..0d25ca3be4 100644 --- a/platform/ios/Mapbox-iOS-SDK.podspec +++ b/platform/ios/Mapbox-iOS-SDK.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |m| - version = '3.6.0-beta.3' + version = '3.6.0-rc.1' m.name = 'Mapbox-iOS-SDK' m.version = version -- cgit v1.2.1 From 9b0b74dba6f33b49e2ed009fd0fef2755a944954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Fri, 23 Jun 2017 16:10:04 -0700 Subject: [ios] Fixed infinite loop zooming in past z23 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At zoom levels where the minimum 1 meter or 4 feet would be wider than the scale bar’s maximum width, the local variable holding the preferred row was left undefined. A loop that later iterated based on this row would effectively iterate infinitely until memory pressure forces the system to quit the application. --- platform/ios/src/MGLScaleBar.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/ios/src/MGLScaleBar.mm b/platform/ios/src/MGLScaleBar.mm index cd88c1e08e..410aa7d57e 100644 --- a/platform/ios/src/MGLScaleBar.mm +++ b/platform/ios/src/MGLScaleBar.mm @@ -188,9 +188,9 @@ static const CGFloat MGLFeetPerMeter = 3.28084; - (MGLRow)preferredRow { CLLocationDistance maximumDistance = [self maximumWidth] * [self unitsPerPoint]; - MGLRow row; BOOL useMetric = [self usesMetricSystem]; + MGLRow row = useMetric ? MGLMetricTable[0] : MGLImperialTable[0]; NSUInteger count = useMetric ? sizeof(MGLMetricTable) / sizeof(MGLMetricTable[0]) : sizeof(MGLImperialTable) / sizeof(MGLImperialTable[0]); -- cgit v1.2.1 From 361dda25a63b44d6be08fba91db891871b01e233 Mon Sep 17 00:00:00 2001 From: Jason Wray Date: Mon, 26 Jun 2017 12:52:04 -0400 Subject: [ios, macos] Fix size and color of default marker image --- platform/default/resources/default_marker.svg | 2 +- .../default_marker.imageset/default_marker.pdf | Bin 2601 -> 4354 bytes platform/macos/CHANGELOG.md | 1 + platform/macos/sdk/default_marker.pdf | Bin 2601 -> 4354 bytes 4 files changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/default/resources/default_marker.svg b/platform/default/resources/default_marker.svg index 3cb5af09a4..08ae2d76d6 100644 --- a/platform/default/resources/default_marker.svg +++ b/platform/default/resources/default_marker.svg @@ -4,7 +4,7 @@ - diff --git a/platform/ios/resources/Images.xcassets/default_marker.imageset/default_marker.pdf b/platform/ios/resources/Images.xcassets/default_marker.imageset/default_marker.pdf index 4e2e332301..d3e0e2ce12 100644 Binary files a/platform/ios/resources/Images.xcassets/default_marker.imageset/default_marker.pdf and b/platform/ios/resources/Images.xcassets/default_marker.imageset/default_marker.pdf differ diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index 356a44bf89..db6d66355a 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -35,6 +35,7 @@ * Improved CPU and battery performance while animating a tilted map’s camera in an area with many labels. ([#9031](https://github.com/mapbox/mapbox-gl-native/pull/9031)) * Fixed an issue rendering polylines that contain duplicate vertices. ([#8808](https://github.com/mapbox/mapbox-gl-native/pull/8808)) * Added struct boxing to `MGLCoordinateSpan`, `MGLCoordinateBounds`, `MGLOfflinePackProgress`, and `MGLTransition`. ([#9343](https://github.com/mapbox/mapbox-gl-native/pull/9343)) +* The default marker image has been made slightly larger and now matches the version in the Mapbox iOS SDK. ([#9370](https://github.com/mapbox/mapbox-gl-native/pull/9370)) ## 0.4.1 - April 8, 2017 diff --git a/platform/macos/sdk/default_marker.pdf b/platform/macos/sdk/default_marker.pdf index 4e2e332301..d3e0e2ce12 100644 Binary files a/platform/macos/sdk/default_marker.pdf and b/platform/macos/sdk/default_marker.pdf differ -- cgit v1.2.1 From 24a00231f3f6cf119e3e7e349d1b43ff36750ca9 Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Mon, 26 Jun 2017 08:50:49 -0700 Subject: =?UTF-8?q?[core]=20fix=20render=20doesn=E2=80=99t=20flag=20style?= =?UTF-8?q?=20mutation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mbgl/map/map.cpp | 4 ++-- test/map/map.test.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 37442770fa..d52315d19c 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -238,8 +238,8 @@ void Map::Impl::render(View& view) { transform.getState(), style->impl->getGlyphURL(), style->impl->spriteLoaded, - style->getTransitionOptions(), - style->getLight()->impl, + style->impl->getTransitionOptions(), + style->impl->getLight()->impl, style->impl->getImageImpls(), style->impl->getSourceImpls(), style->impl->getLayerImpls(), diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp index bed46f2c3e..a820590fb4 100644 --- a/test/map/map.test.cpp +++ b/test/map/map.test.cpp @@ -280,6 +280,32 @@ TEST(Map, StyleExpiredWithAnnotations) { EXPECT_EQ(1u, fileSource.requests.size()); } +TEST(Map, StyleExpiredWithRender) { + // Rendering should not prevent revalidation of an expired style. + + using namespace std::chrono_literals; + + MapTest test; + FakeFileSource fileSource; + + Map map(test.backend, test.view.getSize(), 1, fileSource, test.threadPool, MapMode::Still); + map.getStyle().loadURL("mapbox://styles/test"); + EXPECT_EQ(1u, fileSource.requests.size()); + + Response response; + response.data = std::make_shared(util::read_file("test/fixtures/api/empty.json")); + response.expires = util::now() - 1h; + + fileSource.respond(Resource::Style, response); + EXPECT_EQ(1u, fileSource.requests.size()); + + map.render(test.view); + EXPECT_EQ(1u, fileSource.requests.size()); + + fileSource.respond(Resource::Style, response); + EXPECT_EQ(1u, fileSource.requests.size()); +} + TEST(Map, StyleEarlyMutation) { // An early mutation should not prevent the initial style load. -- cgit v1.2.1 From 88b2fbd4ecd0b4b59e900ce743abed41d63bbf46 Mon Sep 17 00:00:00 2001 From: Jason Wray Date: Wed, 21 Jun 2017 23:55:56 -0400 Subject: [darwin] Assign threads more specific names --- platform/darwin/src/nsthread.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/darwin/src/nsthread.mm b/platform/darwin/src/nsthread.mm index 6caa1be43e..458db968d8 100644 --- a/platform/darwin/src/nsthread.mm +++ b/platform/darwin/src/nsthread.mm @@ -15,7 +15,8 @@ std::string getCurrentThreadName() { } void setCurrentThreadName(const std::string& name) { - pthread_setname_np(name.c_str()); + std::string qualifiedName = "com.mapbox.mbgl." + name; + pthread_setname_np(qualifiedName.c_str()); } void makeThreadLowPriority() { -- cgit v1.2.1 From 20189db67fa6b5b769fc802d67df77e0988799b2 Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Mon, 26 Jun 2017 10:06:47 -0700 Subject: [core] remove tile cache size setter --- include/mbgl/map/map.hpp | 1 - src/mbgl/annotation/render_annotation_source.cpp | 4 ---- src/mbgl/annotation/render_annotation_source.hpp | 1 - src/mbgl/map/map.cpp | 11 ----------- src/mbgl/renderer/render_source.hpp | 1 - src/mbgl/renderer/render_style.cpp | 6 ------ src/mbgl/renderer/render_style.hpp | 1 - src/mbgl/renderer/sources/render_geojson_source.cpp | 4 ---- src/mbgl/renderer/sources/render_geojson_source.hpp | 1 - src/mbgl/renderer/sources/render_image_source.hpp | 2 -- src/mbgl/renderer/sources/render_raster_source.cpp | 4 ---- src/mbgl/renderer/sources/render_raster_source.hpp | 1 - src/mbgl/renderer/sources/render_vector_source.cpp | 4 ---- src/mbgl/renderer/sources/render_vector_source.hpp | 1 - 14 files changed, 42 deletions(-) diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index dd29d444bd..1b45c87c28 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -157,7 +157,6 @@ public: AnnotationIDs queryPointAnnotations(const ScreenBox&); // Memory - void setSourceTileCacheSize(size_t); void onLowMemory(); // Debug diff --git a/src/mbgl/annotation/render_annotation_source.cpp b/src/mbgl/annotation/render_annotation_source.cpp index b8601d4ed2..8fb11785fd 100644 --- a/src/mbgl/annotation/render_annotation_source.cpp +++ b/src/mbgl/annotation/render_annotation_source.cpp @@ -69,10 +69,6 @@ std::vector RenderAnnotationSource::querySourceFeatures(const SourceQue return {}; } -void RenderAnnotationSource::setCacheSize(size_t size) { - tilePyramid.setCacheSize(size); -} - void RenderAnnotationSource::onLowMemory() { tilePyramid.onLowMemory(); } diff --git a/src/mbgl/annotation/render_annotation_source.hpp b/src/mbgl/annotation/render_annotation_source.hpp index fe384c64ca..7231452d4f 100644 --- a/src/mbgl/annotation/render_annotation_source.hpp +++ b/src/mbgl/annotation/render_annotation_source.hpp @@ -32,7 +32,6 @@ public: std::vector querySourceFeatures(const SourceQueryOptions&) const final; - void setCacheSize(size_t) final; void onLowMemory() final; void dumpDebugLogs() const final; diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index d52315d19c..4d073802c2 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -92,8 +92,6 @@ public: std::unique_ptr renderStyle; bool cameraMutated = false; - - size_t sourceCacheSize; bool loading = false; util::AsyncTask asyncInvalidate; @@ -823,15 +821,6 @@ bool Map::isFullyLoaded() const { return impl->style->impl->isLoaded() && impl->renderStyle && impl->renderStyle->isLoaded(); } -void Map::setSourceTileCacheSize(size_t size) { - if (size != impl->sourceCacheSize) { - impl->sourceCacheSize = size; - if (!impl->renderStyle) return; - impl->renderStyle->setSourceTileCacheSize(size); - impl->backend.invalidate(); - } -} - void Map::onLowMemory() { if (impl->painter) { BackendScope guard(impl->backend); diff --git a/src/mbgl/renderer/render_source.hpp b/src/mbgl/renderer/render_source.hpp index a00a6c797d..b82547b375 100644 --- a/src/mbgl/renderer/render_source.hpp +++ b/src/mbgl/renderer/render_source.hpp @@ -68,7 +68,6 @@ public: virtual std::vector querySourceFeatures(const SourceQueryOptions&) const = 0; - virtual void setCacheSize(size_t) = 0; virtual void onLowMemory() = 0; virtual void dumpDebugLogs() const = 0; diff --git a/src/mbgl/renderer/render_style.cpp b/src/mbgl/renderer/render_style.cpp index f9c3f0ca9f..79b20a9d71 100644 --- a/src/mbgl/renderer/render_style.cpp +++ b/src/mbgl/renderer/render_style.cpp @@ -417,12 +417,6 @@ std::vector RenderStyle::queryRenderedFeatures(const ScreenLineString& return result; } -void RenderStyle::setSourceTileCacheSize(size_t size) { - for (const auto& entry : renderSources) { - entry.second->setCacheSize(size); - } -} - void RenderStyle::onLowMemory() { for (const auto& entry : renderSources) { entry.second->onLowMemory(); diff --git a/src/mbgl/renderer/render_style.hpp b/src/mbgl/renderer/render_style.hpp index dc33e7b2f4..23a640c482 100644 --- a/src/mbgl/renderer/render_style.hpp +++ b/src/mbgl/renderer/render_style.hpp @@ -59,7 +59,6 @@ public: const TransformState& transformState, const RenderedQueryOptions& options) const; - void setSourceTileCacheSize(size_t); void onLowMemory(); void dumpDebugLogs() const; diff --git a/src/mbgl/renderer/sources/render_geojson_source.cpp b/src/mbgl/renderer/sources/render_geojson_source.cpp index 337b7b8b7a..2c6935b273 100644 --- a/src/mbgl/renderer/sources/render_geojson_source.cpp +++ b/src/mbgl/renderer/sources/render_geojson_source.cpp @@ -84,10 +84,6 @@ std::vector RenderGeoJSONSource::querySourceFeatures(const SourceQueryO return tilePyramid.querySourceFeatures(options); } -void RenderGeoJSONSource::setCacheSize(size_t size) { - tilePyramid.setCacheSize(size); -} - void RenderGeoJSONSource::onLowMemory() { tilePyramid.onLowMemory(); } diff --git a/src/mbgl/renderer/sources/render_geojson_source.hpp b/src/mbgl/renderer/sources/render_geojson_source.hpp index 9b5477e1d0..b7c5a3fa7f 100644 --- a/src/mbgl/renderer/sources/render_geojson_source.hpp +++ b/src/mbgl/renderer/sources/render_geojson_source.hpp @@ -36,7 +36,6 @@ public: std::vector querySourceFeatures(const SourceQueryOptions&) const final; - void setCacheSize(size_t) final; void onLowMemory() final; void dumpDebugLogs() const final; diff --git a/src/mbgl/renderer/sources/render_image_source.hpp b/src/mbgl/renderer/sources/render_image_source.hpp index 5175cbf4a4..88f1c56567 100644 --- a/src/mbgl/renderer/sources/render_image_source.hpp +++ b/src/mbgl/renderer/sources/render_image_source.hpp @@ -42,8 +42,6 @@ public: std::vector querySourceFeatures(const SourceQueryOptions&) const final; - void setCacheSize(size_t) final { - } void onLowMemory() final { } void dumpDebugLogs() const final; diff --git a/src/mbgl/renderer/sources/render_raster_source.cpp b/src/mbgl/renderer/sources/render_raster_source.cpp index 385437af1d..20c148870e 100644 --- a/src/mbgl/renderer/sources/render_raster_source.cpp +++ b/src/mbgl/renderer/sources/render_raster_source.cpp @@ -80,10 +80,6 @@ std::vector RenderRasterSource::querySourceFeatures(const SourceQueryOp return {}; } -void RenderRasterSource::setCacheSize(size_t size) { - tilePyramid.setCacheSize(size); -} - void RenderRasterSource::onLowMemory() { tilePyramid.onLowMemory(); } diff --git a/src/mbgl/renderer/sources/render_raster_source.hpp b/src/mbgl/renderer/sources/render_raster_source.hpp index d1e37a3099..7d0c245e45 100644 --- a/src/mbgl/renderer/sources/render_raster_source.hpp +++ b/src/mbgl/renderer/sources/render_raster_source.hpp @@ -32,7 +32,6 @@ public: std::vector querySourceFeatures(const SourceQueryOptions&) const final; - void setCacheSize(size_t) final; void onLowMemory() final; void dumpDebugLogs() const final; diff --git a/src/mbgl/renderer/sources/render_vector_source.cpp b/src/mbgl/renderer/sources/render_vector_source.cpp index 5b266b10a5..4302fb21ee 100644 --- a/src/mbgl/renderer/sources/render_vector_source.cpp +++ b/src/mbgl/renderer/sources/render_vector_source.cpp @@ -85,10 +85,6 @@ std::vector RenderVectorSource::querySourceFeatures(const SourceQueryOp return tilePyramid.querySourceFeatures(options); } -void RenderVectorSource::setCacheSize(size_t size) { - tilePyramid.setCacheSize(size); -} - void RenderVectorSource::onLowMemory() { tilePyramid.onLowMemory(); } diff --git a/src/mbgl/renderer/sources/render_vector_source.hpp b/src/mbgl/renderer/sources/render_vector_source.hpp index d5d9598a75..5e15fee533 100644 --- a/src/mbgl/renderer/sources/render_vector_source.hpp +++ b/src/mbgl/renderer/sources/render_vector_source.hpp @@ -32,7 +32,6 @@ public: std::vector querySourceFeatures(const SourceQueryOptions&) const final; - void setCacheSize(size_t) final; void onLowMemory() final; void dumpDebugLogs() const final; -- cgit v1.2.1 From d13d82571a301f98981d03964d4e9eb64993198f Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Mon, 26 Jun 2017 10:07:27 -0700 Subject: [macos] remove tile cache size customization --- platform/macos/src/MGLMapView.mm | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index 0a567a8510..e0eb0c477c 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -271,7 +271,6 @@ public: _mbglThreadPool = mbgl::sharedThreadPool(); _mbglMap = new mbgl::Map(*_mbglView, self.size, [NSScreen mainScreen].backingScaleFactor, *mbglFileSource, *_mbglThreadPool, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None, mbgl::ViewportMode::Default); - [self validateTileCacheSize]; // Install the OpenGL layer. Interface Builder’s synchronous drawing means // we can’t display a map, so don’t even bother to have a map layer. @@ -687,9 +686,6 @@ public: - (void)setFrame:(NSRect)frame { super.frame = frame; - if (!NSEqualRects(frame, self.frame)) { - [self validateTileCacheSize]; - } if (!_isTargetingInterfaceBuilder) { _mbglMap->setSize(self.size); } @@ -789,21 +785,6 @@ public: } } -- (void)validateTileCacheSize { - if (!_mbglMap) { - return; - } - - CGFloat zoomFactor = self.maximumZoomLevel - self.minimumZoomLevel + 1; - CGFloat cpuFactor = [NSProcessInfo processInfo].processorCount; - CGFloat memoryFactor = (CGFloat)[NSProcessInfo processInfo].physicalMemory / 1000 / 1000 / 1000; - CGFloat sizeFactor = (NSWidth(self.bounds) / mbgl::util::tileSize) * (NSHeight(self.bounds) / mbgl::util::tileSize); - - NSUInteger cacheSize = zoomFactor * cpuFactor * memoryFactor * sizeFactor * 0.5; - - _mbglMap->setSourceTileCacheSize(cacheSize); -} - - (void)setNeedsGLDisplay { MGLAssertIsMainThread(); @@ -1061,13 +1042,11 @@ public: - (void)setMinimumZoomLevel:(double)minimumZoomLevel { _mbglMap->setMinZoom(minimumZoomLevel); - [self validateTileCacheSize]; } - (void)setMaximumZoomLevel:(double)maximumZoomLevel { _mbglMap->setMaxZoom(maximumZoomLevel); - [self validateTileCacheSize]; } - (double)maximumZoomLevel { -- cgit v1.2.1 From de37ae9628045c825ebf9434b87331c69a75f197 Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Mon, 26 Jun 2017 10:21:00 -0700 Subject: [ios] remove tile cache size customization --- platform/ios/src/MGLMapView.mm | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 6c6d8d2980..c1d257dd51 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -438,7 +438,6 @@ public: const float scaleFactor = [UIScreen instancesRespondToSelector:@selector(nativeScale)] ? [[UIScreen mainScreen] nativeScale] : [[UIScreen mainScreen] scale]; _mbglThreadPool = mbgl::sharedThreadPool(); _mbglMap = new mbgl::Map(*_mbglView, self.size, scaleFactor, *mbglFileSource, *_mbglThreadPool, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None, mbgl::ViewportMode::Default); - [self validateTileCacheSize]; // start paused if in IB if (_isTargetingInterfaceBuilder || background) { @@ -757,42 +756,6 @@ public: #pragma mark - Layout - -- (void)setFrame:(CGRect)frame -{ - [super setFrame:frame]; - if ( ! CGRectEqualToRect(frame, self.frame)) - { - [self validateTileCacheSize]; - } -} - -- (void)setBounds:(CGRect)bounds -{ - [super setBounds:bounds]; - if ( ! CGRectEqualToRect(bounds, self.bounds)) - { - [self validateTileCacheSize]; - } -} - -- (void)validateTileCacheSize -{ - if ( ! _mbglMap) - { - return; - } - - CGFloat zoomFactor = self.maximumZoomLevel - self.minimumZoomLevel + 1; - CGFloat cpuFactor = [NSProcessInfo processInfo].processorCount; - CGFloat memoryFactor = (CGFloat)[NSProcessInfo processInfo].physicalMemory / 1000 / 1000 / 1000; - CGFloat sizeFactor = (CGRectGetWidth(self.bounds) / mbgl::util::tileSize) * - (CGRectGetHeight(self.bounds) / mbgl::util::tileSize); - - NSUInteger cacheSize = zoomFactor * cpuFactor * memoryFactor * sizeFactor * 0.5; - - _mbglMap->setSourceTileCacheSize(cacheSize); -} - + (BOOL)requiresConstraintBasedLayout { return YES; @@ -2547,8 +2510,6 @@ public: - (void)setMinimumZoomLevel:(double)minimumZoomLevel { - _mbglMap->setMinZoom(minimumZoomLevel); - [self validateTileCacheSize]; } - (double)minimumZoomLevel @@ -2559,7 +2520,6 @@ public: - (void)setMaximumZoomLevel:(double)maximumZoomLevel { _mbglMap->setMaxZoom(maximumZoomLevel); - [self validateTileCacheSize]; } - (double)maximumZoomLevel -- cgit v1.2.1 From a35b268606b6becf218286036e4d1cfc22ddcaa3 Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Mon, 26 Jun 2017 10:36:26 -0700 Subject: [android] remove tile cache size customization --- .../com/mapbox/mapboxsdk/maps/NativeMapView.java | 24 ++-------------------- platform/android/src/native_map_view.cpp | 24 ++-------------------- platform/android/src/native_map_view.hpp | 9 +------- 3 files changed, 5 insertions(+), 52 deletions(-) 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 c0586a6449..a88a11d387 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 @@ -1,11 +1,9 @@ package com.mapbox.mapboxsdk.maps; -import android.app.ActivityManager; import android.content.Context; import android.graphics.Bitmap; import android.graphics.PointF; import android.graphics.RectF; -import android.os.Build; import android.support.annotation.IntRange; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -78,27 +76,11 @@ final class NativeMapView { fileSource = FileSource.getInstance(context); pixelRatio = context.getResources().getDisplayMetrics().density; - int availableProcessors = Runtime.getRuntime().availableProcessors(); - ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); - ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); - activityManager.getMemoryInfo(memoryInfo); - long totalMemory = memoryInfo.availMem; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - totalMemory = memoryInfo.totalMem; - } - - if (availableProcessors < 0) { - throw new IllegalArgumentException("availableProcessors cannot be negative."); - } - - if (totalMemory < 0) { - throw new IllegalArgumentException("totalMemory cannot be negative."); - } onMapChangedListeners = new CopyOnWriteArrayList<>(); this.mapView = mapView; String programCacheDir = context.getCacheDir().getAbsolutePath(); - nativeInitialize(this, fileSource, pixelRatio, programCacheDir, availableProcessors, totalMemory); + nativeInitialize(this, fileSource, pixelRatio, programCacheDir); } // @@ -941,9 +923,7 @@ final class NativeMapView { private native void nativeInitialize(NativeMapView nativeMapView, FileSource fileSource, float pixelRatio, - String programCacheDir, - int availableProcessors, - long totalMemory); + String programCacheDir); private native void nativeDestroy(); diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index 13d5be01b9..79e7c3c82f 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -56,13 +56,9 @@ NativeMapView::NativeMapView(jni::JNIEnv& _env, jni::Object _obj, jni::Object jFileSource, jni::jfloat _pixelRatio, - jni::String _programCacheDir, - jni::jint _availableProcessors, - jni::jlong _totalMemory) + jni::String _programCacheDir) : javaPeer(_obj.NewWeakGlobalRef(_env)), pixelRatio(_pixelRatio), - availableProcessors(_availableProcessors), - totalMemory(_totalMemory), threadPool(sharedThreadPool()) { // Get a reference to the JavaVM for callbacks @@ -77,19 +73,6 @@ NativeMapView::NativeMapView(jni::JNIEnv& _env, pixelRatio, mbgl::android::FileSource::getDefaultFileSource(_env, jFileSource), *threadPool, MapMode::Continuous, GLContextMode::Unique, ConstrainMode::HeightOnly, ViewportMode::Default, jni::Make(_env, _programCacheDir)); - - recalculateSourceTileCacheSize(); -} - -void NativeMapView::recalculateSourceTileCacheSize() { - //Calculate a fitting cache size based on device parameters - float zoomFactor = map->getMaxZoom() - map->getMinZoom() + 1; - float cpuFactor = availableProcessors; - float memoryFactor = static_cast(totalMemory) / 1000.0f / 1000.0f / 1000.0f; - float sizeFactor = (static_cast(map->getSize().width) / mbgl::util::tileSize) * - (static_cast(map->getSize().height) / mbgl::util::tileSize); - - map->setSourceTileCacheSize(zoomFactor * cpuFactor * memoryFactor * sizeFactor * 0.5f); } /** @@ -333,7 +316,6 @@ void NativeMapView::resizeView(jni::JNIEnv&, int w, int h) { width = util::max(64, w); height = util::max(64, h); map->setSize({ static_cast(width), static_cast(height) }); - recalculateSourceTileCacheSize(); } void NativeMapView::resizeFramebuffer(jni::JNIEnv&, int w, int h) { @@ -488,7 +470,6 @@ void NativeMapView::resetZoom(jni::JNIEnv&) { void NativeMapView::setMinZoom(jni::JNIEnv&, jni::jdouble zoom) { map->setMinZoom(zoom); - recalculateSourceTileCacheSize(); } jni::jdouble NativeMapView::getMinZoom(jni::JNIEnv&) { @@ -497,7 +478,6 @@ jni::jdouble NativeMapView::getMinZoom(jni::JNIEnv&) { void NativeMapView::setMaxZoom(jni::JNIEnv&, jni::jdouble zoom) { map->setMaxZoom(zoom); - recalculateSourceTileCacheSize(); } jni::jdouble NativeMapView::getMaxZoom(jni::JNIEnv&) { @@ -1473,7 +1453,7 @@ void NativeMapView::registerNative(jni::JNIEnv& env) { // Register the peer jni::RegisterNativePeer(env, NativeMapView::javaClass, "nativePtr", - std::make_unique, jni::Object, jni::jfloat, jni::String, jni::jint, jni::jlong>, + std::make_unique, jni::Object, jni::jfloat, jni::String>, "nativeInitialize", "nativeDestroy", METHOD(&NativeMapView::render, "nativeRender"), diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp index df43ad08b7..393a2c913f 100755 --- a/platform/android/src/native_map_view.hpp +++ b/platform/android/src/native_map_view.hpp @@ -49,9 +49,7 @@ public: jni::Object, jni::Object, jni::jfloat pixelRatio, - jni::String programCacheDir, - jni::jint availableProcessors, - jni::jlong totalMemory); + jni::String programCacheDir); virtual ~NativeMapView(); @@ -290,8 +288,6 @@ private: void updateFps(); private: - void recalculateSourceTileCacheSize(); - JavaVM *vm = nullptr; jni::UniqueWeakObject javaPeer; @@ -327,9 +323,6 @@ private: bool framebufferSizeChanged = true; - int availableProcessors = 0; - size_t totalMemory = 0; - // Ensure these are initialised last std::shared_ptr threadPool; std::unique_ptr map; -- cgit v1.2.1 From 433e54e636293eb3b6644c143866aa0d39198441 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Wed, 28 Jun 2017 14:23:39 +0300 Subject: [core] Clamp to scale boundaries in TransformState::setLatLngZoom --- src/mbgl/map/transform_state.cpp | 2 +- test/map/transform.test.cpp | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp index bbf7e22b31..f052e30a6b 100644 --- a/src/mbgl/map/transform_state.cpp +++ b/src/mbgl/map/transform_state.cpp @@ -358,7 +358,7 @@ void TransformState::setLatLngZoom(const LatLng& latLng, double zoom) { constrained = bounds->constrain(latLng); } - double newScale = zoomScale(zoom); + double newScale = util::clamp(zoomScale(zoom), min_scale, max_scale); const double newWorldSize = newScale * util::tileSize; Bc = newWorldSize / util::DEGREES_MAX; Cc = newWorldSize / util::M2PI; diff --git a/test/map/transform.test.cpp b/test/map/transform.test.cpp index aa49d250b6..6d41a868dc 100644 --- a/test/map/transform.test.cpp +++ b/test/map/transform.test.cpp @@ -28,6 +28,22 @@ TEST(Transform, InvalidZoom) { ASSERT_DOUBLE_EQ(0, transform.getLatLng().latitude()); ASSERT_DOUBLE_EQ(0, transform.getLatLng().longitude()); ASSERT_DOUBLE_EQ(1, transform.getZoom()); + + transform.setZoom(transform.getState().getMaxZoom() + 0.1); + ASSERT_DOUBLE_EQ(transform.getZoom(), transform.getState().getMaxZoom()); + + CameraOptions cameraOptions; + cameraOptions.center = LatLng { util::LATITUDE_MAX, util::LONGITUDE_MAX }; + cameraOptions.zoom = transform.getState().getMaxZoom(); + + // Executing flyTo with maximum zoom level to the same zoom level causes + // frameZoom to be bigger than maximum zoom. + transform.resize(Size { 100, 100 }); + transform.flyTo(cameraOptions); + transform.updateTransitions(transform.getTransitionStart() + transform.getTransitionDuration()); + + ASSERT_TRUE(transform.getState().valid()); + ASSERT_DOUBLE_EQ(transform.getState().getMaxZoom(), transform.getZoom()); } -- cgit v1.2.1 From 1df45a5e42b8f299d01cea09c9717c5df287f0b7 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Wed, 28 Jun 2017 14:36:28 +0300 Subject: [core] Check if frameZoom is NaN in Transform::flyTo callback --- src/mbgl/map/transform.cpp | 5 +++++ test/map/transform.test.cpp | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp index 8d05bc0e91..50f979437d 100644 --- a/src/mbgl/map/transform.cpp +++ b/src/mbgl/map/transform.cpp @@ -293,6 +293,11 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima Point framePoint = util::interpolate(startPoint, endPoint, us); double frameZoom = startZoom + state.scaleZoom(1 / w(s)); + // Zoom can be NaN if size is empty. + if (std::isnan(frameZoom)) { + frameZoom = zoom; + } + // Convert to geographic coordinates and set the new viewpoint. LatLng frameLatLng = Projection::unproject(framePoint, startScale); state.setLatLngZoom(frameLatLng, frameZoom); diff --git a/test/map/transform.test.cpp b/test/map/transform.test.cpp index 6d41a868dc..11c2c1cc6b 100644 --- a/test/map/transform.test.cpp +++ b/test/map/transform.test.cpp @@ -36,6 +36,11 @@ TEST(Transform, InvalidZoom) { cameraOptions.center = LatLng { util::LATITUDE_MAX, util::LONGITUDE_MAX }; cameraOptions.zoom = transform.getState().getMaxZoom(); + // Executing flyTo with an empty size causes frameZoom to be NaN. + transform.flyTo(cameraOptions); + transform.updateTransitions(transform.getTransitionStart() + transform.getTransitionDuration()); + ASSERT_DOUBLE_EQ(transform.getZoom(), transform.getState().getMaxZoom()); + // Executing flyTo with maximum zoom level to the same zoom level causes // frameZoom to be bigger than maximum zoom. transform.resize(Size { 100, 100 }); -- cgit v1.2.1 From 6aecc66fc876825e164675f745ca9c71000ce515 Mon Sep 17 00:00:00 2001 From: Jason Wray Date: Wed, 28 Jun 2017 13:05:12 -0400 Subject: [ios] Minimize tilt gesture delay --- platform/ios/CHANGELOG.md | 1 + platform/ios/src/MGLMapView.mm | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 113d277806..c08952a664 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -46,6 +46,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * The Improve This Map button in the attribution action sheet now leads to a feedback tool that matches MGLMapView’s rotation and pitch. `-[MGLAttributionInfo feedbackURLAtCenterCoordinate:zoomLevel:]` no longer respects the feedback URL specified in TileJSON. ([#9078](https://github.com/mapbox/mapbox-gl-native/pull/9078)) * `-[MGLMapViewDelegate mapView:shouldChangeFromCamera:toCamera:]` can now block any panning caused by a pinch gesture. ([#9344](https://github.com/mapbox/mapbox-gl-native/pull/9344)) * If the user taps on the map while it is flying to the user’s location, the user dot no longer appears in the incorrect location. ([#7916](https://github.com/mapbox/mapbox-gl-native/pull/7916)) +* Improved the responsiveness of the tilt gesture by reducing the initial recognition delay. ([#9386](https://github.com/mapbox/mapbox-gl-native/pull/9386)) ### Other changes diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index ba37dc3d31..f3b0d8506a 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -532,21 +532,21 @@ public: _singleTapGestureRecognizer.delegate = self; [self addGestureRecognizer:_singleTapGestureRecognizer]; - _twoFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTwoFingerTapGesture:)]; - _twoFingerTap.numberOfTouchesRequired = 2; - [_twoFingerTap requireGestureRecognizerToFail:_pinch]; - [_twoFingerTap requireGestureRecognizerToFail:_rotate]; - [self addGestureRecognizer:_twoFingerTap]; - _twoFingerDrag = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleTwoFingerDragGesture:)]; _twoFingerDrag.minimumNumberOfTouches = 2; _twoFingerDrag.maximumNumberOfTouches = 2; _twoFingerDrag.delegate = self; - [_twoFingerDrag requireGestureRecognizerToFail:_twoFingerTap]; [_twoFingerDrag requireGestureRecognizerToFail:_pan]; [self addGestureRecognizer:_twoFingerDrag]; _pitchEnabled = YES; + _twoFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTwoFingerTapGesture:)]; + _twoFingerTap.numberOfTouchesRequired = 2; + [_twoFingerTap requireGestureRecognizerToFail:_pinch]; + [_twoFingerTap requireGestureRecognizerToFail:_rotate]; + [_twoFingerTap requireGestureRecognizerToFail:_twoFingerDrag]; + [self addGestureRecognizer:_twoFingerTap]; + _decelerationRate = MGLMapViewDecelerationRateNormal; _quickZoom = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleQuickZoomGesture:)]; @@ -1682,14 +1682,14 @@ public: if ( ! self.isPitchEnabled) return; _mbglMap->cancelTransitions(); - MGLMapCamera *oldCamera = self.camera; if (twoFingerDrag.state == UIGestureRecognizerStateBegan) { [self trackGestureEvent:MGLEventGesturePitchStart forRecognizer:twoFingerDrag]; [self notifyGestureDidBegin]; } - else if (twoFingerDrag.state == UIGestureRecognizerStateBegan || twoFingerDrag.state == UIGestureRecognizerStateChanged) + + if (twoFingerDrag.state == UIGestureRecognizerStateBegan || twoFingerDrag.state == UIGestureRecognizerStateChanged) { CGFloat gestureDistance = CGPoint([twoFingerDrag translationInView:twoFingerDrag.view]).y; CGFloat currentPitch = _mbglMap->getPitch(); @@ -1699,6 +1699,7 @@ public: CGPoint centerPoint = [self anchorPointForGesture:twoFingerDrag]; + MGLMapCamera *oldCamera = self.camera; MGLMapCamera *toCamera = [self cameraByTiltingToPitch:pitchNew]; if (![self.delegate respondsToSelector:@selector(mapView:shouldChangeFromCamera:toCamera:)] || -- cgit v1.2.1 From 34453eb4e27c0bf45027700e45ad69435f3566d7 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 28 Jun 2017 17:29:20 -0700 Subject: [core] Fix iterator invalidation in erase_if vector::erase invalidates iterators. It's not safe for erase_if to cache the end iterator nor increment, then erase. --- src/mbgl/util/std.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mbgl/util/std.hpp b/src/mbgl/util/std.hpp index 974e21329c..1db20e09e5 100644 --- a/src/mbgl/util/std.hpp +++ b/src/mbgl/util/std.hpp @@ -8,10 +8,10 @@ namespace mbgl { namespace util { template -void erase_if(Container &container, ForwardIterator it, const ForwardIterator end, Predicate pred) { - while (it != end) { +void erase_if(Container &container, ForwardIterator it, Predicate pred) { + while (it != container.end()) { if (pred(*it)) { - container.erase(it++); + it = container.erase(it); } else { ++it; } @@ -20,7 +20,7 @@ void erase_if(Container &container, ForwardIterator it, const ForwardIterator en template void erase_if(Container &container, Predicate pred) { - erase_if(container, container.begin(), container.end(), pred); + erase_if(container, container.begin(), pred); } } // namespace util -- cgit v1.2.1 From 200d184738a2a5c8e7cb19a0f5eaa06d34cb1774 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Thu, 29 Jun 2017 09:29:23 +0200 Subject: OnCameraIdle hook into quickzoom gesture (#9339) * [android] - OnCameraIdle hook into quickzoom gesture * double tap fix * show MyLocationView bearing for GPS when Compass is not available, only show error about missing compass once, fix test activity. * fix accessor lint warning --- .../mapboxsdk/maps/CameraChangeDispatcher.java | 8 +++++--- .../mapbox/mapboxsdk/maps/MapGestureDetector.java | 21 +++++++++++++++++---- .../java/com/mapbox/mapboxsdk/maps/Transform.java | 7 +++++-- .../mapboxsdk/maps/widgets/MyLocationView.java | 18 ++++++++++++------ .../activity/camera/CameraPositionActivity.java | 10 +++++++--- .../MyLocationTrackingModeActivity.java | 2 +- 6 files changed, 47 insertions(+), 19 deletions(-) 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 bd028aecb6..6f7d7c0080 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 @@ -2,8 +2,8 @@ package com.mapbox.mapboxsdk.maps; import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraIdleListener; import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveCanceledListener; -import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveStartedListener; import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveListener; +import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveStartedListener; class CameraChangeDispatcher implements MapboxMap.OnCameraMoveStartedListener, MapboxMap.OnCameraMoveListener, MapboxMap.OnCameraMoveCanceledListener, OnCameraIdleListener { @@ -59,9 +59,11 @@ class CameraChangeDispatcher implements MapboxMap.OnCameraMoveStartedListener, M @Override public void onCameraIdle() { - if (onCameraIdleListener != null && !idle) { + if (!idle) { idle = true; - onCameraIdleListener.onCameraIdle(); + if (onCameraIdleListener != null) { + onCameraIdleListener.onCameraIdle(); + } } } } 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 5346baa4e2..3607703ab1 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 @@ -57,6 +57,7 @@ final class MapGestureDetector { private boolean quickZoom = false; private boolean scrollInProgress = false; private boolean scaleGestureOccurred = false; + private boolean recentScaleGestureOccurred = false; MapGestureDetector(Context context, Transform transform, Projection projection, UiSettings uiSettings, TrackingSettings trackingSettings, AnnotationManager annotationManager, @@ -148,7 +149,7 @@ final class MapGestureDetector { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: // First pointer down, reset scaleGestureOccurred, used to avoid triggering a fling after a scale gesture #7666 - scaleGestureOccurred = false; + recentScaleGestureOccurred = false; transform.setGestureInProgress(true); break; @@ -274,7 +275,7 @@ final class MapGestureDetector { break; case MotionEvent.ACTION_UP: if (quickZoom) { - // insert here? + cameraChangeDispatcher.onCameraIdle(); quickZoom = false; break; } @@ -341,7 +342,7 @@ final class MapGestureDetector { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - if ((!trackingSettings.isScrollGestureCurrentlyEnabled()) || scaleGestureOccurred) { + if ((!trackingSettings.isScrollGestureCurrentlyEnabled()) || recentScaleGestureOccurred) { // don't allow a fling is scroll is disabled // and ignore when a scale gesture has occurred return false; @@ -392,12 +393,17 @@ final class MapGestureDetector { return false; } + if (scaleGestureOccurred) { + return false; + } + if (!scrollInProgress) { scrollInProgress = true; // Cancel any animation transform.cancelTransitions(); cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); + MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapClickEvent( getLocationFromGesture(e1.getX(), e1.getY()), MapboxEvent.GESTURE_PAN_START, transform)); @@ -432,6 +438,7 @@ final class MapGestureDetector { } scaleGestureOccurred = true; + recentScaleGestureOccurred = true; beginTime = detector.getEventTime(); MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapClickEvent( getLocationFromGesture(detector.getFocusX(), detector.getFocusY()), @@ -442,9 +449,11 @@ final class MapGestureDetector { // Called when fingers leave screen @Override public void onScaleEnd(ScaleGestureDetector detector) { + scaleGestureOccurred = false; beginTime = 0; scaleFactor = 1.0f; zoomStarted = false; + cameraChangeDispatcher.onCameraIdle(); } // Called each time a finger moves @@ -480,6 +489,9 @@ final class MapGestureDetector { } // Gesture is a quickzoom if there aren't two fingers + if (!quickZoom && !twoTap) { + cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); + } quickZoom = !twoTap; // make an assumption here; if the zoom center is specified by the gesture, it's NOT going @@ -492,6 +504,7 @@ final class MapGestureDetector { // arround user provided focal point transform.zoomBy(Math.log(detector.getScaleFactor()) / Math.log(2), focalPoint.x, focalPoint.y); } else if (quickZoom) { + cameraChangeDispatcher.onCameraMove(); // clamp scale factors we feed to core #7514 float scaleFactor = MathUtils.clamp(detector.getScaleFactor(), MapboxConstants.MINIMUM_SCALE_FACTOR_CLAMP, @@ -553,7 +566,7 @@ final class MapGestureDetector { // If rotate is large enough ignore a tap // Also is zoom already started, don't rotate totalAngle += detector.getRotationDegreesDelta(); - if (!zoomStarted && ((totalAngle > 20.0f) || (totalAngle < -20.0f))) { + if (totalAngle > 20.0f || totalAngle < -20.0f) { started = true; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java index 89fbb79504..d788b7772b 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java @@ -215,6 +215,9 @@ final class Transform implements MapView.OnMapChangedListener { if (cameraPosition != null) { int newZoom = (int) Math.round(cameraPosition.zoom + (zoomIn ? 1 : -1)); setZoom(newZoom, focalPoint, MapboxConstants.ANIMATION_DURATION); + } else { + // we are not transforming, notify about being idle + cameraChangeDispatcher.onCameraIdle(); } } @@ -227,8 +230,8 @@ final class Transform implements MapView.OnMapChangedListener { @Override public void onMapChanged(int change) { if (change == MapView.REGION_DID_CHANGE_ANIMATED) { - mapView.removeOnMapChangedListener(this); cameraChangeDispatcher.onCameraIdle(); + mapView.removeOnMapChangedListener(this); } } }); @@ -327,7 +330,7 @@ final class Transform implements MapView.OnMapChangedListener { mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() { @Override public void onMapChanged(int change) { - if (change == MapView.DID_FINISH_RENDERING_MAP_FULLY_RENDERED) { + if (change == MapView.REGION_DID_CHANGE_ANIMATED) { mapView.removeOnMapChangedListener(this); cameraChangeDispatcher.onCameraIdle(); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java index 72868a91d8..8b6b93e03a 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java @@ -348,12 +348,17 @@ public class MyLocationView extends View { } // draw foreground - if (myBearingTrackingMode == MyBearingTracking.NONE || !compassListener.isSensorAvailable()) { + if (myBearingTrackingMode == MyBearingTracking.NONE) { if (foregroundDrawable != null) { foregroundDrawable.draw(canvas); } } else if (foregroundBearingDrawable != null && foregroundBounds != null) { - foregroundBearingDrawable.draw(canvas); + if (myBearingTrackingMode == MyBearingTracking.GPS || compassListener.isSensorAvailable()) { + foregroundBearingDrawable.draw(canvas); + } else { + // We are tracking MyBearingTracking.COMPASS, but sensor is not available. + foregroundDrawable.draw(canvas); + } } } @@ -774,9 +779,9 @@ public class MyLocationView extends View { private final SensorManager sensorManager; private Sensor rotationVectorSensor; - float[] matrix = new float[9]; - float[] orientation = new float[3]; - + private float[] matrix = new float[9]; + private float[] orientation = new float[3]; + private boolean reportMissingSensor = true; // Compass data private long compassUpdateNextTimestamp = 0; @@ -794,7 +799,8 @@ public class MyLocationView extends View { } public boolean isSensorAvailable() { - if (rotationVectorSensor == null) { + if (rotationVectorSensor == null && reportMissingSensor) { + reportMissingSensor = false; Timber.e("Sensor.TYPE_ROTATION_VECTOR is missing from this device. Unable to use MyBearingTracking.COMPASS."); } return rotationVectorSensor != null; diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraPositionActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraPositionActivity.java index 60518239c8..cb2f57d860 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraPositionActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraPositionActivity.java @@ -28,6 +28,7 @@ public class CameraPositionActivity extends AppCompatActivity implements OnMapRe private MapView mapView; private MapboxMap mapboxMap; + private FloatingActionButton fab; @Override protected void onCreate(Bundle savedInstanceState) { @@ -40,13 +41,14 @@ public class CameraPositionActivity extends AppCompatActivity implements OnMapRe } @Override - public void onMapReady(@NonNull final MapboxMap mapboxMap) { - this.mapboxMap = mapboxMap; + public void onMapReady(@NonNull final MapboxMap map) { + mapboxMap = map; mapboxMap.setOnCameraIdleListener(new MapboxMap.OnCameraIdleListener() { @Override public void onCameraIdle() { Timber.e("OnCameraIdle"); + fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, android.R.color.holo_green_dark)); } }); @@ -61,6 +63,7 @@ public class CameraPositionActivity extends AppCompatActivity implements OnMapRe @Override public void onCameraMove() { Timber.e("OnCameraMove"); + fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, android.R.color.holo_orange_dark)); } }); @@ -71,12 +74,13 @@ public class CameraPositionActivity extends AppCompatActivity implements OnMapRe @Override public void onCameraMoveStarted(int reason) { // reason ranges from 1 <-> 3 + fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, android.R.color.holo_red_dark)); Timber.e("OnCameraMoveStarted: %s", REASONS[reason - 1]); } }); // add a listener to FAB - FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); + fab = (FloatingActionButton) findViewById(R.id.fab); fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, R.color.primary)); fab.setOnClickListener(new View.OnClickListener() { @Override diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java index 91f3de0837..c4d29bebec 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java @@ -236,8 +236,8 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements @Override protected void onStop() { super.onStop(); - LocationServices.FusedLocationApi.removeLocationUpdates(lostApiClient, this); if (lostApiClient.isConnected()) { + LocationServices.FusedLocationApi.removeLocationUpdates(lostApiClient, this); lostApiClient.unregisterConnectionCallbacks(this); lostApiClient.disconnect(); } -- cgit v1.2.1 From 8abe210964c3815141b98bf5e00eb11468696477 Mon Sep 17 00:00:00 2001 From: Jordan Kiley Date: Thu, 29 Jun 2017 03:33:20 -0700 Subject: [ios] moved changes to darwin (#9387) --- platform/darwin/docs/guides/For Style Authors.md.ejs | 2 ++ platform/ios/docs/guides/For Style Authors.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/platform/darwin/docs/guides/For Style Authors.md.ejs b/platform/darwin/docs/guides/For Style Authors.md.ejs index 2d9ce635b8..26c533632f 100644 --- a/platform/darwin/docs/guides/For Style Authors.md.ejs +++ b/platform/darwin/docs/guides/For Style Authors.md.ejs @@ -121,6 +121,8 @@ for ink economy before printing the map view. <% if (iOS) { -%> For more information about user interface design, consult Apple’s [_iOS Human Interface Guidelines_](https://developer.apple.com/ios/human-interface-guidelines/). +To learn more about designing maps for mobile devices, see [Nathaniel Slaughter's blog post](https://www.mapbox.com/blog/designing-maps-for-mobile-devices/) on +the subject. <% } else { -%> For more information about user interface design, consult Apple’s [_macOS Human Interface Guidelines_](https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/OSXHIGuidelines/). diff --git a/platform/ios/docs/guides/For Style Authors.md b/platform/ios/docs/guides/For Style Authors.md index fee4d70b34..35375ea2a9 100644 --- a/platform/ios/docs/guides/For Style Authors.md +++ b/platform/ios/docs/guides/For Style Authors.md @@ -76,6 +76,8 @@ gestures. For more information about user interface design, consult Apple’s [_iOS Human Interface Guidelines_](https://developer.apple.com/ios/human-interface-guidelines/). +To learn more about designing maps for mobile devices, see [Nathaniel Slaughter's blog post](https://www.mapbox.com/blog/designing-maps-for-mobile-devices/) on +the subject. ## Applying your style -- cgit v1.2.1 From f836425be467ac9830d8f6b4caa98700ce87c19b Mon Sep 17 00:00:00 2001 From: Tobrun Date: Thu, 29 Jun 2017 13:36:59 +0200 Subject: [android] - keep state of initial overlain views margins (#9391) --- .../java/com/mapbox/mapboxsdk/maps/UiSettings.java | 45 ++++++++++++++-------- 1 file changed, 29 insertions(+), 16 deletions(-) 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 5f7b6c571b..285cd18089 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 @@ -37,8 +37,14 @@ public final class UiSettings { private final FocalPointChangeListener focalPointChangeListener; private final Projection projection; private final CompassView compassView; + private final int[] compassMargins = new int[4]; + private final ImageView attributionsView; + private final int[] attributionsMargins = new int[4]; + private final View logoView; + private final int[] logoMargins = new int[4]; + private float pixelRatio; private boolean rotateGesturesEnabled = true; @@ -370,7 +376,7 @@ public final class UiSettings { */ @UiThread public void setCompassMargins(int left, int top, int right, int bottom) { - setWidgetMargins(compassView, left, top, right, bottom); + setWidgetMargins(compassView, compassMargins, left, top, right, bottom); } /** @@ -379,7 +385,7 @@ public final class UiSettings { * @return The left margin in pixels */ public int getCompassMarginLeft() { - return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).leftMargin; + return compassMargins[0]; } /** @@ -388,7 +394,7 @@ public final class UiSettings { * @return The top margin in pixels */ public int getCompassMarginTop() { - return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).topMargin; + return compassMargins[1]; } /** @@ -397,7 +403,7 @@ public final class UiSettings { * @return The right margin in pixels */ public int getCompassMarginRight() { - return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).rightMargin; + return compassMargins[2]; } /** @@ -406,7 +412,7 @@ public final class UiSettings { * @return The bottom margin in pixels */ public int getCompassMarginBottom() { - return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).bottomMargin; + return compassMargins[3]; } /** @@ -480,7 +486,7 @@ public final class UiSettings { * @param bottom The bottom margin in pixels. */ public void setLogoMargins(int left, int top, int right, int bottom) { - setWidgetMargins(logoView, left, top, right, bottom); + setWidgetMargins(logoView, logoMargins, left, top, right, bottom); } /** @@ -489,7 +495,7 @@ public final class UiSettings { * @return The left margin in pixels */ public int getLogoMarginLeft() { - return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).leftMargin; + return logoMargins[0]; } /** @@ -498,7 +504,7 @@ public final class UiSettings { * @return The top margin in pixels */ public int getLogoMarginTop() { - return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).topMargin; + return logoMargins[1]; } /** @@ -507,7 +513,7 @@ public final class UiSettings { * @return The right margin in pixels */ public int getLogoMarginRight() { - return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).rightMargin; + return logoMargins[2]; } /** @@ -516,7 +522,7 @@ public final class UiSettings { * @return The bottom margin in pixels */ public int getLogoMarginBottom() { - return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).bottomMargin; + return logoMargins[3]; } /** @@ -571,7 +577,7 @@ public final class UiSettings { * @param bottom The bottom margin in pixels. */ public void setAttributionMargins(int left, int top, int right, int bottom) { - setWidgetMargins(attributionsView, left, top, right, bottom); + setWidgetMargins(attributionsView, attributionsMargins, left, top, right, bottom); } /** @@ -598,7 +604,7 @@ public final class UiSettings { * @return The left margin in pixels */ public int getAttributionMarginLeft() { - return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).leftMargin; + return attributionsMargins[0]; } /** @@ -607,7 +613,7 @@ public final class UiSettings { * @return The top margin in pixels */ public int getAttributionMarginTop() { - return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).topMargin; + return attributionsMargins[1]; } /** @@ -616,7 +622,7 @@ public final class UiSettings { * @return The right margin in pixels */ public int getAttributionMarginRight() { - return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).rightMargin; + return attributionsMargins[2]; } /** @@ -625,7 +631,7 @@ public final class UiSettings { * @return The bottom margin in pixels */ public int getAttributionMarginBottom() { - return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).bottomMargin; + return attributionsMargins[3]; } /** @@ -929,7 +935,14 @@ public final class UiSettings { view.setLayoutParams(layoutParams); } - private void setWidgetMargins(@NonNull final View view, int left, int top, int right, int bottom) { + private void setWidgetMargins(@NonNull final View view, int[] initMargins, int left, int top, int right, int bottom) { + // keep state of initially set margins + initMargins[0] = left; + initMargins[1] = top; + initMargins[2] = right; + initMargins[3] = bottom; + + // convert inital margins with padding int[] contentPadding = projection.getContentPadding(); FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) view.getLayoutParams(); left += contentPadding[0]; -- cgit v1.2.1 From ae7dc8ce48d7923a41abb79b4bd0b895e74196fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Wed, 28 Jun 2017 22:28:29 -0700 Subject: [macos] Reorganized changelog --- platform/macos/CHANGELOG.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index db6d66355a..ace533e01f 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -2,6 +2,8 @@ ## 0.5.0 +This version of the Mapbox macOS SDK corresponds to version 3.6.0 of the Mapbox iOS SDK. + ### Packaging * Xcode 8.0 or higher is now recommended for using this SDK. ([#8775](https://github.com/mapbox/mapbox-gl-native/pull/8775)) @@ -23,19 +25,25 @@ * Letter spacing is now disabled in Arabic text so that ligatures are drawn correctly. ([#9062](https://github.com/mapbox/mapbox-gl-native/pull/9062)) * Improved the performance of styles using source and composite style functions. ([#9185](https://github.com/mapbox/mapbox-gl-native/pull/9185), [#9257](https://github.com/mapbox/mapbox-gl-native/pull/9257)) +### Annotations + +* The default marker image has been made slightly larger and now matches the version in the Mapbox iOS SDK. ([#9370](https://github.com/mapbox/mapbox-gl-native/pull/9370)) +* The `MGLPolyline.coordinate` and `MGLPolygon.coordinate` properties now return the midpoint and centroid, respectively, instead of the first coordinate. ([#8713](https://github.com/mapbox/mapbox-gl-native/pull/8713)) + +### User interaction + +* Fixed an issue causing the map to go blank during a flight animation that travels a very short distance. ([#9199](https://github.com/mapbox/mapbox-gl-native/pull/9199)) +* The Improve This Map button in the attribution action sheet now leads to a feedback tool that matches MGLMapView’s rotation and pitch. `-[MGLAttributionInfo feedbackURLAtCenterCoordinate:zoomLevel:]` no longer respects the feedback URL specified in TileJSON. ([#9078](https://github.com/mapbox/mapbox-gl-native/pull/9078)) + ### Other changes * Fixed a crash when calling `MGLMultiPolygon.coordinate` [#8713](https://github.com/mapbox/mapbox-gl-native/pull/8713) * Fixed an issue causing attribution button text to appear blue instead of black. ([#8701](https://github.com/mapbox/mapbox-gl-native/pull/8701)) * Fixed a crash or console spew when MGLMapView is initialized with a frame smaller than 64 points wide by 64 points tall. ([#8562](https://github.com/mapbox/mapbox-gl-native/pull/8562)) -* Fixed an issue causing the map to go blank during a flight animation that travels a very short distance. ([#9199](https://github.com/mapbox/mapbox-gl-native/pull/9199)) -* The Improve This Map button in the attribution action sheet now leads to a feedback tool that matches MGLMapView’s rotation and pitch. `-[MGLAttributionInfo feedbackURLAtCenterCoordinate:zoomLevel:]` no longer respects the feedback URL specified in TileJSON. ([#9078](https://github.com/mapbox/mapbox-gl-native/pull/9078)) * The error passed into `-[MGLMapViewDelegate mapViewDidFailLoadingMap:withError:]` now includes a more specific description and failure reason. ([#8418](https://github.com/mapbox/mapbox-gl-native/pull/8418)) -* The `MGLPolyline.coordinate` and `MGLPolygon.coordinate` properties now return the midpoint and centroid, respectively, instead of the first coordinate. ([#8713](https://github.com/mapbox/mapbox-gl-native/pull/8713)) * Improved CPU and battery performance while animating a tilted map’s camera in an area with many labels. ([#9031](https://github.com/mapbox/mapbox-gl-native/pull/9031)) * Fixed an issue rendering polylines that contain duplicate vertices. ([#8808](https://github.com/mapbox/mapbox-gl-native/pull/8808)) * Added struct boxing to `MGLCoordinateSpan`, `MGLCoordinateBounds`, `MGLOfflinePackProgress`, and `MGLTransition`. ([#9343](https://github.com/mapbox/mapbox-gl-native/pull/9343)) -* The default marker image has been made slightly larger and now matches the version in the Mapbox iOS SDK. ([#9370](https://github.com/mapbox/mapbox-gl-native/pull/9370)) ## 0.4.1 - April 8, 2017 -- cgit v1.2.1 From 92157762cf501c9b96de2d1c6d384cb8633c554b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Wed, 28 Jun 2017 22:47:30 -0700 Subject: [macos] Fixed cursor shifting after drag gesture When redisplaying the mouse cursor after a modified drag gesture, incorporate the conversion from view coordinates to window coordinates. Previously, this code performed the conversion but threw away the results. Fixes #8670. --- platform/macos/CHANGELOG.md | 1 + platform/macos/src/MGLMapView.mm | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index ace533e01f..f69f7e1b5d 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -33,6 +33,7 @@ This version of the Mapbox macOS SDK corresponds to version 3.6.0 of the Mapbox ### User interaction * Fixed an issue causing the map to go blank during a flight animation that travels a very short distance. ([#9199](https://github.com/mapbox/mapbox-gl-native/pull/9199)) +* Fixed an issue causing the mouse cursor to jump after Shift- or Option-dragging the map. ([#9390](https://github.com/mapbox/mapbox-gl-native/pull/9390)) * The Improve This Map button in the attribution action sheet now leads to a feedback tool that matches MGLMapView’s rotation and pitch. `-[MGLAttributionInfo feedbackURLAtCenterCoordinate:zoomLevel:]` no longer respects the feedback URL specified in TileJSON. ([#9078](https://github.com/mapbox/mapbox-gl-native/pull/9078)) ### Other changes diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index 3e91a6c5a5..1908a46cf9 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -1369,7 +1369,7 @@ public: // Move the cursor back to the start point and show it again, creating // the illusion that it has stayed in place during the entire gesture. CGPoint cursorPoint = [self convertPoint:startPoint toView:nil]; - cursorPoint = [self.window convertRectToScreen:{ startPoint, NSZeroSize }].origin; + cursorPoint = [self.window convertRectToScreen:{ cursorPoint, NSZeroSize }].origin; cursorPoint.y = self.window.screen.frame.size.height - cursorPoint.y; CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cursorPoint); CGDisplayShowCursor(kCGDirectMainDisplay); -- cgit v1.2.1 From b5fed1172d77bac0ba122c73a9d30739a51e5028 Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Thu, 29 Jun 2017 11:29:48 -0700 Subject: [core] Bind only active attributes in order to avoid exceeding attribute limits (#9373) Introducing two new attributes to enable property functions for line-width (#9250) pushed the attribute count over GL_MAX_VERTEX_ATTRIBS on some devices. Now we selectively bind only attributes that are used, making it unlikely to surpass GL_MAX_VERTEX_ATTRIBS. --- src/mbgl/gl/attribute.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/mbgl/gl/attribute.hpp | 12 +++++++++++- src/mbgl/gl/program.hpp | 12 +++++++----- 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/src/mbgl/gl/attribute.cpp b/src/mbgl/gl/attribute.cpp index e05ca75866..4e6f78e689 100644 --- a/src/mbgl/gl/attribute.cpp +++ b/src/mbgl/gl/attribute.cpp @@ -2,14 +2,55 @@ #include #include +#include + namespace mbgl { namespace gl { AttributeLocation bindAttributeLocation(ProgramID id, AttributeLocation location, const char* name) { + assert(location < 8); MBGL_CHECK_ERROR(glBindAttribLocation(id, location, name)); return location; } +int32_t getActiveAttributeCount(ProgramID id) { + GLint numAttributes; + MBGL_CHECK_ERROR(glGetProgramiv(id, GL_ACTIVE_ATTRIBUTES, &numAttributes)); + return numAttributes; +} + +int32_t getMaxAttributeNameLength(ProgramID id) { + GLint nameLength; + MBGL_CHECK_ERROR(glGetProgramiv(id, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &nameLength)); + return nameLength; +} + +std::string getAttributeName(ProgramID id, int32_t maxLength, AttributeLocation location) { + std::string attributeName; + attributeName.resize(maxLength); + GLsizei actualLength; + GLint size; + GLenum type; + MBGL_CHECK_ERROR(glGetActiveAttrib(id, static_cast(location), + static_cast(maxLength), &actualLength, &size, &type, + const_cast(attributeName.data()))); + attributeName.resize(actualLength); + return attributeName; +} + +std::set getActiveAttributes(ProgramID id) { + std::set activeAttributes; + + GLint attributeCount = getActiveAttributeCount(id); + GLint maxAttributeLength = getMaxAttributeNameLength(id); + + for (int32_t i = 0; i < attributeCount; i++) { + activeAttributes.emplace(getAttributeName(id, maxAttributeLength, i)); + } + + return activeAttributes; +} + void DisabledAttribute::bind(Context&, AttributeLocation location, std::size_t) const { MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); } @@ -25,6 +66,11 @@ template <> DataType DataTypeOf = DataType::Float; template void AttributeBinding::bind(Context& context, AttributeLocation location, std::size_t vertexOffset) const { + // FillProgram will attempt to bind at location -1 because it includes + // a fill-outline-color paint property but does not use it or have an + // a_outline_color shader attribute - in this case, we have nothing to bind. + if (location == -1) return; + context.vertexBuffer = vertexBuffer; MBGL_CHECK_ERROR(glEnableVertexAttribArray(location)); MBGL_CHECK_ERROR(glVertexAttribPointer( diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp index 48222146fa..f018a1d261 100644 --- a/src/mbgl/gl/attribute.hpp +++ b/src/mbgl/gl/attribute.hpp @@ -8,6 +8,7 @@ #include #include +#include #include namespace mbgl { @@ -223,6 +224,7 @@ const std::size_t Vertex::attributeOffsets[5] = { } // namespace detail AttributeLocation bindAttributeLocation(ProgramID, AttributeLocation, const char * name); +std::set getActiveAttributes(ProgramID); template class Attributes { @@ -242,7 +244,15 @@ public: static constexpr std::size_t Index = TypeIndex::value; static Locations bindLocations(const ProgramID& id) { - return Locations { bindAttributeLocation(id, Index, As::name())... }; + std::set activeAttributes = getActiveAttributes(id); + + AttributeLocation location = -1; + auto bindAndIncrement = [&](const char* name) { + location++; + return bindAttributeLocation(id, location, name); + }; + return Locations{ (activeAttributes.count(As::name()) ? bindAndIncrement(As::name()) + : -1)... }; } template diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp index 47ad39de7c..583d53e4ec 100644 --- a/src/mbgl/gl/program.hpp +++ b/src/mbgl/gl/program.hpp @@ -33,15 +33,17 @@ public: : program( context.createProgram(context.createShader(ShaderType::Vertex, vertexSource), context.createShader(ShaderType::Fragment, fragmentSource))), - attributeLocations(Attributes::bindLocations(program)), - uniformsState((context.linkProgram(program), Uniforms::bindLocations(program))) { + uniformsState((context.linkProgram(program), Uniforms::bindLocations(program))), + attributeLocations(Attributes::bindLocations(program)) { + // Re-link program after manually binding only active attributes in Attributes::bindLocations + context.linkProgram(program); } template Program(Context& context, const BinaryProgram& binaryProgram) : program(context.createProgram(binaryProgram.format(), binaryProgram.code())), - attributeLocations(Attributes::loadNamedLocations(binaryProgram)), - uniformsState(Uniforms::loadNamedLocations(binaryProgram)) { + uniformsState(Uniforms::loadNamedLocations(binaryProgram)), + attributeLocations(Attributes::loadNamedLocations(binaryProgram)) { } static Program createProgram(gl::Context& context, @@ -144,8 +146,8 @@ public: private: UniqueProgram program; - typename Attributes::Locations attributeLocations; typename Uniforms::State uniformsState; + typename Attributes::Locations attributeLocations; }; } // namespace gl -- cgit v1.2.1 From dafba03bbc679dec890b54bff733b7569fd51ad4 Mon Sep 17 00:00:00 2001 From: Fabian Guerra Date: Thu, 29 Jun 2017 14:21:24 -0400 Subject: ios] Update pods spec for iOS v3.6.0 --- platform/ios/Mapbox-iOS-SDK-symbols.podspec | 2 +- platform/ios/Mapbox-iOS-SDK.podspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/ios/Mapbox-iOS-SDK-symbols.podspec b/platform/ios/Mapbox-iOS-SDK-symbols.podspec index 382acb13a4..d2a686f1fb 100644 --- a/platform/ios/Mapbox-iOS-SDK-symbols.podspec +++ b/platform/ios/Mapbox-iOS-SDK-symbols.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |m| - version = '3.6.0-rc.1' + version = '3.6.0' m.name = 'Mapbox-iOS-SDK-symbols' m.version = "#{version}-symbols" diff --git a/platform/ios/Mapbox-iOS-SDK.podspec b/platform/ios/Mapbox-iOS-SDK.podspec index 0d25ca3be4..55e8791b4c 100644 --- a/platform/ios/Mapbox-iOS-SDK.podspec +++ b/platform/ios/Mapbox-iOS-SDK.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |m| - version = '3.6.0-rc.1' + version = '3.6.0' m.name = 'Mapbox-iOS-SDK' m.version = version -- cgit v1.2.1 From 47ca78b705628291f3bfc4f2e01fca2275f2a429 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Thu, 29 Jun 2017 17:45:41 -0700 Subject: [macos] Updated screenshot The new screenshot features 3D extruded buildings, vertical CJK, and right-to-left Arabic, all via runtime styling. --- platform/macos/docs/img/screenshot.jpg | Bin 445665 -> 351938 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/platform/macos/docs/img/screenshot.jpg b/platform/macos/docs/img/screenshot.jpg index 5341a3d6f0..a8c64a69fe 100644 Binary files a/platform/macos/docs/img/screenshot.jpg and b/platform/macos/docs/img/screenshot.jpg differ -- cgit v1.2.1 From 3821ce27de9da37fd8ea04e292ca9fdfea2d8ab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Thu, 29 Jun 2017 17:46:40 -0700 Subject: macos-v0.5.0 --- platform/macos/Mapbox-macOS-SDK-symbols.podspec | 2 +- platform/macos/Mapbox-macOS-SDK.podspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/macos/Mapbox-macOS-SDK-symbols.podspec b/platform/macos/Mapbox-macOS-SDK-symbols.podspec index c621a7312b..5b70c52681 100644 --- a/platform/macos/Mapbox-macOS-SDK-symbols.podspec +++ b/platform/macos/Mapbox-macOS-SDK-symbols.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |m| - version = '0.4.1' + version = '0.5.0' m.name = 'Mapbox-macOS-SDK-symbols' m.version = "#{version}-symbols" diff --git a/platform/macos/Mapbox-macOS-SDK.podspec b/platform/macos/Mapbox-macOS-SDK.podspec index 2417fb11ec..0b26b13beb 100644 --- a/platform/macos/Mapbox-macOS-SDK.podspec +++ b/platform/macos/Mapbox-macOS-SDK.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |m| - version = '0.4.1' + version = '0.5.0' m.name = 'Mapbox-macOS-SDK' m.version = version -- cgit v1.2.1 From 95735c06f6c394bde67532913fd7b51b2938cbc1 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 30 Jun 2017 11:21:39 +0200 Subject: Downgrade location provider dependency (#9394) * [android] - downgrade LOST to Mapbox SDK 5.0.2 version. * bump LOST back to Mapbox Android SDK version 4.x --- platform/android/MapboxGLAndroidSDK/build.gradle | 4 ++- .../mapbox/mapboxsdk/location/LocationSource.java | 33 ++++++---------------- .../userlocation/MyLocationDrawableActivity.java | 27 ++++++------------ .../MyLocationTrackingModeActivity.java | 22 ++++----------- platform/android/dependencies.gradle | 4 +-- 5 files changed, 27 insertions(+), 63 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/build.gradle b/platform/android/MapboxGLAndroidSDK/build.gradle index 5e19e94f5d..018294d462 100644 --- a/platform/android/MapboxGLAndroidSDK/build.gradle +++ b/platform/android/MapboxGLAndroidSDK/build.gradle @@ -6,7 +6,9 @@ dependencies { compile rootProject.ext.dep.supportDesign compile rootProject.ext.dep.timber compile rootProject.ext.dep.okhttp3 - compile rootProject.ext.dep.lost + compile(rootProject.ext.dep.lost) { + exclude group: 'com.google.guava' + } // Mapbox Android Services (GeoJSON support) compile(rootProject.ext.dep.mapboxJavaGeoJSON) { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java index 12e3300429..6652142be3 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java @@ -28,7 +28,7 @@ import com.mapzen.android.lost.api.LostApiClient; * in the history stack. *

      */ -public class LocationSource extends LocationEngine implements LostApiClient.ConnectionCallbacks, LocationListener { +public class LocationSource extends LocationEngine implements LocationListener { private Context context; private LostApiClient lostApiClient; @@ -41,9 +41,7 @@ public class LocationSource extends LocationEngine implements LostApiClient.Conn public LocationSource(Context context) { super(); this.context = context.getApplicationContext(); - lostApiClient = new LostApiClient.Builder(this.context) - .addConnectionCallbacks(this) - .build(); + lostApiClient = new LostApiClient.Builder(this.context).build(); } /** @@ -55,6 +53,9 @@ public class LocationSource extends LocationEngine implements LostApiClient.Conn if (!lostApiClient.isConnected()) { lostApiClient.connect(); } + for (LocationEngineListener listener : locationListeners) { + listener.onConnected(); + } } /** @@ -80,23 +81,6 @@ public class LocationSource extends LocationEngine implements LostApiClient.Conn return lostApiClient.isConnected(); } - /** - * Invoked when the location provider has connected. - */ - @Override - public void onConnected() { - for (LocationEngineListener listener : locationListeners) { - listener.onConnected(); - } - } - - /** - * Invoked when the location provider connection has been suspended. - */ - @Override - public void onConnectionSuspended() { - } - /** * Returns the Last known location is the location provider is connected and location permissions are granted. * @@ -107,9 +91,8 @@ public class LocationSource extends LocationEngine implements LostApiClient.Conn public Location getLastLocation() { if (lostApiClient.isConnected() && PermissionsManager.areLocationPermissionsGranted(context)) { //noinspection MissingPermission - return LocationServices.FusedLocationApi.getLastLocation(lostApiClient); + return LocationServices.FusedLocationApi.getLastLocation(); } - return null; } @@ -137,7 +120,7 @@ public class LocationSource extends LocationEngine implements LostApiClient.Conn if (lostApiClient.isConnected() && PermissionsManager.areLocationPermissionsGranted(context)) { //noinspection MissingPermission - LocationServices.FusedLocationApi.requestLocationUpdates(lostApiClient, request, this); + LocationServices.FusedLocationApi.requestLocationUpdates(request, this); } } @@ -147,7 +130,7 @@ public class LocationSource extends LocationEngine implements LostApiClient.Conn @Override public void removeLocationUpdates() { if (lostApiClient.isConnected()) { - LocationServices.FusedLocationApi.removeLocationUpdates(lostApiClient, this); + LocationServices.FusedLocationApi.removeLocationUpdates(this); } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java index 8657434127..69e6d64325 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java @@ -16,7 +16,6 @@ import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.MapboxMapOptions; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; import com.mapbox.mapboxsdk.testapp.R; - import com.mapzen.android.lost.api.LocationListener; import com.mapzen.android.lost.api.LocationRequest; import com.mapzen.android.lost.api.LocationServices; @@ -25,8 +24,7 @@ import com.mapzen.android.lost.api.LostApiClient; /** * Test activity showcasing how to change the MyLocationView drawable. */ -public class MyLocationDrawableActivity extends BaseLocationActivity implements LostApiClient.ConnectionCallbacks, - LocationListener { +public class MyLocationDrawableActivity extends BaseLocationActivity implements LocationListener { private MapView mapView; private MapboxMap mapboxMap; @@ -69,29 +67,21 @@ public class MyLocationDrawableActivity extends BaseLocationActivity implements protected void enableLocation(boolean enabled) { mapboxMap.setMyLocationEnabled(enabled); if (lostApiClient == null) { - lostApiClient = new LostApiClient.Builder(this).addConnectionCallbacks(this).build(); + lostApiClient = new LostApiClient.Builder(this).build(); lostApiClient.connect(); + LocationRequest request = LocationRequest.create() + .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) + .setInterval(5000) + .setSmallestDisplacement(10); + LocationServices.FusedLocationApi.requestLocationUpdates(request, this); } } - @Override - public void onConnected() { - LocationRequest request = LocationRequest.create() - .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) - .setInterval(5000) - .setSmallestDisplacement(10); - LocationServices.FusedLocationApi.requestLocationUpdates(lostApiClient, request, this); - } - @Override public void onLocationChanged(Location location) { mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location), 14)); } - @Override - public void onConnectionSuspended() { - } - @Override protected void onStart() { super.onStart(); @@ -115,10 +105,9 @@ public class MyLocationDrawableActivity extends BaseLocationActivity implements super.onStop(); mapView.onStop(); if (lostApiClient.isConnected()) { - LocationServices.FusedLocationApi.removeLocationUpdates(lostApiClient, this); + LocationServices.FusedLocationApi.removeLocationUpdates(this); lostApiClient.disconnect(); } - lostApiClient.unregisterConnectionCallbacks(this); } @Override diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java index c4d29bebec..786aeb8733 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java @@ -38,8 +38,8 @@ import timber.log.Timber; * using gesture configurations. *

      */ -public class MyLocationTrackingModeActivity extends AppCompatActivity implements - AdapterView.OnItemSelectedListener, OnMapReadyCallback, LostApiClient.ConnectionCallbacks, LocationListener { +public class MyLocationTrackingModeActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener, + OnMapReadyCallback, LocationListener { // Testing for user defined LostApiClient private LostApiClient lostApiClient; @@ -75,27 +75,18 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements @Override public void onMapReady(MapboxMap mapboxMap) { MyLocationTrackingModeActivity.this.mapboxMap = mapboxMap; - lostApiClient = new LostApiClient.Builder(this).addConnectionCallbacks(this).build(); + lostApiClient = new LostApiClient.Builder(this).build(); lostApiClient.connect(); - } - - @Override - public void onConnected() { LocationRequest request = LocationRequest.create() .setPriority(LocationRequest.PRIORITY_LOW_POWER) .setInterval(5000) .setSmallestDisplacement(10); - Location location = LocationServices.FusedLocationApi.getLastLocation(lostApiClient); + Location location = LocationServices.FusedLocationApi.getLastLocation(); if (location != null) { setInitialLocation(location, 15); } - LocationServices.FusedLocationApi.requestLocationUpdates(lostApiClient, request, this); - } - - @Override - public void onConnectionSuspended() { - + LocationServices.FusedLocationApi.requestLocationUpdates(request, this); } @Override @@ -237,8 +228,7 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements protected void onStop() { super.onStop(); if (lostApiClient.isConnected()) { - LocationServices.FusedLocationApi.removeLocationUpdates(lostApiClient, this); - lostApiClient.unregisterConnectionCallbacks(this); + LocationServices.FusedLocationApi.removeLocationUpdates(this); lostApiClient.disconnect(); } mapView.onStop(); diff --git a/platform/android/dependencies.gradle b/platform/android/dependencies.gradle index 2172d6a536..058992cc85 100644 --- a/platform/android/dependencies.gradle +++ b/platform/android/dependencies.gradle @@ -21,8 +21,8 @@ ext { mapboxAndroidTelemetry : "com.mapbox.mapboxsdk:mapbox-android-telemetry:${mapboxServicesVersion}@aar", // mapzen lost - lost : 'com.mapzen.android:lost:3.0.1', - + lost : 'com.mapzen.android:lost:1.1.1', + // unit test junit : 'junit:junit:4.12', mockito : 'org.mockito:mockito-core:2.2.27', -- cgit v1.2.1 From b9a4addac6f9c95e5b02b216ea19d624bf4140b6 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 30 Jun 2017 16:47:31 +0200 Subject: [android] - bump Mapbox Android Services to latest for 5.1.0 final release (#9402) --- platform/android/dependencies.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/android/dependencies.gradle b/platform/android/dependencies.gradle index 058992cc85..500b99def6 100644 --- a/platform/android/dependencies.gradle +++ b/platform/android/dependencies.gradle @@ -7,7 +7,7 @@ ext { versionCode = 11 versionName = "5.0.0" - mapboxServicesVersion = "2.1.2" + mapboxServicesVersion = "2.1.3" supportLibVersion = "25.3.1" wearableVersion = '2.0.0' espressoVersion = '2.2.2' -- cgit v1.2.1 From d2d8a575be2d4f28894c0c1f845cbb464869d97c Mon Sep 17 00:00:00 2001 From: Tobrun Date: Sat, 1 Jul 2017 17:38:44 +0200 Subject: [android] - update changelog for 5.1.0 release (#9405) --- platform/android/CHANGELOG.md | 7 ++++++- platform/android/MapboxGLAndroidSDK/gradle.properties | 2 +- .../fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md index 1e37717d8b..6d4bb46357 100644 --- a/platform/android/CHANGELOG.md +++ b/platform/android/CHANGELOG.md @@ -2,7 +2,12 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to do so please see the [`Contributing Guide`](https://github.com/mapbox/mapbox-gl-native/blob/master/CONTRIBUTING.md) first to get started. -## 5.1.0 - TBA +## 5.1.0 - June 30, 2017 + +* Update to MAS 2.1.3 [#9402](https://github.com/mapbox/mapbox-gl-native/pull/9402) +* Downgrade LOST to v1.1.1 [#9394](https://github.com/mapbox/mapbox-gl-native/pull/9394) +* OnCameraIdle hook into quickzoom gesture [#9339](https://github.com/mapbox/mapbox-gl-native/pull/9339) +* LatLngBounds conversion regression, add test [#9324](https://github.com/mapbox/mapbox-gl-native/pull/9324) ## 5.1.0-beta.5 - June 21, 2017 diff --git a/platform/android/MapboxGLAndroidSDK/gradle.properties b/platform/android/MapboxGLAndroidSDK/gradle.properties index 9f555da5f8..078fdbc801 100644 --- a/platform/android/MapboxGLAndroidSDK/gradle.properties +++ b/platform/android/MapboxGLAndroidSDK/gradle.properties @@ -1,5 +1,5 @@ GROUP=com.mapbox.mapboxsdk -VERSION_NAME=5.1.0-SNAPSHOT +VERSION_NAME=5.2.0-SNAPSHOT POM_DESCRIPTION=Mapbox GL Android SDK POM_URL=https://github.com/mapbox/mapbox-gl-native diff --git a/platform/android/MapboxGLAndroidSDK/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties b/platform/android/MapboxGLAndroidSDK/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties index bc0350fe1f..029d25e046 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties +++ b/platform/android/MapboxGLAndroidSDK/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties @@ -1,3 +1,3 @@ fabric-identifier=com.mapbox.mapboxsdk.mapbox-android-sdk -fabric-version=5.0.1 +fabric-version=5.1.0 fabric-build-type=binary -- cgit v1.2.1 From 9a0c5b4dfa7fdb6f980d03bbfb93064e9f2ec81d Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Thu, 29 Jun 2017 22:17:11 +0300 Subject: [test] Use test::checkImage in API.RepeatedRender --- test/api/repeated_render.test.cpp | 14 +++++--------- test/fixtures/api/repeated_render/expected.png | Bin 0 -> 31046 bytes 2 files changed, 5 insertions(+), 9 deletions(-) create mode 100644 test/fixtures/api/repeated_render/expected.png diff --git a/test/api/repeated_render.test.cpp b/test/api/repeated_render.test.cpp index b6565dbf23..3da65939cc 100644 --- a/test/api/repeated_render.test.cpp +++ b/test/api/repeated_render.test.cpp @@ -25,7 +25,7 @@ TEST(API, RepeatedRender) { HeadlessBackend backend { test::sharedDisplay() }; BackendScope scope { backend }; - OffscreenView view { backend.getContext(), { 256, 512 } }; + OffscreenView view { backend.getContext(), { 512, 512 } }; DefaultFileSource fileSource(":memory:", "test/fixtures/api/assets"); ThreadPool threadPool(4); @@ -44,11 +44,9 @@ TEST(API, RepeatedRender) { loop.runOnce(); } - ASSERT_EQ(256u, result.size.width); + ASSERT_EQ(512u, result.size.width); ASSERT_EQ(512u, result.size.height); -#if !TEST_READ_ONLY - util::write_file("test/fixtures/api/1.png", encodePNG(result)); -#endif + test::checkImage("test/fixtures/api/repeated_render", result, 0.0003, 0.1); } { @@ -62,11 +60,9 @@ TEST(API, RepeatedRender) { loop.runOnce(); } - ASSERT_EQ(256u, result.size.width); + ASSERT_EQ(512u, result.size.width); ASSERT_EQ(512u, result.size.height); -#if !TEST_READ_ONLY - util::write_file("test/fixtures/api/2.png", encodePNG(result)); -#endif + test::checkImage("test/fixtures/api/repeated_render", result, 0.0003, 0.1); } auto observer = Log::removeObserver(); diff --git a/test/fixtures/api/repeated_render/expected.png b/test/fixtures/api/repeated_render/expected.png new file mode 100644 index 0000000000..927f6d4c82 Binary files /dev/null and b/test/fixtures/api/repeated_render/expected.png differ -- cgit v1.2.1 From a744e35f44213584574b2e5377076d4b6d99ac7b Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Fri, 30 Jun 2017 14:56:51 +0300 Subject: [test] Added API.ZoomHistory --- test/api/repeated_render.test.cpp | 62 ++++++++++++++++++++++++++++++++++++++ test/fixtures/api/z0/expected.png | Bin 0 -> 5042 bytes test/fixtures/api/z1/expected.png | Bin 0 -> 5648 bytes 3 files changed, 62 insertions(+) create mode 100644 test/fixtures/api/z0/expected.png create mode 100644 test/fixtures/api/z1/expected.png diff --git a/test/api/repeated_render.test.cpp b/test/api/repeated_render.test.cpp index 3da65939cc..dd9085efd7 100644 --- a/test/api/repeated_render.test.cpp +++ b/test/api/repeated_render.test.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include @@ -70,3 +72,63 @@ TEST(API, RepeatedRender) { auto unchecked = flo->unchecked(); EXPECT_TRUE(unchecked.empty()) << unchecked; } + +TEST(API, ZoomHistory) { + util::RunLoop loop; + + const auto style = util::read_file("test/fixtures/api/empty.json"); + + HeadlessBackend backend { test::sharedDisplay() }; + BackendScope scope { backend }; + OffscreenView view { backend.getContext(), { 512, 512 } }; + DefaultFileSource fileSource(":memory:", "."); + ThreadPool threadPool(4); + + Log::setObserver(std::make_unique()); + + Map map(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still); + map.getStyle().loadJSON(style); + + auto geojson = mapbox::geojson::parse(R"t({ "type": "FeatureCollection", "features": [{ "type": "Feature", "properties": {}, "geometry": { "type": "LineString", "coordinates": [ [ -150, -75 ], [ 150, 75 ] ] } } ] })t"); + auto source = std::make_unique("testSource"); + source->setGeoJSON(std::move(geojson)); + map.getStyle().addSource(std::move(source)); + + auto layer = std::make_unique("testLayer", "testSource"); + layer->setLineDasharray({ { 1.0f, 2.0f } }); + layer->setLineWidth({ 16.0f }); + map.getStyle().addLayer(std::move(layer)); + + { + PremultipliedImage result; + map.renderStill(view, [&](std::exception_ptr) { + result = view.readStillImage(); + }); + + while (!result.valid()) { + loop.runOnce(); + } + + test::checkImage("test/fixtures/api/z0", result, 0.0002, 0.1); + } + + { + map.setZoom(1.0); + + PremultipliedImage result; + map.renderStill(view, [&](std::exception_ptr) { + result = view.readStillImage(); + }); + + while (!result.valid()) { + loop.runOnce(); + } + + test::checkImage("test/fixtures/api/z1", result, 0.0002, 0.1); + } + + auto observer = Log::removeObserver(); + auto flo = dynamic_cast(observer.get()); + auto unchecked = flo->unchecked(); + EXPECT_TRUE(unchecked.empty()) << unchecked; +} diff --git a/test/fixtures/api/z0/expected.png b/test/fixtures/api/z0/expected.png new file mode 100644 index 0000000000..0867a8cbf6 Binary files /dev/null and b/test/fixtures/api/z0/expected.png differ diff --git a/test/fixtures/api/z1/expected.png b/test/fixtures/api/z1/expected.png new file mode 100644 index 0000000000..897dc196cc Binary files /dev/null and b/test/fixtures/api/z1/expected.png differ -- cgit v1.2.1 From 60eae41549cec18dfeed5175fe1d6c327060a8de Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Thu, 29 Jun 2017 22:40:50 +0300 Subject: [core] Factor timePoint initialization: take 2 --- src/mbgl/map/map.cpp | 4 +++- src/mbgl/map/zoom_history.hpp | 7 ++++--- src/mbgl/renderer/render_style.cpp | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 4d073802c2..034e43f260 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -207,7 +207,9 @@ void Map::render(View& view) { } void Map::Impl::render(View& view) { - TimePoint timePoint = Clock::now(); + TimePoint timePoint = mode == MapMode::Continuous + ? Clock::now() + : Clock::time_point::max(); transform.updateTransitions(timePoint); diff --git a/src/mbgl/map/zoom_history.hpp b/src/mbgl/map/zoom_history.hpp index 308846b1e3..697e28573c 100644 --- a/src/mbgl/map/zoom_history.hpp +++ b/src/mbgl/map/zoom_history.hpp @@ -13,19 +13,20 @@ struct ZoomHistory { bool first = true; bool update(float z, const TimePoint& now) { + constexpr TimePoint zero = TimePoint(Duration::zero()); if (first) { first = false; lastIntegerZoom = std::floor(z); - lastIntegerZoomTime = TimePoint(Duration::zero()); + lastIntegerZoomTime = zero; lastZoom = z; return true; } else { if (std::floor(lastZoom) < std::floor(z)) { lastIntegerZoom = std::floor(z); - lastIntegerZoomTime = now; + lastIntegerZoomTime = now == Clock::time_point::max() ? zero : now; } else if (std::floor(lastZoom) > std::floor(z)) { lastIntegerZoom = std::floor(z + 1); - lastIntegerZoomTime = now; + lastIntegerZoomTime = now == Clock::time_point::max() ? zero : now; } if (z != lastZoom) { diff --git a/src/mbgl/renderer/render_style.cpp b/src/mbgl/renderer/render_style.cpp index 79b20a9d71..91efb6c737 100644 --- a/src/mbgl/renderer/render_style.cpp +++ b/src/mbgl/renderer/render_style.cpp @@ -86,13 +86,13 @@ void RenderStyle::update(const UpdateParameters& parameters) { const bool zoomChanged = zoomHistory.update(parameters.transformState.getZoom(), parameters.timePoint); const TransitionParameters transitionParameters { - parameters.mode == MapMode::Continuous ? parameters.timePoint : Clock::time_point::max(), + parameters.timePoint, parameters.mode == MapMode::Continuous ? parameters.transitionOptions : TransitionOptions() }; const PropertyEvaluationParameters evaluationParameters { zoomHistory, - parameters.mode == MapMode::Continuous ? parameters.timePoint : Clock::time_point::max(), + parameters.timePoint, parameters.mode == MapMode::Continuous ? util::DEFAULT_TRANSITION_DURATION : Duration::zero() }; -- cgit v1.2.1 From 5921f692e085bde5d4e8000c33dac29c796acbf0 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Wed, 5 Jul 2017 14:01:37 +0300 Subject: [qt] Pass size in QMapboxGLTest's QMapboxGL ctor --- platform/qt/test/qmapboxgl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/qt/test/qmapboxgl.cpp b/platform/qt/test/qmapboxgl.cpp index 453604076e..747f8796fa 100644 --- a/platform/qt/test/qmapboxgl.cpp +++ b/platform/qt/test/qmapboxgl.cpp @@ -15,7 +15,7 @@ class QMapboxGLTest : public QObject, public ::testing::Test { Q_OBJECT public: - QMapboxGLTest() : fbo((assert(widget.context()->isValid()), widget.makeCurrent(), QSize(512, 512))), map(nullptr, settings) { + QMapboxGLTest() : size(512, 512), fbo((assert(widget.context()->isValid()), widget.makeCurrent(), size)), map(nullptr, settings, size) { connect(&map, SIGNAL(mapChanged(QMapboxGL::MapChange)), this, SLOT(onMapChanged(QMapboxGL::MapChange))); connect(&map, SIGNAL(needsRendering()), @@ -38,6 +38,7 @@ public: private: QGLWidget widget; + const QSize size; QGLFramebufferObject fbo; protected: -- cgit v1.2.1 From eb7926d20572c19363568f53c117cf8eb1b373d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Wed, 5 Jul 2017 17:32:23 +0200 Subject: [android] - invible marker views performance fix #9419 (#9420) --- .../main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java index 6d42842b7d..dce6f6b277 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java @@ -198,7 +198,7 @@ public class MarkerViewManager implements MapView.OnMapChangedListener { // ensure view is measured first // #6805 invalidate marker views to ensure convertView width and height // values are properly measured and up to date - if (marker.getWidth() == 0) { + if (marker.getWidth() == 0 && marker.isVisible()) { convertView.getViewTreeObserver().addOnPreDrawListener(markerViewPreDrawObserver); } } -- cgit v1.2.1 From 87081b8391edb3a5e3bd0dede45534f191d1f84a Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 28 Jun 2017 17:29:20 -0700 Subject: [core] Fix iterator invalidation in erase_if vector::erase invalidates iterators. It's not safe for erase_if to cache the end iterator nor increment, then erase. --- src/mbgl/util/std.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mbgl/util/std.hpp b/src/mbgl/util/std.hpp index 974e21329c..1db20e09e5 100644 --- a/src/mbgl/util/std.hpp +++ b/src/mbgl/util/std.hpp @@ -8,10 +8,10 @@ namespace mbgl { namespace util { template -void erase_if(Container &container, ForwardIterator it, const ForwardIterator end, Predicate pred) { - while (it != end) { +void erase_if(Container &container, ForwardIterator it, Predicate pred) { + while (it != container.end()) { if (pred(*it)) { - container.erase(it++); + it = container.erase(it); } else { ++it; } @@ -20,7 +20,7 @@ void erase_if(Container &container, ForwardIterator it, const ForwardIterator en template void erase_if(Container &container, Predicate pred) { - erase_if(container, container.begin(), container.end(), pred); + erase_if(container, container.begin(), pred); } } // namespace util -- cgit v1.2.1 From 9ab04a29655014f1df24e269ce53942c934c8333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Wed, 5 Jul 2017 17:32:23 +0200 Subject: [android] - invible marker views performance fix #9419 (#9420) --- .../main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java index 6d42842b7d..dce6f6b277 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java @@ -198,7 +198,7 @@ public class MarkerViewManager implements MapView.OnMapChangedListener { // ensure view is measured first // #6805 invalidate marker views to ensure convertView width and height // values are properly measured and up to date - if (marker.getWidth() == 0) { + if (marker.getWidth() == 0 && marker.isVisible()) { convertView.getViewTreeObserver().addOnPreDrawListener(markerViewPreDrawObserver); } } -- cgit v1.2.1 From 79d849dc44e977ca8711adb7a397e5e560cbc80a Mon Sep 17 00:00:00 2001 From: Tobrun Date: Wed, 5 Jul 2017 21:15:54 +0200 Subject: [darwin] - re-add swift documentation --- platform/darwin/src/MGLCircleStyleLayer.h | 10 ++++++++++ platform/darwin/src/MGLFillExtrusionStyleLayer.h | 6 ++++++ platform/darwin/src/MGLFillStyleLayer.h | 5 +++++ platform/darwin/src/MGLLineStyleLayer.h | 10 ++++++++++ platform/darwin/src/MGLRasterStyleLayer.h | 3 +++ platform/darwin/src/MGLSymbolStyleLayer.h | 10 ++++++++++ 6 files changed, 44 insertions(+) diff --git a/platform/darwin/src/MGLCircleStyleLayer.h b/platform/darwin/src/MGLCircleStyleLayer.h index 823824b50f..789ff7a258 100644 --- a/platform/darwin/src/MGLCircleStyleLayer.h +++ b/platform/darwin/src/MGLCircleStyleLayer.h @@ -64,6 +64,16 @@ typedef NS_ENUM(NSUInteger, MGLCircleTranslationAnchor) { ### Example ```swift + let layer = MGLCircleStyleLayer(identifier: "circles", source: population) + layer.sourceLayerIdentifier = "population" + layer.circleColor = MGLStyleValue(rawValue: .green) + layer.circleRadius = MGLStyleValue(interpolationMode: .exponential, + cameraStops: [12: MGLStyleValue(rawValue: 2), + 22: MGLStyleValue(rawValue: 180)], + options: [.interpolationBase: 1.75]) + layer.circleOpacity = MGLStyleValue(rawValue: 0.7) + layer.predicate = NSPredicate(format: "%K == %@", "marital-status", "married") + mapView.style?.addLayer(layer) ``` */ MGL_EXPORT diff --git a/platform/darwin/src/MGLFillExtrusionStyleLayer.h b/platform/darwin/src/MGLFillExtrusionStyleLayer.h index 443391756d..c4fb9aa77e 100644 --- a/platform/darwin/src/MGLFillExtrusionStyleLayer.h +++ b/platform/darwin/src/MGLFillExtrusionStyleLayer.h @@ -42,6 +42,12 @@ typedef NS_ENUM(NSUInteger, MGLFillExtrusionTranslationAnchor) { ### Example ```swift + let layer = MGLFillExtrusionStyleLayer(identifier: "buildings", source: buildings) + layer.sourceLayerIdentifier = "building" + layer.fillExtrusionHeight = MGLStyleValue(interpolationMode: .identity, sourceStops: nil, attributeName: "height", options: nil) + layer.fillExtrusionBase = MGLStyleValue(interpolationMode: .identity, sourceStops: nil, attributeName: "min_height", options: nil) + layer.predicate = NSPredicate(format: "extrude == 'true'") + mapView.style?.addLayer(layer) ``` */ MGL_EXPORT diff --git a/platform/darwin/src/MGLFillStyleLayer.h b/platform/darwin/src/MGLFillStyleLayer.h index 8776f17bcb..6e3297bdec 100644 --- a/platform/darwin/src/MGLFillStyleLayer.h +++ b/platform/darwin/src/MGLFillStyleLayer.h @@ -42,6 +42,11 @@ typedef NS_ENUM(NSUInteger, MGLFillTranslationAnchor) { ### Example ```swift + let layer = MGLFillStyleLayer(identifier: "parks", source: parks) + layer.sourceLayerIdentifier = "parks" + layer.fillColor = MGLStyleValue(rawValue: .green) + layer.predicate = NSPredicate(format: "type == %@", "national-park") + mapView.style?.addLayer(layer) ``` */ MGL_EXPORT diff --git a/platform/darwin/src/MGLLineStyleLayer.h b/platform/darwin/src/MGLLineStyleLayer.h index 7c5b66a2c2..4a96b11abf 100644 --- a/platform/darwin/src/MGLLineStyleLayer.h +++ b/platform/darwin/src/MGLLineStyleLayer.h @@ -92,6 +92,16 @@ typedef NS_ENUM(NSUInteger, MGLLineTranslationAnchor) { ### Example ```swift + let layer = MGLLineStyleLayer(identifier: "trails-path", source: trails) + layer.sourceLayerIdentifier = "trails" + layer.lineWidth = MGLStyleValue(interpolationMode: .exponential, + cameraStops: [14: MGLStyleValue(rawValue: 2), + 18: MGLStyleValue(rawValue: 20)], + options: [.interpolationBase: 1.5]) + layer.lineColor = MGLStyleValue(rawValue: .brown) + layer.lineCap = MGLStyleValue(rawValue: NSValue(mglLineCap: .round)) + layer.predicate = NSPredicate(format: "%K == %@", "trail-type", "mountain-biking") + mapView.style?.addLayer(layer) ``` */ MGL_EXPORT diff --git a/platform/darwin/src/MGLRasterStyleLayer.h b/platform/darwin/src/MGLRasterStyleLayer.h index 09fafd114d..53a6a98b8a 100644 --- a/platform/darwin/src/MGLRasterStyleLayer.h +++ b/platform/darwin/src/MGLRasterStyleLayer.h @@ -28,6 +28,9 @@ NS_ASSUME_NONNULL_BEGIN ### Example ```swift + let layer = MGLRasterStyleLayer(identifier: "clouds", source: source) + layer.rasterOpacity = MGLStyleValue(rawValue: 0.5) + mapView.style?.addLayer(layer) ``` */ MGL_EXPORT diff --git a/platform/darwin/src/MGLSymbolStyleLayer.h b/platform/darwin/src/MGLSymbolStyleLayer.h index 8512870e1b..5df995aa01 100644 --- a/platform/darwin/src/MGLSymbolStyleLayer.h +++ b/platform/darwin/src/MGLSymbolStyleLayer.h @@ -265,6 +265,16 @@ typedef NS_ENUM(NSUInteger, MGLTextTranslationAnchor) { ### Example ```swift + let layer = MGLSymbolStyleLayer(identifier: "coffeeshops", source: pois) + layer.sourceLayerIdentifier = "pois" + layer.iconImageName = MGLStyleValue(rawValue: "coffee") + layer.iconScale = MGLStyleValue(rawValue: 0.5) + layer.text = MGLStyleValue(rawValue: "{name}") + layer.textTranslation = MGLStyleValue(rawValue: NSValue(cgVector: CGVector(dx: 10, dy: 0))) + layer.textJustification = MGLStyleValue(rawValue: NSValue(mglTextJustification: .left)) + layer.textAnchor = MGLStyleValue(rawValue: NSValue(mglTextAnchor: .left)) + layer.predicate = NSPredicate(format: "%K == %@", "venue-type", "coffee") + mapView.style?.addLayer(layer) ``` */ MGL_EXPORT -- cgit v1.2.1 From 6ca8cd7e24cf919d5eeb0be49d34a02ba9969ac8 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Wed, 5 Jul 2017 21:21:04 +0200 Subject: [macos] - add Styles header to CHANGELOG.md --- platform/macos/CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index df8c395ee8..29e3803dc2 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -3,6 +3,7 @@ ## master ### Styles + * Added support for displaying geo-referenced images via the `MGLImageSource`. [#9110](https://github.com/mapbox/mapbox-gl-native/pull/9110) * The previously-deprecated support for style classes has been removed. For interface compatibility, the API methods remain, but they are now non-functional. * Added an `overlays` property to `MGLMapView`. ([#8617](https://github.com/mapbox/mapbox-gl-native/pull/8617)) @@ -16,6 +17,8 @@ This version of the Mapbox macOS SDK corresponds to version 3.6.0 of the Mapbox * Xcode 8.0 or higher is now recommended for using this SDK. ([#8775](https://github.com/mapbox/mapbox-gl-native/pull/8775)) * Updated MGLMapView’s logo view to display [the new Mapbox logo](https://www.mapbox.com/blog/new-mapbox-logo/). ([#8771](https://github.com/mapbox/mapbox-gl-native/pull/8771), [#8773](https://github.com/mapbox/mapbox-gl-native/pull/8773)) +### Styles + * Added support for 3D extrusion of buildings and other polygonal features via the `MGLFillExtrusionStyleLayer` class and the `fill-extrusion` layer type in style JSON. ([#8431](https://github.com/mapbox/mapbox-gl-native/pull/8431)) * MGLMapView and MGLTilePyramidOfflineRegion now default to version 10 of the Mapbox Streets style. Similarly, several style URL class methods of MGLStyle return URLs to version 10 styles. Unversioned variations of these methods are no longer deprecated. `MGLStyleDefaultVersion` should no longer be used with any style other than Streets. ([#6301](https://github.com/mapbox/mapbox-gl-native/pull/6301)) * Added class methods to MGLStyle that correspond to the new [Traffic Day and Traffic Night](https://www.mapbox.com/blog/live-traffic-maps/) styles. ([#6301](https://github.com/mapbox/mapbox-gl-native/pull/6301)) -- cgit v1.2.1 From adbce36fe6e1a9d95633776ff9fada67289733ae Mon Sep 17 00:00:00 2001 From: Pablo Guardiola Date: Thu, 6 Jul 2017 11:26:03 +0200 Subject: [android] Fix my location drawable getting tinted (#9410) * fix my location drawable tinted when setting mapbox_myLocationTintColor in xml issue (linking my location foreground drawables with my location foreground tint color and adding the possibility of setting an undefined my location foreground tint color) * link my location background drawable with my location background tint color and add the possibility of setting an undefined my location background tint color --- .../mapbox/mapboxsdk/maps/MapboxMapOptions.java | 21 ++++++++------- .../mapboxsdk/maps/widgets/MyLocationView.java | 31 +++++++++++++++++----- .../maps/widgets/MyLocationViewSettings.java | 10 +++++-- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java index 2efed1b322..80b25bf0de 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java @@ -4,7 +4,6 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; -import android.graphics.Color; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Parcel; @@ -37,6 +36,7 @@ public class MapboxMapOptions implements Parcelable { private static final float FOUR_DP = 4f; private static final float NINETY_TWO_DP = 92f; + private static final int UNDEFINED_COLOR = -1; private CameraPosition cameraPosition; @@ -53,7 +53,7 @@ public class MapboxMapOptions implements Parcelable { private int[] logoMargins; @ColorInt - private int attributionTintColor = -1; + private int attributionTintColor = UNDEFINED_COLOR; private boolean attributionEnabled = true; private int attributionGravity = Gravity.BOTTOM; private int[] attributionMargins; @@ -72,8 +72,10 @@ public class MapboxMapOptions implements Parcelable { private Drawable myLocationForegroundDrawable; private Drawable myLocationForegroundBearingDrawable; private Drawable myLocationBackgroundDrawable; - private int myLocationForegroundTintColor; - private int myLocationBackgroundTintColor; + @ColorInt + private int myLocationForegroundTintColor = UNDEFINED_COLOR; + @ColorInt + private int myLocationBackgroundTintColor = UNDEFINED_COLOR; private int[] myLocationBackgroundPadding; private int myLocationAccuracyTintColor; private int myLocationAccuracyAlpha; @@ -234,7 +236,7 @@ public class MapboxMapOptions implements Parcelable { FOUR_DP * pxlRatio))}); mapboxMapOptions.attributionTintColor(typedArray.getColor( - R.styleable.mapbox_MapView_mapbox_uiAttributionTintColor, -1)); + R.styleable.mapbox_MapView_mapbox_uiAttributionTintColor, UNDEFINED_COLOR)); mapboxMapOptions.attributionEnabled(typedArray.getBoolean( R.styleable.mapbox_MapView_mapbox_uiAttribution, true)); mapboxMapOptions.attributionGravity(typedArray.getInt( @@ -251,10 +253,9 @@ public class MapboxMapOptions implements Parcelable { mapboxMapOptions.locationEnabled(typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_myLocation, false)); mapboxMapOptions.myLocationForegroundTintColor( - typedArray.getColor(R.styleable.mapbox_MapView_mapbox_myLocationTintColor, - ColorUtils.getPrimaryColor(context))); + typedArray.getColor(R.styleable.mapbox_MapView_mapbox_myLocationTintColor, UNDEFINED_COLOR)); mapboxMapOptions.myLocationBackgroundTintColor( - typedArray.getColor(R.styleable.mapbox_MapView_mapbox_myLocationBackgroundTintColor, Color.WHITE)); + typedArray.getColor(R.styleable.mapbox_MapView_mapbox_myLocationBackgroundTintColor, UNDEFINED_COLOR)); Drawable foregroundDrawable = typedArray.getDrawable(R.styleable.mapbox_MapView_mapbox_myLocationDrawable); if (foregroundDrawable == null) { @@ -638,7 +639,7 @@ public class MapboxMapOptions implements Parcelable { /** * Set the background tint color of MyLocationView. * - * @param myLocationBackgroundTintColor the color to tint the background + * @param myLocationBackgroundTintColor the color to tint the background drawable * @return This */ public MapboxMapOptions myLocationBackgroundTintColor(@ColorInt int myLocationBackgroundTintColor) { @@ -944,6 +945,7 @@ public class MapboxMapOptions implements Parcelable { * * @return the tint color */ + @ColorInt public int getMyLocationForegroundTintColor() { return myLocationForegroundTintColor; } @@ -953,6 +955,7 @@ public class MapboxMapOptions implements Parcelable { * * @return the tint color */ + @ColorInt public int getMyLocationBackgroundTintColor() { return myLocationBackgroundTintColor; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java index 8b6b93e03a..24da59bb7e 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java @@ -51,6 +51,7 @@ import timber.log.Timber; */ public class MyLocationView extends View { + private static final int UNDEFINED_TINT_COLOR = -1; private MyLocationBehavior myLocationBehavior; private MapboxMap mapboxMap; @@ -198,12 +199,8 @@ public class MyLocationView extends View { * @param color The color to tint the drawable with */ public final void setForegroundDrawableTint(@ColorInt int color) { - if (foregroundDrawable != null) { - foregroundDrawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN); - } - if (foregroundBearingDrawable != null) { - foregroundBearingDrawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN); - } + applyDrawableTint(foregroundDrawable, color); + applyDrawableTint(foregroundBearingDrawable, color); invalidate(); } @@ -247,7 +244,7 @@ public class MyLocationView extends View { if (backgroundDrawable == null) { return; } - backgroundDrawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN); + applyDrawableTint(backgroundDrawable, color); invalidate(); } @@ -737,6 +734,26 @@ public class MyLocationView extends View { setEnabled(isEnabled(), locationSource != null); } + private void applyDrawableTint(Drawable drawable, @ColorInt int color) { + if (color == UNDEFINED_TINT_COLOR) { + removeTintColorFilter(drawable); + } else { + applyTintColorFilter(drawable, color); + } + } + + private void removeTintColorFilter(Drawable drawable) { + if (drawable != null) { + drawable.mutate().setColorFilter(null); + } + } + + private void applyTintColorFilter(Drawable drawable, @ColorInt int color) { + if (drawable != null) { + drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN); + } + } + private static class GpsLocationListener implements LocationEngineListener { private WeakReference userLocationView; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java index 2ad1bf7ebc..fe2f18e4dd 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java @@ -119,6 +119,7 @@ public class MyLocationViewSettings { *

      * The foreground drawable is the image visible on screen *

      + * It's linked with the foreground tint color * * @param foregroundDrawable the drawable to show as foreground without bearing * @param foregroundBearingDrawable the drawable to show as foreground when bearing is enabled @@ -127,6 +128,7 @@ public class MyLocationViewSettings { this.foregroundDrawable = foregroundDrawable; this.foregroundBearingDrawable = foregroundBearingDrawable; myLocationView.setForegroundDrawables(foregroundDrawable, foregroundBearingDrawable); + myLocationView.setForegroundDrawableTint(foregroundTintColor); } /** @@ -153,7 +155,8 @@ public class MyLocationViewSettings { * The color will tint both the foreground and the bearing foreground drawable. *

      * - * @param foregroundTintColor the color to tint the foreground drawable + * @param foregroundTintColor the color to tint the foreground drawable or -1 (undefined color) to remove the + * existing foreground tint color */ public void setForegroundTintColor(@ColorInt int foregroundTintColor) { this.foregroundTintColor = foregroundTintColor; @@ -174,6 +177,7 @@ public class MyLocationViewSettings { *

      * Padding can be added to provide an offset to the background *

      + * It's linked with the background tint color * * @param backgroundDrawable the drawable to show as background * @param padding the padding added to the background @@ -186,6 +190,7 @@ public class MyLocationViewSettings { } else { myLocationView.setShadowDrawable(backgroundDrawable); } + myLocationView.setShadowDrawableTint(backgroundTintColor); } /** @@ -200,7 +205,8 @@ public class MyLocationViewSettings { /** * Set the background tint color. * - * @param backgroundTintColor the color to tint the background + * @param backgroundTintColor the color to tint the background drawable or -1 (undefined color) to remove the + * existing background tint color */ public void setBackgroundTintColor(@ColorInt int backgroundTintColor) { this.backgroundTintColor = backgroundTintColor; -- cgit v1.2.1 From fc48ca18018564e26f0498c4f59f77374c1cadbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Tue, 4 Jul 2017 14:19:25 +0200 Subject: [build] use CMake to generate Xcode schemes --- CMakeLists.txt | 1 + Makefile | 31 +-------- cmake/benchmark.cmake | 7 ++ cmake/core.cmake | 2 + cmake/executable.xcscheme | 102 +++++++++++++++++++++++++++ cmake/glfw.cmake | 13 ++++ cmake/library.xcscheme | 80 ++++++++++++++++++++++ cmake/loop-darwin.cmake | 2 + cmake/loop-uv.cmake | 2 + cmake/node.cmake | 34 +++++++++ cmake/node.xcscheme | 95 ++++++++++++++++++++++++++ cmake/offline.cmake | 15 ++++ cmake/render.cmake | 19 ++++++ cmake/test.cmake | 11 +++ cmake/xcode.cmake | 75 ++++++++++++++++++++ platform/macos/scripts/create_scheme.sh | 40 ----------- platform/macos/scripts/executable.xcscheme | 106 ----------------------------- platform/macos/scripts/library.xcscheme | 80 ---------------------- platform/macos/scripts/node.xcscheme | 99 --------------------------- platform/qt/qt.cmake | 4 ++ 20 files changed, 463 insertions(+), 355 deletions(-) create mode 100644 cmake/executable.xcscheme create mode 100644 cmake/library.xcscheme create mode 100644 cmake/node.xcscheme create mode 100644 cmake/xcode.cmake delete mode 100755 platform/macos/scripts/create_scheme.sh delete mode 100644 platform/macos/scripts/executable.xcscheme delete mode 100644 platform/macos/scripts/library.xcscheme delete mode 100644 platform/macos/scripts/node.xcscheme diff --git a/CMakeLists.txt b/CMakeLists.txt index e84b3a6da2..189f033b79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ set(CMAKE_CXX_STANDARD 14) include(cmake/mbgl.cmake) include(cmake/mason.cmake) +include(cmake/xcode.cmake) option(WITH_CXX11ABI "Use cxx11abi mason packages" OFF) option(WITH_COVERAGE "Enable coverage reports" OFF) diff --git a/Makefile b/Makefile index ba2f1ae31d..f694d19b52 100644 --- a/Makefile +++ b/Makefile @@ -70,31 +70,10 @@ MACOS_XCODEBUILD = xcodebuild \ -configuration $(BUILDTYPE) \ -workspace $(MACOS_WORK_PATH) - -MACOS_XCSCHEMES += platform/macos/scripts/executable.xcscheme -MACOS_XCSCHEMES += platform/macos/scripts/library.xcscheme -MACOS_XCSCHEMES += platform/macos/scripts/node.xcscheme - -$(MACOS_PROJ_PATH): $(BUILD_DEPS) $(MACOS_USER_DATA_PATH)/WorkspaceSettings.xcsettings $(MACOS_XCSCHEMES) +$(MACOS_PROJ_PATH): $(BUILD_DEPS) $(MACOS_USER_DATA_PATH)/WorkspaceSettings.xcsettings mkdir -p $(MACOS_OUTPUT_PATH) (cd $(MACOS_OUTPUT_PATH) && cmake -G Xcode ../..) - @# Create Xcode schemes so that we can use xcodebuild from the command line. CMake doesn't - @# create these automatically. - SCHEME_NAME=mbgl-test SCHEME_TYPE=executable platform/macos/scripts/create_scheme.sh - SCHEME_NAME=mbgl-benchmark SCHEME_TYPE=executable platform/macos/scripts/create_scheme.sh - SCHEME_NAME=mbgl-render SCHEME_TYPE=executable platform/macos/scripts/create_scheme.sh - SCHEME_NAME=mbgl-offline SCHEME_TYPE=executable platform/macos/scripts/create_scheme.sh - SCHEME_NAME=mbgl-glfw SCHEME_TYPE=executable platform/macos/scripts/create_scheme.sh - SCHEME_NAME=mbgl-core SCHEME_TYPE=library BUILDABLE_NAME=libmbgl-core.a BLUEPRINT_NAME=mbgl-core platform/macos/scripts/create_scheme.sh - SCHEME_NAME=mbgl-node SCHEME_TYPE=library BUILDABLE_NAME=mbgl-node.node BLUEPRINT_NAME=mbgl-node platform/macos/scripts/create_scheme.sh - - @# Create schemes for running node tests. These have all of the environment variables set to - @# launch in the correct location. - SCHEME_NAME="node tests" SCHEME_TYPE=node BUILDABLE_NAME=mbgl-node.node BLUEPRINT_NAME=mbgl-node NODE_ARGUMENT="`npm bin tape`/tape platform/node/test/js/**/*.test.js" platform/macos/scripts/create_scheme.sh - SCHEME_NAME="node render tests" SCHEME_TYPE=node BUILDABLE_NAME=mbgl-node.node BLUEPRINT_NAME=mbgl-node NODE_ARGUMENT="platform/node/test/render.test.js" platform/macos/scripts/create_scheme.sh - SCHEME_NAME="node query tests" SCHEME_TYPE=node BUILDABLE_NAME=mbgl-node.node BLUEPRINT_NAME=mbgl-node NODE_ARGUMENT="platform/node/test/query.test.js" platform/macos/scripts/create_scheme.sh - $(MACOS_USER_DATA_PATH)/WorkspaceSettings.xcsettings: platform/macos/WorkspaceSettings.xcsettings mkdir -p "$(MACOS_USER_DATA_PATH)" cp platform/macos/WorkspaceSettings.xcsettings "$@" @@ -408,14 +387,6 @@ $(MACOS_QT_PROJ_PATH): $(BUILD_DEPS) -DWITH_CXX11ABI=$(shell scripts/check-cxx11abi.sh) \ -DWITH_COVERAGE=${WITH_COVERAGE}) - @# Create Xcode schemes so that we can use xcodebuild from the command line. CMake doesn't - @# create these automatically. - XCODEPROJ=$(MACOS_QT_PROJ_PATH) SCHEME_NAME=mbgl-qt SCHEME_TYPE=executable platform/macos/scripts/create_scheme.sh - XCODEPROJ=$(MACOS_QT_PROJ_PATH) SCHEME_NAME=mbgl-test SCHEME_TYPE=executable platform/macos/scripts/create_scheme.sh - XCODEPROJ=$(MACOS_QT_PROJ_PATH) SCHEME_NAME=mbgl-benchmark SCHEME_TYPE=executable platform/macos/scripts/create_scheme.sh - XCODEPROJ=$(MACOS_QT_PROJ_PATH) SCHEME_NAME=mbgl-core SCHEME_TYPE=library BUILDABLE_NAME=libmbgl-core.a BLUEPRINT_NAME=mbgl-core platform/macos/scripts/create_scheme.sh - XCODEPROJ=$(MACOS_QT_PROJ_PATH) SCHEME_NAME=qmapboxgl SCHEME_TYPE=library BUILDABLE_NAME=libqmapboxgl.dylib BLUEPRINT_NAME=qmapboxgl platform/macos/scripts/create_scheme.sh - .PHONY: qtproj qtproj: $(MACOS_QT_PROJ_PATH) open $(MACOS_QT_PROJ_PATH) diff --git a/cmake/benchmark.cmake b/cmake/benchmark.cmake index f4c59fa01e..1dfca27e6c 100644 --- a/cmake/benchmark.cmake +++ b/cmake/benchmark.cmake @@ -25,3 +25,10 @@ target_add_mason_package(mbgl-benchmark PRIVATE vector-tile) mbgl_platform_benchmark() create_source_groups(mbgl-benchmark) + +xcode_create_scheme( + TARGET mbgl-benchmark + OPTIONAL_ARGS + "--benchmark_filter=Category.*" + "--benchmark_repetitions=1" +) diff --git a/cmake/core.cmake b/cmake/core.cmake index c4e4d2abc7..ff2b4ba53c 100644 --- a/cmake/core.cmake +++ b/cmake/core.cmake @@ -32,3 +32,5 @@ target_add_mason_package(mbgl-core PRIVATE vector-tile) mbgl_platform_core() create_source_groups(mbgl-core) + +xcode_create_scheme(TARGET mbgl-core) diff --git a/cmake/executable.xcscheme b/cmake/executable.xcscheme new file mode 100644 index 0000000000..44146a621d --- /dev/null +++ b/cmake/executable.xcscheme @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + ${XCSCHEME_COMMAND_LINE_ARGS} + + + + + + + + + + + + + + + + + + + diff --git a/cmake/glfw.cmake b/cmake/glfw.cmake index 744477e39a..b176fbb5bc 100644 --- a/cmake/glfw.cmake +++ b/cmake/glfw.cmake @@ -43,3 +43,16 @@ target_add_mason_package(mbgl-glfw PRIVATE variant) mbgl_platform_glfw() create_source_groups(mbgl-glfw) + +xcode_create_scheme( + TARGET mbgl-glfw + OPTIONAL_ARGS + "--style=file.json" + "--lon=0" + "--lat=0" + "--zoom=1" + "--bearing=0" + "--pitch=0" + "--fullscreen" + "--benchmark" +) diff --git a/cmake/library.xcscheme b/cmake/library.xcscheme new file mode 100644 index 0000000000..320a2f851f --- /dev/null +++ b/cmake/library.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cmake/loop-darwin.cmake b/cmake/loop-darwin.cmake index 92ea631809..46511d2548 100644 --- a/cmake/loop-darwin.cmake +++ b/cmake/loop-darwin.cmake @@ -17,3 +17,5 @@ target_include_directories(mbgl-loop-darwin ) create_source_groups(mbgl-loop-darwin) + +xcode_create_scheme(TARGET mbgl-loop-darwin) \ No newline at end of file diff --git a/cmake/loop-uv.cmake b/cmake/loop-uv.cmake index 182b0d6f90..8840040963 100644 --- a/cmake/loop-uv.cmake +++ b/cmake/loop-uv.cmake @@ -19,3 +19,5 @@ target_link_libraries(mbgl-loop-uv ) create_source_groups(mbgl-loop-uv) + +xcode_create_scheme(TARGET mbgl-loop-uv) \ No newline at end of file diff --git a/cmake/node.cmake b/cmake/node.cmake index 6833cb983f..8626534271 100644 --- a/cmake/node.cmake +++ b/cmake/node.cmake @@ -53,3 +53,37 @@ add_custom_command( mbgl_platform_node() create_source_groups(mbgl-node) + +xcode_create_scheme( + TARGET mbgl-node +) + +xcode_create_scheme( + TARGET mbgl-node + TYPE node + NAME "node tests" + ARGS + "`npm bin tape`/tape platform/node/test/js/**/*.test.js" +) + +xcode_create_scheme( + TARGET mbgl-node + TYPE node + NAME "node render tests" + ARGS + "platform/node/test/render.test.js" + OPTIONAL_ARGS + "group" + "test" +) + +xcode_create_scheme( + TARGET mbgl-node + TYPE node + NAME "node query tests" + ARGS + "platform/node/test/query.test.js" + OPTIONAL_ARGS + "group" + "test" +) diff --git a/cmake/node.xcscheme b/cmake/node.xcscheme new file mode 100644 index 0000000000..0daffa46e6 --- /dev/null +++ b/cmake/node.xcscheme @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + ${XCSCHEME_COMMAND_LINE_ARGS} + + + + + + + + + + + + + + + + + + + diff --git a/cmake/offline.cmake b/cmake/offline.cmake index d0124e661f..1ec3f61e36 100644 --- a/cmake/offline.cmake +++ b/cmake/offline.cmake @@ -25,3 +25,18 @@ target_add_mason_package(mbgl-offline PRIVATE boost_libprogram_options) mbgl_platform_offline() create_source_groups(mbgl-offline) + +xcode_create_scheme( + TARGET mbgl-offline + OPTIONAL_ARGS + "--style=file.json" + "--north=37.2" + "--west=-122.8" + "--south=38.1" + "--east=-121.7" + "--minZoom=0.0" + "--maxZoom=15.0" + "--pixelRatio=1.0" + "--token=" + "--output=offline.db" +) diff --git a/cmake/render.cmake b/cmake/render.cmake index 023b3c21e3..407e1ca8ef 100644 --- a/cmake/render.cmake +++ b/cmake/render.cmake @@ -20,3 +20,22 @@ target_add_mason_package(mbgl-render PRIVATE boost_libprogram_options) mbgl_platform_render() create_source_groups(mbgl-render) + +xcode_create_scheme( + TARGET mbgl-render + OPTIONAL_ARGS + "--style=file.json" + "--lon=0" + "--lat=0" + "--zoom=0" + "--bearing=0" + "--pitch=0" + "--width=512" + "--height=512" + "--ratio=1" + "--token=" + "--debug" + "--output=out.png" + "--cache=cache.sqlite" + "--assets=." +) diff --git a/cmake/test.cmake b/cmake/test.cmake index 8a5233f5a5..5e404577ed 100644 --- a/cmake/test.cmake +++ b/cmake/test.cmake @@ -40,3 +40,14 @@ target_add_mason_package(mbgl-test PRIVATE shelf-pack) mbgl_platform_test() create_source_groups(mbgl-test) + +xcode_create_scheme( + TARGET mbgl-test + OPTIONAL_ARGS + "--gtest_filter=Category.*" + "--gtest_repeat=0" + "--gtest_shuffle=0" + "--gtest_break_on_failure=0" + "--gtest_throw_on_failure=0" + "--gtest_catch_exceptions=0" + ) diff --git a/cmake/xcode.cmake b/cmake/xcode.cmake new file mode 100644 index 0000000000..3537009330 --- /dev/null +++ b/cmake/xcode.cmake @@ -0,0 +1,75 @@ +function(get_target_filename OUTPUT TARGET) + get_target_property(_TYPE "${TARGET}" TYPE) + get_target_property(_PREFIX "${TARGET}" PREFIX) + if(NOT _PREFIX AND NOT _PREFIX STREQUAL "") + set(_PREFIX "${CMAKE_${_TYPE}_PREFIX}") + endif() + get_target_property(_BASENAME "${TARGET}" OUTPUT_NAME) + if(NOT _BASENAME) + get_target_property(_BASENAME "${TARGET}" NAME) + endif() + get_target_property(_SUFFIX "${TARGET}" SUFFIX) + if(NOT _SUFFIX AND NOT _SUFFIX STREQUAL "") + set(_SUFFIX "${CMAKE_${_TYPE}_SUFFIX}") + endif() + set(${OUTPUT} "${_PREFIX}${_BASENAME}${_SUFFIX}" PARENT_SCOPE) +endfunction() + +function(xcode_create_scheme) + if (NOT CMAKE_GENERATOR STREQUAL "Xcode") + return() + endif() + + cmake_parse_arguments(XCSCHEME "" "TARGET;TYPE;NAME" "ARGS;OPTIONAL_ARGS" ${ARGN}) + + if(XCSCHEME_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "xcode_create_scheme() called with unrecognized arguments: ${XCSCHEME_UNPARSED_ARGUMENTS}") + endif() + + if(NOT XCSCHEME_TARGET) + message(FATAL_ERROR "xcode_create_scheme() called without required argument TARGET") + endif() + + if(NOT XCSCHEME_TYPE) + get_target_property(_TYPE "${XCSCHEME_TARGET}" TYPE) + if (_TYPE MATCHES "^.*_LIBRARY$") + set(XCSCHEME_TYPE "library") + elseif(_TYPE STREQUAL "EXECUTABLE") + set(XCSCHEME_TYPE "executable") + else() + message(FATAL_ERROR "xcode_create_scheme() could not determine type of ${XCSCHEME_TARGET}") + endif() + endif() + + if(NOT XCSCHEME_NAME) + set(XCSCHEME_NAME "${XCSCHEME_TARGET}") + endif() + + set(XCODEPROJ_PATH "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.xcodeproj") + set(XCSCHEME_OUTPUT_FILE "${XCODEPROJ_PATH}/xcshareddata/xcschemes/${XCSCHEME_NAME}.xcscheme") + + # Prevent overwriting of the scheme file on every CMake rerun. + if (EXISTS "${XCSCHEME_OUTPUT_FILE}") + return() + endif() + + file(RELATIVE_PATH XCSCHEME_CONTAINER "${CMAKE_SOURCE_DIR}" "${XCODEPROJ_PATH}") + string(RANDOM LENGTH 24 ALPHABET "0123456789ABCDEF" XCSCHEME_BLUEPRINT_ID) + get_target_filename(XCSCHEME_BUILDABLE_NAME "${XCSCHEME_TARGET}") + set(XCSCHEME_BLUEPRINT_NAME "${XCSCHEME_TARGET}") + set(XCSCHEME_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}") + set(XCSCHEME_NODE_EXECUTABLE "${NodeJS_EXECUTABLE}") + get_filename_component(XCSCHEME_NODE_PATH "${NodeJS_EXECUTABLE}" DIRECTORY) + + set(XCSCHEME_COMMAND_LINE_ARGS "") + foreach(_ARG IN LISTS XCSCHEME_ARGS) + set(XCSCHEME_COMMAND_LINE_ARGS "${XCSCHEME_COMMAND_LINE_ARGS}\n \n ") + endforeach() + foreach(_ARG IN LISTS XCSCHEME_OPTIONAL_ARGS) + set(XCSCHEME_COMMAND_LINE_ARGS "${XCSCHEME_COMMAND_LINE_ARGS}\n \n ") + endforeach() + + configure_file( + "${CMAKE_SOURCE_DIR}/cmake/${XCSCHEME_TYPE}.xcscheme" + "${XCSCHEME_OUTPUT_FILE}") +endfunction() diff --git a/platform/macos/scripts/create_scheme.sh b/platform/macos/scripts/create_scheme.sh deleted file mode 100755 index 5a609130d8..0000000000 --- a/platform/macos/scripts/create_scheme.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env bash - -set -u - -XCODEPROJ=${XCODEPROJ:-build/macos/mbgl.xcodeproj} -OUTPUT="${XCODEPROJ}/xcshareddata/xcschemes/${SCHEME_NAME}.xcscheme" - -# Required ENV vars: -# - SCHEME_TYPE: type of the scheme -# - SCHEME_NAME: name of the scheme - -# Optional ENV vars: -# - NODE_ARGUMENT (defaults to "") -# - BUILDABLE_NAME (defaults ot SCHEME_NAME) -# - BLUEPRINT_NAME (defaults ot SCHEME_NAME) - - -# Try to reuse the existing Blueprint ID if the scheme already exists. -if [ -f "${OUTPUT}" ]; then - BLUEPRINT_ID=$(sed -n "s/[ \t]*BlueprintIdentifier *= *\"\([A-Z0-9]\{24\}\)\"/\\1/p" "${OUTPUT}" | head -1) -fi - -NODE_ARGUMENT=${NODE_ARGUMENT:-} -MAPBOX_ACCESS_TOKEN=${MAPBOX_ACCESS_TOKEN:-} -BLUEPRINT_ID=${BLUEPRINT_ID:-$(hexdump -n 12 -v -e '/1 "%02X"' /dev/urandom)} -BUILDABLE_NAME=${BUILDABLE_NAME:-${SCHEME_NAME}} -BLUEPRINT_NAME=${BLUEPRINT_NAME:-${SCHEME_NAME}} - -mkdir -p "${XCODEPROJ}/xcshareddata/xcschemes" - -sed "\ -s#{{BLUEPRINT_ID}}#${BLUEPRINT_ID}#;\ -s#{{BLUEPRINT_NAME}}#${BLUEPRINT_NAME}#;\ -s#{{BUILDABLE_NAME}}#${BUILDABLE_NAME}#;\ -s#{{CONTAINER}}#${XCODEPROJ}#;\ -s#{{MAPBOX_ACCESS_TOKEN}}#${MAPBOX_ACCESS_TOKEN}#;\ -s#{{WORKING_DIRECTORY}}#$(pwd)#;\ -s#{{NODE_PATH}}#$(dirname `which node`)#;\ -s#{{NODE_ARGUMENT}}#${NODE_ARGUMENT}#" \ - platform/macos/scripts/${SCHEME_TYPE}.xcscheme > "${OUTPUT}" diff --git a/platform/macos/scripts/executable.xcscheme b/platform/macos/scripts/executable.xcscheme deleted file mode 100644 index c6a8d04d30..0000000000 --- a/platform/macos/scripts/executable.xcscheme +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/platform/macos/scripts/library.xcscheme b/platform/macos/scripts/library.xcscheme deleted file mode 100644 index 5472d3c821..0000000000 --- a/platform/macos/scripts/library.xcscheme +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/platform/macos/scripts/node.xcscheme b/platform/macos/scripts/node.xcscheme deleted file mode 100644 index 6f541deca3..0000000000 --- a/platform/macos/scripts/node.xcscheme +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/platform/qt/qt.cmake b/platform/qt/qt.cmake index cee0d1080c..e5b96bfe93 100644 --- a/platform/qt/qt.cmake +++ b/platform/qt/qt.cmake @@ -76,6 +76,8 @@ add_executable(mbgl-qt platform/qt/resources/common.qrc ) +xcode_create_scheme(TARGET mbgl-qt) + if(WITH_QT_4) include(platform/qt/qt4.cmake) else() @@ -107,3 +109,5 @@ add_custom_command( ${CMAKE_SOURCE_DIR}/platform/qt/include ${CMAKE_CURRENT_BINARY_DIR}/platform/qt/include ) + +xcode_create_scheme(TARGET qmapboxgl) -- cgit v1.2.1 From 6d526c7b1dad81c8da1cf0d221d0b83ed2be9862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Tue, 4 Jul 2017 18:18:05 +0200 Subject: [core] refactor ClipID generation --- src/mbgl/algorithm/generate_clip_ids.hpp | 4 +- src/mbgl/algorithm/generate_clip_ids_impl.hpp | 26 +- src/mbgl/annotation/render_annotation_source.cpp | 2 +- src/mbgl/annotation/render_annotation_source.hpp | 2 +- src/mbgl/renderer/render_source.hpp | 3 +- src/mbgl/renderer/render_style.cpp | 10 +- src/mbgl/renderer/render_tile.hpp | 2 +- .../renderer/sources/render_geojson_source.cpp | 2 +- .../renderer/sources/render_geojson_source.hpp | 2 +- src/mbgl/renderer/sources/render_image_source.hpp | 5 +- src/mbgl/renderer/sources/render_raster_source.cpp | 2 +- src/mbgl/renderer/sources/render_raster_source.hpp | 2 +- src/mbgl/renderer/sources/render_vector_source.cpp | 2 +- src/mbgl/renderer/sources/render_vector_source.hpp | 2 +- src/mbgl/renderer/tile_pyramid.cpp | 27 +- src/mbgl/renderer/tile_pyramid.hpp | 4 +- test/algorithm/generate_clip_ids.test.cpp | 357 ++++++++++----------- 17 files changed, 209 insertions(+), 245 deletions(-) diff --git a/src/mbgl/algorithm/generate_clip_ids.hpp b/src/mbgl/algorithm/generate_clip_ids.hpp index d917b398af..c4d332343b 100644 --- a/src/mbgl/algorithm/generate_clip_ids.hpp +++ b/src/mbgl/algorithm/generate_clip_ids.hpp @@ -25,8 +25,8 @@ private: std::unordered_multimap pool; public: - template - void update(Renderables& renderables); + template + void update(std::vector> renderables); std::map getStencils() const; }; diff --git a/src/mbgl/algorithm/generate_clip_ids_impl.hpp b/src/mbgl/algorithm/generate_clip_ids_impl.hpp index d63ba27b6b..db62214220 100644 --- a/src/mbgl/algorithm/generate_clip_ids_impl.hpp +++ b/src/mbgl/algorithm/generate_clip_ids_impl.hpp @@ -7,14 +7,16 @@ namespace mbgl { namespace algorithm { -template -void ClipIDGenerator::update(Renderables& renderables) { +template +void ClipIDGenerator::update(std::vector> renderables) { std::size_t size = 0; + std::sort(renderables.begin(), renderables.end(), + [](const auto& a, const auto& b) { return a.get().id < b.get().id; }); + const auto end = renderables.end(); for (auto it = renderables.begin(); it != end; it++) { - auto& tileID = it->first; - auto& renderable = it->second; + auto& renderable = it->get(); if (!renderable.used) { continue; } @@ -28,17 +30,17 @@ void ClipIDGenerator::update(Renderables& renderables) { // can never be children of the current wrap. auto child_it = std::next(it); const auto children_end = std::lower_bound( - child_it, end, UnwrappedTileID{ static_cast(tileID.wrap + 1), { 0, 0, 0 } }, - [](auto& a, auto& b) { return a.first < b; }); + child_it, end, UnwrappedTileID{ static_cast(renderable.id.wrap + 1), { 0, 0, 0 } }, + [](auto& a, auto& b) { return a.get().id < b; }); for (; child_it != children_end; ++child_it) { - auto& childTileID = child_it->first; - if (childTileID.isChildOf(tileID)) { + auto& childTileID = child_it->get().id; + if (childTileID.isChildOf(it->get().id)) { leaf.add(childTileID.canonical); } } // Find a leaf with matching children. - for (auto its = pool.equal_range(tileID); its.first != its.second; ++its.first) { + for (auto its = pool.equal_range(renderable.id); its.first != its.second; ++its.first) { auto& existing = its.first->second; if (existing == leaf) { leaf.clip = existing.clip; @@ -50,7 +52,7 @@ void ClipIDGenerator::update(Renderables& renderables) { size++; } - pool.emplace(tileID, std::move(leaf)); + pool.emplace(renderable.id, std::move(leaf)); } if (size > 0) { @@ -60,8 +62,8 @@ void ClipIDGenerator::update(Renderables& renderables) { // We are starting our count with 1 since we need at least 1 bit set to distinguish between // areas without any tiles whatsoever and the current area. uint8_t count = 1; - for (auto& pair : renderables) { - auto& renderable = pair.second; + for (auto& it : renderables) { + auto& renderable = it.get(); if (!renderable.used) { continue; } diff --git a/src/mbgl/annotation/render_annotation_source.cpp b/src/mbgl/annotation/render_annotation_source.cpp index 8fb11785fd..0d0427b7a7 100644 --- a/src/mbgl/annotation/render_annotation_source.cpp +++ b/src/mbgl/annotation/render_annotation_source.cpp @@ -53,7 +53,7 @@ void RenderAnnotationSource::finishRender(Painter& painter) { tilePyramid.finishRender(painter); } -std::map& RenderAnnotationSource::getRenderTiles() { +std::vector> RenderAnnotationSource::getRenderTiles() { return tilePyramid.getRenderTiles(); } diff --git a/src/mbgl/annotation/render_annotation_source.hpp b/src/mbgl/annotation/render_annotation_source.hpp index 7231452d4f..621298a112 100644 --- a/src/mbgl/annotation/render_annotation_source.hpp +++ b/src/mbgl/annotation/render_annotation_source.hpp @@ -21,7 +21,7 @@ public: void startRender(Painter&) final; void finishRender(Painter&) final; - std::map& getRenderTiles() final; + std::vector> getRenderTiles() final; std::unordered_map> queryRenderedFeatures(const ScreenLineString& geometry, diff --git a/src/mbgl/renderer/render_source.hpp b/src/mbgl/renderer/render_source.hpp index b82547b375..9d2e74b50b 100644 --- a/src/mbgl/renderer/render_source.hpp +++ b/src/mbgl/renderer/render_source.hpp @@ -57,7 +57,8 @@ public: virtual void startRender(Painter&) = 0; virtual void finishRender(Painter&) = 0; - virtual std::map& getRenderTiles() = 0; + // Returns an unsorted list of RenderTiles. + virtual std::vector> getRenderTiles() = 0; virtual std::unordered_map> queryRenderedFeatures(const ScreenLineString& geometry, diff --git a/src/mbgl/renderer/render_style.cpp b/src/mbgl/renderer/render_style.cpp index 91efb6c737..bae879dca7 100644 --- a/src/mbgl/renderer/render_style.cpp +++ b/src/mbgl/renderer/render_style.cpp @@ -309,16 +309,12 @@ RenderData RenderStyle::getRenderData(MapDebugOptions debugOptions, float angle) continue; } - auto& renderTiles = source->getRenderTiles(); const bool symbolLayer = layer->is(); - // Sort symbol tiles in opposite y position, so tiles with overlapping - // symbols are drawn on top of each other, with lower symbols being - // drawn on top of higher symbols. - std::vector> sortedTiles; - std::transform(renderTiles.begin(), renderTiles.end(), std::back_inserter(sortedTiles), - [](auto& pair) { return std::ref(pair.second); }); + auto sortedTiles = source->getRenderTiles(); if (symbolLayer) { + // Sort symbol tiles in opposite y position, so tiles with overlapping symbols are drawn + // on top of each other, with lower symbols being drawn on top of higher symbols. std::sort(sortedTiles.begin(), sortedTiles.end(), [angle](const RenderTile& a, const RenderTile& b) { Point pa(a.id.canonical.x, a.id.canonical.y); diff --git a/src/mbgl/renderer/render_tile.hpp b/src/mbgl/renderer/render_tile.hpp index 6677278873..07e2d699f7 100644 --- a/src/mbgl/renderer/render_tile.hpp +++ b/src/mbgl/renderer/render_tile.hpp @@ -13,7 +13,7 @@ class Tile; class TransformState; class Painter; -class RenderTile { +class RenderTile final { public: RenderTile(UnwrappedTileID id_, Tile& tile_) : id(std::move(id_)), tile(tile_) {} RenderTile(const RenderTile&) = delete; diff --git a/src/mbgl/renderer/sources/render_geojson_source.cpp b/src/mbgl/renderer/sources/render_geojson_source.cpp index 2c6935b273..c45a62498d 100644 --- a/src/mbgl/renderer/sources/render_geojson_source.cpp +++ b/src/mbgl/renderer/sources/render_geojson_source.cpp @@ -68,7 +68,7 @@ void RenderGeoJSONSource::finishRender(Painter& painter) { tilePyramid.finishRender(painter); } -std::map& RenderGeoJSONSource::getRenderTiles() { +std::vector> RenderGeoJSONSource::getRenderTiles() { return tilePyramid.getRenderTiles(); } diff --git a/src/mbgl/renderer/sources/render_geojson_source.hpp b/src/mbgl/renderer/sources/render_geojson_source.hpp index b7c5a3fa7f..8d4154112f 100644 --- a/src/mbgl/renderer/sources/render_geojson_source.hpp +++ b/src/mbgl/renderer/sources/render_geojson_source.hpp @@ -25,7 +25,7 @@ public: void startRender(Painter&) final; void finishRender(Painter&) final; - std::map& getRenderTiles() final; + std::vector> getRenderTiles() final; std::unordered_map> queryRenderedFeatures(const ScreenLineString& geometry, diff --git a/src/mbgl/renderer/sources/render_image_source.hpp b/src/mbgl/renderer/sources/render_image_source.hpp index 88f1c56567..41c4bd5483 100644 --- a/src/mbgl/renderer/sources/render_image_source.hpp +++ b/src/mbgl/renderer/sources/render_image_source.hpp @@ -30,8 +30,8 @@ public: bool needsRelayout, const TileParameters&) final; - std::map& getRenderTiles() final { - return tiles; + std::vector> getRenderTiles() final { + return {}; } std::unordered_map> @@ -48,7 +48,6 @@ public: private: const style::ImageSource::Impl& impl() const; - std::map tiles; std::vector tileIds; std::unique_ptr bucket; diff --git a/src/mbgl/renderer/sources/render_raster_source.cpp b/src/mbgl/renderer/sources/render_raster_source.cpp index 20c148870e..2006e31628 100644 --- a/src/mbgl/renderer/sources/render_raster_source.cpp +++ b/src/mbgl/renderer/sources/render_raster_source.cpp @@ -64,7 +64,7 @@ void RenderRasterSource::finishRender(Painter& painter) { tilePyramid.finishRender(painter); } -std::map& RenderRasterSource::getRenderTiles() { +std::vector> RenderRasterSource::getRenderTiles() { return tilePyramid.getRenderTiles(); } diff --git a/src/mbgl/renderer/sources/render_raster_source.hpp b/src/mbgl/renderer/sources/render_raster_source.hpp index 7d0c245e45..73a2ac3b22 100644 --- a/src/mbgl/renderer/sources/render_raster_source.hpp +++ b/src/mbgl/renderer/sources/render_raster_source.hpp @@ -21,7 +21,7 @@ public: void startRender(Painter&) final; void finishRender(Painter&) final; - std::map& getRenderTiles() final; + std::vector> getRenderTiles() final; std::unordered_map> queryRenderedFeatures(const ScreenLineString& geometry, diff --git a/src/mbgl/renderer/sources/render_vector_source.cpp b/src/mbgl/renderer/sources/render_vector_source.cpp index 4302fb21ee..0f44a64b63 100644 --- a/src/mbgl/renderer/sources/render_vector_source.cpp +++ b/src/mbgl/renderer/sources/render_vector_source.cpp @@ -69,7 +69,7 @@ void RenderVectorSource::finishRender(Painter& painter) { tilePyramid.finishRender(painter); } -std::map& RenderVectorSource::getRenderTiles() { +std::vector> RenderVectorSource::getRenderTiles() { return tilePyramid.getRenderTiles(); } diff --git a/src/mbgl/renderer/sources/render_vector_source.hpp b/src/mbgl/renderer/sources/render_vector_source.hpp index 5e15fee533..231a9071ab 100644 --- a/src/mbgl/renderer/sources/render_vector_source.hpp +++ b/src/mbgl/renderer/sources/render_vector_source.hpp @@ -21,7 +21,7 @@ public: void startRender(Painter&) final; void finishRender(Painter&) final; - std::map& getRenderTiles() final; + std::vector> getRenderTiles() final; std::unordered_map> queryRenderedFeatures(const ScreenLineString& geometry, diff --git a/src/mbgl/renderer/tile_pyramid.cpp b/src/mbgl/renderer/tile_pyramid.cpp index c2806299e3..caf55d64e8 100644 --- a/src/mbgl/renderer/tile_pyramid.cpp +++ b/src/mbgl/renderer/tile_pyramid.cpp @@ -40,22 +40,21 @@ bool TilePyramid::isLoaded() const { } void TilePyramid::startRender(Painter& painter) { - for (auto& pair : renderTiles) { - pair.second.startRender(painter); + for (auto& tile : renderTiles) { + tile.startRender(painter); } } void TilePyramid::finishRender(Painter& painter) { - for (auto& pair : renderTiles) { - auto& tile = pair.second; + for (auto& tile : renderTiles) { if (tile.used) { painter.renderTileDebug(tile); } } } -std::map& TilePyramid::getRenderTiles() { - return renderTiles; +std::vector> TilePyramid::getRenderTiles() { + return { renderTiles.begin(), renderTiles.end() }; } void TilePyramid::update(const std::vector>& layers, @@ -134,7 +133,7 @@ void TilePyramid::update(const std::vector>& layer return tiles.emplace(tileID, std::move(tile)).first->second.get(); }; auto renderTileFn = [&](const UnwrappedTileID& tileID, Tile& tile) { - renderTiles.emplace(tileID, RenderTile{ tileID, tile }); + renderTiles.emplace_back(tileID, tile); }; renderTiles.clear(); @@ -199,18 +198,14 @@ std::unordered_map> TilePyramid::queryRendered mapbox::geometry::box box = mapbox::geometry::envelope(queryGeometry); - - auto sortRenderTiles = [](const RenderTile& a, const RenderTile& b) { + std::vector> sortedTiles{ renderTiles.begin(), + renderTiles.end() }; + std::sort(sortedTiles.begin(), sortedTiles.end(), [](const RenderTile& a, const RenderTile& b) { return std::tie(a.id.canonical.z, a.id.canonical.y, a.id.wrap, a.id.canonical.x) < std::tie(b.id.canonical.z, b.id.canonical.y, b.id.wrap, b.id.canonical.x); - }; - std::vector> sortedTiles; - std::transform(renderTiles.cbegin(), renderTiles.cend(), std::back_inserter(sortedTiles), - [](const auto& pair) { return std::ref(pair.second); }); - std::sort(sortedTiles.begin(), sortedTiles.end(), sortRenderTiles); + }); - for (const auto& renderTileRef : sortedTiles) { - const RenderTile& renderTile = renderTileRef.get(); + for (const RenderTile& renderTile : sortedTiles) { GeometryCoordinate tileSpaceBoundsMin = TileCoordinate::toGeometryCoordinate(renderTile.id, box.min); if (tileSpaceBoundsMin.x >= util::EXTENT || tileSpaceBoundsMin.y >= util::EXTENT) { continue; diff --git a/src/mbgl/renderer/tile_pyramid.hpp b/src/mbgl/renderer/tile_pyramid.hpp index 5846560808..a3db65b460 100644 --- a/src/mbgl/renderer/tile_pyramid.hpp +++ b/src/mbgl/renderer/tile_pyramid.hpp @@ -45,7 +45,7 @@ public: void startRender(Painter&); void finishRender(Painter&); - std::map& getRenderTiles(); + std::vector> getRenderTiles(); std::unordered_map> queryRenderedFeatures(const ScreenLineString& geometry, @@ -68,7 +68,7 @@ public: std::map> tiles; TileCache cache; - std::map renderTiles; + std::vector renderTiles; TileObserver* observer = nullptr; }; diff --git a/test/algorithm/generate_clip_ids.test.cpp b/test/algorithm/generate_clip_ids.test.cpp index 8ca0191b3a..730dc7b7f3 100644 --- a/test/algorithm/generate_clip_ids.test.cpp +++ b/test/algorithm/generate_clip_ids.test.cpp @@ -5,6 +5,7 @@ using namespace mbgl; struct Renderable { + UnwrappedTileID id; ClipID clip; bool used = true; @@ -14,59 +15,28 @@ struct Renderable { }; ::std::ostream& operator<<(::std::ostream& os, const Renderable& rhs) { - return os << "ClipID(" << rhs.clip << ")"; + return os << "Renderable{ " << rhs.id << ", " << rhs.clip << " }"; } -namespace { - -// void print(const std::map& renderables) { -// std::cout << " EXPECT_EQ(decltype(renderables)({" << std::endl; -// for (auto& pair : renderables) { -// std::cout << " { UnwrappedTileID{ " << int(pair.first.canonical.z) << ", " -// << (int64_t(pair.first.canonical.x) + -// pair.first.wrap * (1ll << pair.first.canonical.z)) -// << ", " << pair.first.canonical.y << " }, Renderable{ ClipID{ \"" -// << pair.second.clip.mask << "\", \"" << pair.second.clip.reference << "\" } } }," -// << std::endl; -// } -// std::cout << " })," << std::endl; -// std::cout << " renderables);" << std::endl; -// } - -// void print(const std::map& stencils) { -// std::cout << " EXPECT_EQ(decltype(stencils)({" << std::endl; -// for (auto& pair : stencils) { -// std::cout << " { UnwrappedTileID{ " << int(pair.first.canonical.z) << ", " -// << (int64_t(pair.first.canonical.x) + -// pair.first.wrap * (1ll << pair.first.canonical.z)) -// << ", " << pair.first.canonical.y << " }, ClipID{ \"" << pair.second.mask -// << "\", \"" << pair.second.reference << "\" } }," << std::endl; -// } -// std::cout << " })," << std::endl; -// std::cout << " stencils);" << std::endl; -// } - -} // end namespace - TEST(GenerateClipIDs, ParentAndFourChildren) { - std::map renderables{ - { UnwrappedTileID{ 0, 0, 0 }, Renderable{ {} } }, + std::vector renderables{ + Renderable{ UnwrappedTileID{ 0, 0, 0 }, {} }, // All four covering children - { UnwrappedTileID{ 1, 0, 0 }, Renderable{ {} } }, - { UnwrappedTileID{ 1, 0, 1 }, Renderable{ {} } }, - { UnwrappedTileID{ 1, 1, 0 }, Renderable{ {} } }, - { UnwrappedTileID{ 1, 1, 1 }, Renderable{ {} } }, + Renderable{ UnwrappedTileID{ 1, 0, 0 }, {} }, + Renderable{ UnwrappedTileID{ 1, 0, 1 }, {} }, + Renderable{ UnwrappedTileID{ 1, 1, 0 }, {} }, + Renderable{ UnwrappedTileID{ 1, 1, 1 }, {} }, }; algorithm::ClipIDGenerator generator; - generator.update(renderables); + generator.update({ renderables.begin(), renderables.end() }); EXPECT_EQ(decltype(renderables)({ - { UnwrappedTileID{ 0, 0, 0 }, Renderable{ ClipID{ "00000111", "00000001" } } }, - { UnwrappedTileID{ 1, 0, 0 }, Renderable{ ClipID{ "00000111", "00000010" } } }, - { UnwrappedTileID{ 1, 0, 1 }, Renderable{ ClipID{ "00000111", "00000011" } } }, - { UnwrappedTileID{ 1, 1, 0 }, Renderable{ ClipID{ "00000111", "00000100" } } }, - { UnwrappedTileID{ 1, 1, 1 }, Renderable{ ClipID{ "00000111", "00000101" } } }, + Renderable{ UnwrappedTileID{ 0, 0, 0 }, ClipID{ "00000111", "00000001" } }, + Renderable{ UnwrappedTileID{ 1, 0, 0 }, ClipID{ "00000111", "00000010" } }, + Renderable{ UnwrappedTileID{ 1, 0, 1 }, ClipID{ "00000111", "00000011" } }, + Renderable{ UnwrappedTileID{ 1, 1, 0 }, ClipID{ "00000111", "00000100" } }, + Renderable{ UnwrappedTileID{ 1, 1, 1 }, ClipID{ "00000111", "00000101" } }, }), renderables); @@ -82,23 +52,23 @@ TEST(GenerateClipIDs, ParentAndFourChildren) { } TEST(GenerateClipIDs, ParentAndFourChildrenNegative) { - std::map renderables{ - { UnwrappedTileID{ 1, -2, 0 }, Renderable{ {} } }, - { UnwrappedTileID{ 1, -2, 1 }, Renderable{ {} } }, - { UnwrappedTileID{ 1, -1, 0 }, Renderable{ {} } }, - { UnwrappedTileID{ 1, -1, 1 }, Renderable{ {} } }, - { UnwrappedTileID{ 0, -1, 0 }, Renderable{ {} } }, + std::vector renderables{ + Renderable{ UnwrappedTileID{ 1, -2, 0 }, {} }, + Renderable{ UnwrappedTileID{ 1, -2, 1 }, {} }, + Renderable{ UnwrappedTileID{ 1, -1, 0 }, {} }, + Renderable{ UnwrappedTileID{ 1, -1, 1 }, {} }, + Renderable{ UnwrappedTileID{ 0, -1, 0 }, {} }, }; algorithm::ClipIDGenerator generator; - generator.update(renderables); + generator.update({ renderables.begin(), renderables.end() }); EXPECT_EQ(decltype(renderables)({ - { UnwrappedTileID{ 0, -1, 0 }, Renderable{ ClipID{ "00000111", "00000001" } } }, - { UnwrappedTileID{ 1, -2, 0 }, Renderable{ ClipID{ "00000111", "00000010" } } }, - { UnwrappedTileID{ 1, -2, 1 }, Renderable{ ClipID{ "00000111", "00000011" } } }, - { UnwrappedTileID{ 1, -1, 0 }, Renderable{ ClipID{ "00000111", "00000100" } } }, - { UnwrappedTileID{ 1, -1, 1 }, Renderable{ ClipID{ "00000111", "00000101" } } }, + Renderable{ UnwrappedTileID{ 1, -2, 0 }, ClipID{ "00000111", "00000010" } }, + Renderable{ UnwrappedTileID{ 1, -2, 1 }, ClipID{ "00000111", "00000011" } }, + Renderable{ UnwrappedTileID{ 1, -1, 0 }, ClipID{ "00000111", "00000100" } }, + Renderable{ UnwrappedTileID{ 1, -1, 1 }, ClipID{ "00000111", "00000101" } }, + Renderable{ UnwrappedTileID{ 0, -1, 0 }, ClipID{ "00000111", "00000001" } }, }), renderables); @@ -113,23 +83,23 @@ TEST(GenerateClipIDs, ParentAndFourChildrenNegative) { } TEST(GenerateClipIDs, NegativeParentAndMissingLevel) { - std::map renderables{ - { UnwrappedTileID{ 1, -1, 0 }, Renderable{ {} } }, - { UnwrappedTileID{ 2, -1, 0 }, Renderable{ {} } }, - { UnwrappedTileID{ 2, -2, 1 }, Renderable{ {} } }, - { UnwrappedTileID{ 2, -1, 1 }, Renderable{ {} } }, - { UnwrappedTileID{ 2, -2, 0 }, Renderable{ {} } }, + std::vector renderables{ + Renderable{ UnwrappedTileID{ 1, -1, 0 }, {} }, + Renderable{ UnwrappedTileID{ 2, -1, 0 }, {} }, + Renderable{ UnwrappedTileID{ 2, -2, 1 }, {} }, + Renderable{ UnwrappedTileID{ 2, -1, 1 }, {} }, + Renderable{ UnwrappedTileID{ 2, -2, 0 }, {} }, }; algorithm::ClipIDGenerator generator; - generator.update(renderables); + generator.update({ renderables.begin(), renderables.end() }); EXPECT_EQ(decltype(renderables)({ - { UnwrappedTileID{ 1, -1, 0 }, Renderable{ ClipID{ "00000111", "00000001" } } }, - { UnwrappedTileID{ 2, -2, 0 }, Renderable{ ClipID{ "00000111", "00000010" } } }, - { UnwrappedTileID{ 2, -2, 1 }, Renderable{ ClipID{ "00000111", "00000011" } } }, - { UnwrappedTileID{ 2, -1, 0 }, Renderable{ ClipID{ "00000111", "00000100" } } }, - { UnwrappedTileID{ 2, -1, 1 }, Renderable{ ClipID{ "00000111", "00000101" } } }, + Renderable{ UnwrappedTileID{ 1, -1, 0 }, ClipID{ "00000111", "00000001" } }, + Renderable{ UnwrappedTileID{ 2, -1, 0 }, ClipID{ "00000111", "00000100" } }, + Renderable{ UnwrappedTileID{ 2, -2, 1 }, ClipID{ "00000111", "00000011" } }, + Renderable{ UnwrappedTileID{ 2, -1, 1 }, ClipID{ "00000111", "00000101" } }, + Renderable{ UnwrappedTileID{ 2, -2, 0 }, ClipID{ "00000111", "00000010" } }, }), renderables); @@ -144,29 +114,29 @@ TEST(GenerateClipIDs, NegativeParentAndMissingLevel) { } TEST(GenerateClipIDs, SevenOnSameLevel) { - std::map renderables{ + std::vector renderables{ // first column - { UnwrappedTileID{ 2, 0, 0 }, Renderable{ {} } }, - { UnwrappedTileID{ 2, 0, 1 }, Renderable{ {} } }, - { UnwrappedTileID{ 2, 0, 2 }, Renderable{ {} } }, + Renderable{ UnwrappedTileID{ 2, 0, 0 }, {} }, + Renderable{ UnwrappedTileID{ 2, 0, 1 }, {} }, + Renderable{ UnwrappedTileID{ 2, 0, 2 }, {} }, // second column - { UnwrappedTileID{ 2, 1, 0 }, Renderable{ {} } }, - { UnwrappedTileID{ 2, 1, 1 }, Renderable{ {} } }, - { UnwrappedTileID{ 2, 1, 2 }, Renderable{ {} } }, + Renderable{ UnwrappedTileID{ 2, 1, 0 }, {} }, + Renderable{ UnwrappedTileID{ 2, 1, 1 }, {} }, + Renderable{ UnwrappedTileID{ 2, 1, 2 }, {} }, // third column - { UnwrappedTileID{ 2, 2, 0 }, Renderable{ {} } }, + Renderable{ UnwrappedTileID{ 2, 2, 0 }, {} }, }; algorithm::ClipIDGenerator generator; - generator.update(renderables); + generator.update({ renderables.begin(), renderables.end() }); EXPECT_EQ(decltype(renderables)({ - { UnwrappedTileID{ 2, 0, 0 }, Renderable{ ClipID{ "00000111", "00000001" } } }, - { UnwrappedTileID{ 2, 0, 1 }, Renderable{ ClipID{ "00000111", "00000010" } } }, - { UnwrappedTileID{ 2, 0, 2 }, Renderable{ ClipID{ "00000111", "00000011" } } }, - { UnwrappedTileID{ 2, 1, 0 }, Renderable{ ClipID{ "00000111", "00000100" } } }, - { UnwrappedTileID{ 2, 1, 1 }, Renderable{ ClipID{ "00000111", "00000101" } } }, - { UnwrappedTileID{ 2, 1, 2 }, Renderable{ ClipID{ "00000111", "00000110" } } }, - { UnwrappedTileID{ 2, 2, 0 }, Renderable{ ClipID{ "00000111", "00000111" } } }, + Renderable{ UnwrappedTileID{ 2, 0, 0 }, ClipID{ "00000111", "00000001" } }, + Renderable{ UnwrappedTileID{ 2, 0, 1 }, ClipID{ "00000111", "00000010" } }, + Renderable{ UnwrappedTileID{ 2, 0, 2 }, ClipID{ "00000111", "00000011" } }, + Renderable{ UnwrappedTileID{ 2, 1, 0 }, ClipID{ "00000111", "00000100" } }, + Renderable{ UnwrappedTileID{ 2, 1, 1 }, ClipID{ "00000111", "00000101" } }, + Renderable{ UnwrappedTileID{ 2, 1, 2 }, ClipID{ "00000111", "00000110" } }, + Renderable{ UnwrappedTileID{ 2, 2, 0 }, ClipID{ "00000111", "00000111" } }, }), renderables); @@ -184,42 +154,42 @@ TEST(GenerateClipIDs, SevenOnSameLevel) { } TEST(GenerateClipIDs, MultipleLevels) { - std::map renderables{ - { UnwrappedTileID{ 2, 0, 0 }, Renderable{ {} } }, + std::vector renderables{ + Renderable{ UnwrappedTileID{ 2, 0, 0 }, {} }, // begin subtiles of (2/0/0) - { UnwrappedTileID{ 3, 0, 0 }, Renderable{ {} } }, - { UnwrappedTileID{ 3, 0, 1 }, Renderable{ {} } }, + Renderable{ UnwrappedTileID{ 3, 0, 0 }, {} }, + Renderable{ UnwrappedTileID{ 3, 0, 1 }, {} }, // begin subtiles of (3/0/1) - { UnwrappedTileID{ 4, 0, 2 }, Renderable{ {} } }, - { UnwrappedTileID{ 4, 1, 2 }, Renderable{ {} } }, - { UnwrappedTileID{ 4, 0, 3 }, Renderable{ {} } }, - { UnwrappedTileID{ 4, 1, 3 }, Renderable{ {} } }, + Renderable{ UnwrappedTileID{ 4, 0, 2 }, {} }, + Renderable{ UnwrappedTileID{ 4, 1, 2 }, {} }, + Renderable{ UnwrappedTileID{ 4, 0, 3 }, {} }, + Renderable{ UnwrappedTileID{ 4, 1, 3 }, {} }, // end subtiles of (3/0/1) - { UnwrappedTileID{ 3, 1, 0 }, Renderable{ {} } }, - { UnwrappedTileID{ 3, 1, 1 }, Renderable{ {} } }, + Renderable{ UnwrappedTileID{ 3, 1, 0 }, {} }, + Renderable{ UnwrappedTileID{ 3, 1, 1 }, {} }, // end subtiles of (2/0/0) - { UnwrappedTileID{ 2, 1, 0 }, Renderable{ {} } }, + Renderable{ UnwrappedTileID{ 2, 1, 0 }, {} }, // begin subtiles of (2/1/0) - { UnwrappedTileID{ 3, 2, 0 }, Renderable{ {} } }, - { UnwrappedTileID{ 3, 2, 1 }, Renderable{ {} } }, + Renderable{ UnwrappedTileID{ 3, 2, 0 }, {} }, + Renderable{ UnwrappedTileID{ 3, 2, 1 }, {} }, // end subtiles of (2/1/0) }; algorithm::ClipIDGenerator generator; - generator.update(renderables); + generator.update({ renderables.begin(), renderables.end() }); ASSERT_EQ(decltype(renderables)({ - { UnwrappedTileID{ 2, 0, 0 }, Renderable{ ClipID{ "00001111", "00000001" } } }, - { UnwrappedTileID{ 2, 1, 0 }, Renderable{ ClipID{ "00001111", "00000010" } } }, - { UnwrappedTileID{ 3, 0, 0 }, Renderable{ ClipID{ "00001111", "00000011" } } }, - { UnwrappedTileID{ 3, 0, 1 }, Renderable{ ClipID{ "00001111", "00000100" } } }, - { UnwrappedTileID{ 3, 1, 0 }, Renderable{ ClipID{ "00001111", "00000101" } } }, - { UnwrappedTileID{ 3, 1, 1 }, Renderable{ ClipID{ "00001111", "00000110" } } }, - { UnwrappedTileID{ 3, 2, 0 }, Renderable{ ClipID{ "00001111", "00000111" } } }, - { UnwrappedTileID{ 3, 2, 1 }, Renderable{ ClipID{ "00001111", "00001000" } } }, - { UnwrappedTileID{ 4, 0, 2 }, Renderable{ ClipID{ "00001111", "00001001" } } }, - { UnwrappedTileID{ 4, 0, 3 }, Renderable{ ClipID{ "00001111", "00001010" } } }, - { UnwrappedTileID{ 4, 1, 2 }, Renderable{ ClipID{ "00001111", "00001011" } } }, - { UnwrappedTileID{ 4, 1, 3 }, Renderable{ ClipID{ "00001111", "00001100" } } }, + Renderable{ UnwrappedTileID{ 2, 0, 0 }, ClipID{ "00001111", "00000001" } }, + Renderable{ UnwrappedTileID{ 3, 0, 0 }, ClipID{ "00001111", "00000011" } }, + Renderable{ UnwrappedTileID{ 3, 0, 1 }, ClipID{ "00001111", "00000100" } }, + Renderable{ UnwrappedTileID{ 4, 0, 2 }, ClipID{ "00001111", "00001001" } }, + Renderable{ UnwrappedTileID{ 4, 1, 2 }, ClipID{ "00001111", "00001011" } }, + Renderable{ UnwrappedTileID{ 4, 0, 3 }, ClipID{ "00001111", "00001010" } }, + Renderable{ UnwrappedTileID{ 4, 1, 3 }, ClipID{ "00001111", "00001100" } }, + Renderable{ UnwrappedTileID{ 3, 1, 0 }, ClipID{ "00001111", "00000101" } }, + Renderable{ UnwrappedTileID{ 3, 1, 1 }, ClipID{ "00001111", "00000110" } }, + Renderable{ UnwrappedTileID{ 2, 1, 0 }, ClipID{ "00001111", "00000010" } }, + Renderable{ UnwrappedTileID{ 3, 2, 0 }, ClipID{ "00001111", "00000111" } }, + Renderable{ UnwrappedTileID{ 3, 2, 1 }, ClipID{ "00001111", "00001000" } }, }), renderables); @@ -240,37 +210,37 @@ TEST(GenerateClipIDs, MultipleLevels) { } TEST(GenerateClipIDs, Bug206) { - std::map renderables{ - { UnwrappedTileID{ 10, 162, 395 }, Renderable{ {} } }, - { UnwrappedTileID{ 10, 162, 396 }, Renderable{ {} } }, - { UnwrappedTileID{ 10, 163, 395 }, Renderable{ {} } }, + std::vector renderables{ + Renderable{ UnwrappedTileID{ 10, 162, 395 }, {} }, + Renderable{ UnwrappedTileID{ 10, 162, 396 }, {} }, + Renderable{ UnwrappedTileID{ 10, 163, 395 }, {} }, // begin subtiles of (10/163/395) - { UnwrappedTileID{ 11, 326, 791 }, Renderable{ {} } }, - { UnwrappedTileID{ 12, 654, 1582 }, Renderable{ {} } }, - { UnwrappedTileID{ 12, 654, 1583 }, Renderable{ {} } }, - { UnwrappedTileID{ 12, 655, 1582 }, Renderable{ {} } }, - { UnwrappedTileID{ 12, 655, 1583 }, Renderable{ {} } }, + Renderable{ UnwrappedTileID{ 11, 326, 791 }, {} }, + Renderable{ UnwrappedTileID{ 12, 654, 1582 }, {} }, + Renderable{ UnwrappedTileID{ 12, 654, 1583 }, {} }, + Renderable{ UnwrappedTileID{ 12, 655, 1582 }, {} }, + Renderable{ UnwrappedTileID{ 12, 655, 1583 }, {} }, // end subtiles of (10/163/395) - { UnwrappedTileID{ 10, 163, 396 }, Renderable{ {} } }, - { UnwrappedTileID{ 10, 164, 395 }, Renderable{ {} } }, - { UnwrappedTileID{ 10, 164, 396 }, Renderable{ {} } }, + Renderable{ UnwrappedTileID{ 10, 163, 396 }, {} }, + Renderable{ UnwrappedTileID{ 10, 164, 395 }, {} }, + Renderable{ UnwrappedTileID{ 10, 164, 396 }, {} }, }; algorithm::ClipIDGenerator generator; - generator.update(renderables); + generator.update({ renderables.begin(), renderables.end() }); EXPECT_EQ( decltype(renderables)({ - { UnwrappedTileID{ 10, 162, 395 }, Renderable{ ClipID{ "00001111", "00000001" } } }, - { UnwrappedTileID{ 10, 162, 396 }, Renderable{ ClipID{ "00001111", "00000010" } } }, - { UnwrappedTileID{ 10, 163, 395 }, Renderable{ ClipID{ "00001111", "00000011" } } }, - { UnwrappedTileID{ 10, 163, 396 }, Renderable{ ClipID{ "00001111", "00000100" } } }, - { UnwrappedTileID{ 10, 164, 395 }, Renderable{ ClipID{ "00001111", "00000101" } } }, - { UnwrappedTileID{ 10, 164, 396 }, Renderable{ ClipID{ "00001111", "00000110" } } }, - { UnwrappedTileID{ 11, 326, 791 }, Renderable{ ClipID{ "00001111", "00000111" } } }, - { UnwrappedTileID{ 12, 654, 1582 }, Renderable{ ClipID{ "00001111", "00001000" } } }, - { UnwrappedTileID{ 12, 654, 1583 }, Renderable{ ClipID{ "00001111", "00001001" } } }, - { UnwrappedTileID{ 12, 655, 1582 }, Renderable{ ClipID{ "00001111", "00001010" } } }, - { UnwrappedTileID{ 12, 655, 1583 }, Renderable{ ClipID{ "00001111", "00001011" } } }, + Renderable{ UnwrappedTileID{ 10, 162, 395 }, ClipID{ "00001111", "00000001" } }, + Renderable{ UnwrappedTileID{ 10, 162, 396 }, ClipID{ "00001111", "00000010" } }, + Renderable{ UnwrappedTileID{ 10, 163, 395 }, ClipID{ "00001111", "00000011" } }, + Renderable{ UnwrappedTileID{ 11, 326, 791 }, ClipID{ "00001111", "00000111" } }, + Renderable{ UnwrappedTileID{ 12, 654, 1582 }, ClipID{ "00001111", "00001000" } }, + Renderable{ UnwrappedTileID{ 12, 654, 1583 }, ClipID{ "00001111", "00001001" } }, + Renderable{ UnwrappedTileID{ 12, 655, 1582 }, ClipID{ "00001111", "00001010" } }, + Renderable{ UnwrappedTileID{ 12, 655, 1583 }, ClipID{ "00001111", "00001011" } }, + Renderable{ UnwrappedTileID{ 10, 163, 396 }, ClipID{ "00001111", "00000100" } }, + Renderable{ UnwrappedTileID{ 10, 164, 395 }, ClipID{ "00001111", "00000101" } }, + Renderable{ UnwrappedTileID{ 10, 164, 396 }, ClipID{ "00001111", "00000110" } }, }), renderables); @@ -292,53 +262,53 @@ TEST(GenerateClipIDs, Bug206) { } TEST(GenerateClipIDs, MultipleSources) { - std::map renderables1{ - { UnwrappedTileID{ 0, 0, 0 }, Renderable{ {} } }, - { UnwrappedTileID{ 1, 1, 1 }, Renderable{ {} } }, + std::vector renderables1{ + Renderable{ UnwrappedTileID{ 0, 0, 0 }, {} }, + Renderable{ UnwrappedTileID{ 1, 1, 1 }, {} }, // Differing children - { UnwrappedTileID{ 2, 2, 1 }, Renderable{ {} } }, - { UnwrappedTileID{ 2, 2, 2 }, Renderable{ {} } }, + Renderable{ UnwrappedTileID{ 2, 2, 1 }, {} }, + Renderable{ UnwrappedTileID{ 2, 2, 2 }, {} }, }; - std::map renderables2{ - { UnwrappedTileID{ 0, 0, 0 }, Renderable{ {} } }, - { UnwrappedTileID{ 1, 1, 1 }, Renderable{ {} } }, + std::vector renderables2{ + Renderable{ UnwrappedTileID{ 0, 0, 0 }, {} }, + Renderable{ UnwrappedTileID{ 1, 1, 1 }, {} }, // Differing children - { UnwrappedTileID{ 2, 1, 1 }, Renderable{ {} } }, - { UnwrappedTileID{ 2, 2, 2 }, Renderable{ {} } }, + Renderable{ UnwrappedTileID{ 2, 1, 1 }, {} }, + Renderable{ UnwrappedTileID{ 2, 2, 2 }, {} }, }; - std::map renderables3{ - { UnwrappedTileID{ 1, 0, 0 }, Renderable{ {} } }, - { UnwrappedTileID{ 1, 0, 1 }, Renderable{ {} } }, - { UnwrappedTileID{ 1, 1, 0 }, Renderable{ {} } }, - { UnwrappedTileID{ 1, 1, 1 }, Renderable{ {} } }, + std::vector renderables3{ + Renderable{ UnwrappedTileID{ 1, 0, 0 }, {} }, + Renderable{ UnwrappedTileID{ 1, 0, 1 }, {} }, + Renderable{ UnwrappedTileID{ 1, 1, 0 }, {} }, + Renderable{ UnwrappedTileID{ 1, 1, 1 }, {} }, // Differing children - { UnwrappedTileID{ 2, 1, 1 }, Renderable{ {} } }, + Renderable{ UnwrappedTileID{ 2, 1, 1 }, {} }, }; algorithm::ClipIDGenerator generator; - generator.update(renderables1); - generator.update(renderables2); - generator.update(renderables3); + generator.update({ renderables1.begin(), renderables1.end() }); + generator.update({ renderables2.begin(), renderables2.end() }); + generator.update({ renderables3.begin(), renderables3.end() }); EXPECT_EQ(decltype(renderables1)({ - { UnwrappedTileID{ 0, 0, 0 }, Renderable{ ClipID{ "00000111", "00000001" } } }, - { UnwrappedTileID{ 1, 1, 1 }, Renderable{ ClipID{ "00000111", "00000010" } } }, - { UnwrappedTileID{ 2, 2, 1 }, Renderable{ ClipID{ "00000111", "00000011" } } }, - { UnwrappedTileID{ 2, 2, 2 }, Renderable{ ClipID{ "00000111", "00000100" } } }, + Renderable{ UnwrappedTileID{ 0, 0, 0 }, ClipID{ "00000111", "00000001" } }, + Renderable{ UnwrappedTileID{ 1, 1, 1 }, ClipID{ "00000111", "00000010" } }, + Renderable{ UnwrappedTileID{ 2, 2, 1 }, ClipID{ "00000111", "00000011" } }, + Renderable{ UnwrappedTileID{ 2, 2, 2 }, ClipID{ "00000111", "00000100" } }, }), renderables1); EXPECT_EQ(decltype(renderables2)({ - { UnwrappedTileID{ 0, 0, 0 }, Renderable{ ClipID{ "00011000", "00001000" } } }, - { UnwrappedTileID{ 1, 1, 1 }, Renderable{ ClipID{ "00011111", "00000010" } } }, - { UnwrappedTileID{ 2, 1, 1 }, Renderable{ ClipID{ "00011000", "00010000" } } }, - { UnwrappedTileID{ 2, 2, 2 }, Renderable{ ClipID{ "00011111", "00000100" } } }, + Renderable{ UnwrappedTileID{ 0, 0, 0 }, ClipID{ "00011000", "00001000" } }, + Renderable{ UnwrappedTileID{ 1, 1, 1 }, ClipID{ "00011111", "00000010" } }, + Renderable{ UnwrappedTileID{ 2, 1, 1 }, ClipID{ "00011000", "00010000" } }, + Renderable{ UnwrappedTileID{ 2, 2, 2 }, ClipID{ "00011111", "00000100" } }, }), renderables2); EXPECT_EQ(decltype(renderables3)({ - { UnwrappedTileID{ 1, 0, 0 }, Renderable{ ClipID{ "11100000", "00100000" } } }, - { UnwrappedTileID{ 1, 0, 1 }, Renderable{ ClipID{ "11100000", "01000000" } } }, - { UnwrappedTileID{ 1, 1, 0 }, Renderable{ ClipID{ "11100000", "01100000" } } }, - { UnwrappedTileID{ 1, 1, 1 }, Renderable{ ClipID{ "11100000", "10000000" } } }, - { UnwrappedTileID{ 2, 1, 1 }, Renderable{ ClipID{ "11111000", "00010000" } } }, + Renderable{ UnwrappedTileID{ 1, 0, 0 }, ClipID{ "11100000", "00100000" } }, + Renderable{ UnwrappedTileID{ 1, 0, 1 }, ClipID{ "11100000", "01000000" } }, + Renderable{ UnwrappedTileID{ 1, 1, 0 }, ClipID{ "11100000", "01100000" } }, + Renderable{ UnwrappedTileID{ 1, 1, 1 }, ClipID{ "11100000", "10000000" } }, + Renderable{ UnwrappedTileID{ 2, 1, 1 }, ClipID{ "11111000", "00010000" } }, }), renderables3); @@ -356,27 +326,28 @@ TEST(GenerateClipIDs, MultipleSources) { } TEST(GenerateClipIDs, DuplicateIDs) { - std::map renderables1{ - { UnwrappedTileID{ 2, 0, 0 }, Renderable{ {} } }, - { UnwrappedTileID{ 2, 0, 1 }, Renderable{ {} } }, + std::vector renderables1{ + Renderable{ UnwrappedTileID{ 2, 0, 0 }, {} }, + Renderable{ UnwrappedTileID{ 2, 0, 1 }, {} }, }; - std::map renderables2{ - { UnwrappedTileID{ 2, 0, 0 }, Renderable{ {} } }, - { UnwrappedTileID{ 2, 0, 1 }, Renderable{ {} } }, - { UnwrappedTileID{ 2, 0, 1 }, Renderable{ {} } }, + std::vector renderables2{ + Renderable{ UnwrappedTileID{ 2, 0, 0 }, {} }, + Renderable{ UnwrappedTileID{ 2, 0, 1 }, {} }, + Renderable{ UnwrappedTileID{ 2, 0, 1 }, {} }, }; algorithm::ClipIDGenerator generator; - generator.update(renderables1); - generator.update(renderables2); + generator.update({ renderables1.begin(), renderables1.end() }); + generator.update({ renderables2.begin(), renderables2.end() }); EXPECT_EQ(decltype(renderables1)({ - { UnwrappedTileID{ 2, 0, 0 }, Renderable{ ClipID{ "00000011", "00000001" } } }, - { UnwrappedTileID{ 2, 0, 1 }, Renderable{ ClipID{ "00000011", "00000010" } } }, + Renderable{ UnwrappedTileID{ 2, 0, 0 }, ClipID{ "00000011", "00000001" } }, + Renderable{ UnwrappedTileID{ 2, 0, 1 }, ClipID{ "00000011", "00000010" } }, }), renderables1); EXPECT_EQ(decltype(renderables2)({ - { UnwrappedTileID{ 2, 0, 0 }, Renderable{ ClipID{ "00000011", "00000001" } } }, - { UnwrappedTileID{ 2, 0, 1 }, Renderable{ ClipID{ "00000011", "00000010" } } }, + Renderable{ UnwrappedTileID{ 2, 0, 0 }, ClipID{ "00000011", "00000001" } }, + Renderable{ UnwrappedTileID{ 2, 0, 1 }, ClipID{ "00000011", "00000010" } }, + Renderable{ UnwrappedTileID{ 2, 0, 1 }, ClipID{ "00000011", "00000010" } }, }), renderables2); @@ -389,33 +360,33 @@ TEST(GenerateClipIDs, DuplicateIDs) { } TEST(GenerateClipIDs, SecondSourceHasParentOfFirstSource) { - std::map renderables1{ - { UnwrappedTileID{ 1, 0, 0 }, Renderable{ {} } }, + std::vector renderables1{ + Renderable{ UnwrappedTileID{ 1, 0, 0 }, {} }, }; - std::map renderables2{ - { UnwrappedTileID{ 0, 0, 0 }, Renderable{ {} } }, + std::vector renderables2{ + Renderable{ UnwrappedTileID{ 0, 0, 0 }, {} }, // Same as in renderables1, but has a parent that it knocks out. - { UnwrappedTileID{ 1, 0, 0 }, Renderable{ {} } }, + Renderable{ UnwrappedTileID{ 1, 0, 0 }, {} }, }; - std::map renderables3{ - { UnwrappedTileID{ 0, 0, 0 }, Renderable{ {} } }, + std::vector renderables3{ + Renderable{ UnwrappedTileID{ 0, 0, 0 }, {} }, }; algorithm::ClipIDGenerator generator; - generator.update(renderables1); - generator.update(renderables2); - generator.update(renderables3); + generator.update({ renderables1.begin(), renderables1.end() }); + generator.update({ renderables2.begin(), renderables2.end() }); + generator.update({ renderables3.begin(), renderables3.end() }); EXPECT_EQ(decltype(renderables1)({ - { UnwrappedTileID{ 1, 0, 0 }, Renderable{ ClipID{ "00000001", "00000001" } } }, + Renderable{ UnwrappedTileID{ 1, 0, 0 }, ClipID{ "00000001", "00000001" } }, }), renderables1); EXPECT_EQ(decltype(renderables2)({ - { UnwrappedTileID{ 0, 0, 0 }, Renderable{ ClipID{ "00000010", "00000010" } } }, - { UnwrappedTileID{ 1, 0, 0 }, Renderable{ ClipID{ "00000011", "00000001" } } }, + Renderable{ UnwrappedTileID{ 0, 0, 0 }, ClipID{ "00000010", "00000010" } }, + Renderable{ UnwrappedTileID{ 1, 0, 0 }, ClipID{ "00000011", "00000001" } }, }), renderables2); EXPECT_EQ(decltype(renderables3)({ - { UnwrappedTileID{ 0, 0, 0 }, Renderable{ ClipID{ "00000100", "00000100" } } }, + Renderable{ UnwrappedTileID{ 0, 0, 0 }, ClipID{ "00000100", "00000100" } }, }), renderables3); -- cgit v1.2.1 From 107622a72ba6929bdd70e42d96c16b62c9f65dd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Tue, 4 Jul 2017 18:26:50 +0200 Subject: [core] don't use unordered_* collections for things we need to sort anyway --- src/mbgl/algorithm/generate_clip_ids.hpp | 8 ++++---- test/algorithm/generate_clip_ids.test.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mbgl/algorithm/generate_clip_ids.hpp b/src/mbgl/algorithm/generate_clip_ids.hpp index c4d332343b..8338c7c145 100644 --- a/src/mbgl/algorithm/generate_clip_ids.hpp +++ b/src/mbgl/algorithm/generate_clip_ids.hpp @@ -3,9 +3,9 @@ #include #include -#include +#include #include -#include +#include namespace mbgl { namespace algorithm { @@ -17,12 +17,12 @@ private: void add(const CanonicalTileID &p); bool operator==(const Leaf &other) const; - std::unordered_set children; + std::set children; ClipID& clip; }; uint8_t bit_offset = 0; - std::unordered_multimap pool; + std::multimap pool; public: template diff --git a/test/algorithm/generate_clip_ids.test.cpp b/test/algorithm/generate_clip_ids.test.cpp index 730dc7b7f3..404ab79912 100644 --- a/test/algorithm/generate_clip_ids.test.cpp +++ b/test/algorithm/generate_clip_ids.test.cpp @@ -10,7 +10,7 @@ struct Renderable { bool used = true; bool operator==(const Renderable& rhs) const { - return clip == rhs.clip; + return id == rhs.id && clip == rhs.clip; } }; -- cgit v1.2.1 From 64a827c3250dda0dd97189abf342e7d3c76fd006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Tue, 4 Jul 2017 18:31:37 +0200 Subject: [core] rename getStencils() to getClipIDs() to better reflect what it actually does --- src/mbgl/algorithm/generate_clip_ids.cpp | 16 ++++----- src/mbgl/algorithm/generate_clip_ids.hpp | 2 +- src/mbgl/renderer/painter.cpp | 6 ++-- test/algorithm/generate_clip_ids.test.cpp | 54 +++++++++++++++---------------- 4 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/mbgl/algorithm/generate_clip_ids.cpp b/src/mbgl/algorithm/generate_clip_ids.cpp index 74e0ee242f..287d2a408e 100644 --- a/src/mbgl/algorithm/generate_clip_ids.cpp +++ b/src/mbgl/algorithm/generate_clip_ids.cpp @@ -31,14 +31,14 @@ bool ClipIDGenerator::Leaf::operator==(const Leaf& other) const { return children == other.children; } -std::map ClipIDGenerator::getStencils() const { - std::map stencils; +std::map ClipIDGenerator::getClipIDs() const { + std::map clipIDs; // Merge everything. for (auto& pair : pool) { auto& id = pair.first; auto& leaf = pair.second; - auto res = stencils.emplace(id, leaf.clip); + auto res = clipIDs.emplace(id, leaf.clip); if (!res.second) { // Merge with the existing ClipID when there was already an element with the // same tile ID. @@ -46,14 +46,14 @@ std::map ClipIDGenerator::getStencils() const { } } - for (auto it = stencils.begin(); it != stencils.end(); ++it) { + for (auto it = clipIDs.begin(); it != clipIDs.end(); ++it) { auto& childId = it->first; auto& childClip = it->second; // Loop through all preceding stencils, and find all parents. for (auto parentIt = std::reverse_iterator(it); - parentIt != stencils.rend(); ++parentIt) { + parentIt != clipIDs.rend(); ++parentIt) { auto& parentId = parentIt->first; if (childId.isChildOf(parentId)) { // Once we have a parent, we add the bits that this ID hasn't set yet. @@ -66,11 +66,11 @@ std::map ClipIDGenerator::getStencils() const { } // Remove tiles that are entirely covered by children. - util::erase_if(stencils, [&](const auto& stencil) { - return algorithm::coveredByChildren(stencil.first, stencils); + util::erase_if(clipIDs, [&](const auto& stencil) { + return algorithm::coveredByChildren(stencil.first, clipIDs); }); - return stencils; + return clipIDs; } } // namespace algorithm diff --git a/src/mbgl/algorithm/generate_clip_ids.hpp b/src/mbgl/algorithm/generate_clip_ids.hpp index 8338c7c145..adcf87a72a 100644 --- a/src/mbgl/algorithm/generate_clip_ids.hpp +++ b/src/mbgl/algorithm/generate_clip_ids.hpp @@ -28,7 +28,7 @@ public: template void update(std::vector> renderables); - std::map getStencils() const; + std::map getClipIDs() const; }; } // namespace algorithm diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index 47db8254e2..a3decdb603 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -198,9 +198,9 @@ void Painter::render(RenderStyle& style, const FrameData& frame_, View& view) { MBGL_DEBUG_GROUP(context, "clipping masks"); - for (const auto& stencil : clipIDGenerator.getStencils()) { - MBGL_DEBUG_GROUP(context, std::string{ "mask: " } + util::toString(stencil.first)); - renderClippingMask(stencil.first, stencil.second); + for (const auto& clipID : clipIDGenerator.getClipIDs()) { + MBGL_DEBUG_GROUP(context, std::string{ "mask: " } + util::toString(clipID.first)); + renderClippingMask(clipID.first, clipID.second); } } diff --git a/test/algorithm/generate_clip_ids.test.cpp b/test/algorithm/generate_clip_ids.test.cpp index 404ab79912..46a577b994 100644 --- a/test/algorithm/generate_clip_ids.test.cpp +++ b/test/algorithm/generate_clip_ids.test.cpp @@ -40,15 +40,15 @@ TEST(GenerateClipIDs, ParentAndFourChildren) { }), renderables); - const auto stencils = generator.getStencils(); - EXPECT_EQ(decltype(stencils)({ + const auto clipIDs = generator.getClipIDs(); + EXPECT_EQ(decltype(clipIDs)({ // 0/0/0 is missing because it is covered by children. { UnwrappedTileID{ 1, 0, 0 }, ClipID{ "00000111", "00000010" } }, { UnwrappedTileID{ 1, 0, 1 }, ClipID{ "00000111", "00000011" } }, { UnwrappedTileID{ 1, 1, 0 }, ClipID{ "00000111", "00000100" } }, { UnwrappedTileID{ 1, 1, 1 }, ClipID{ "00000111", "00000101" } }, }), - stencils); + clipIDs); } TEST(GenerateClipIDs, ParentAndFourChildrenNegative) { @@ -72,14 +72,14 @@ TEST(GenerateClipIDs, ParentAndFourChildrenNegative) { }), renderables); - const auto stencils = generator.getStencils(); - EXPECT_EQ(decltype(stencils)({ + const auto clipIDs = generator.getClipIDs(); + EXPECT_EQ(decltype(clipIDs)({ { UnwrappedTileID{ 1, -2, 0 }, ClipID{ "00000111", "00000010" } }, { UnwrappedTileID{ 1, -2, 1 }, ClipID{ "00000111", "00000011" } }, { UnwrappedTileID{ 1, -1, 0 }, ClipID{ "00000111", "00000100" } }, { UnwrappedTileID{ 1, -1, 1 }, ClipID{ "00000111", "00000101" } }, }), - stencils); + clipIDs); } TEST(GenerateClipIDs, NegativeParentAndMissingLevel) { @@ -103,14 +103,14 @@ TEST(GenerateClipIDs, NegativeParentAndMissingLevel) { }), renderables); - const auto stencils = generator.getStencils(); - EXPECT_EQ(decltype(stencils)({ + const auto clipIDs = generator.getClipIDs(); + EXPECT_EQ(decltype(clipIDs)({ { UnwrappedTileID{ 2, -2, 0 }, ClipID{ "00000111", "00000010" } }, { UnwrappedTileID{ 2, -2, 1 }, ClipID{ "00000111", "00000011" } }, { UnwrappedTileID{ 2, -1, 0 }, ClipID{ "00000111", "00000100" } }, { UnwrappedTileID{ 2, -1, 1 }, ClipID{ "00000111", "00000101" } }, }), - stencils); + clipIDs); } TEST(GenerateClipIDs, SevenOnSameLevel) { @@ -140,8 +140,8 @@ TEST(GenerateClipIDs, SevenOnSameLevel) { }), renderables); - const auto stencils = generator.getStencils(); - EXPECT_EQ(decltype(stencils)({ + const auto clipIDs = generator.getClipIDs(); + EXPECT_EQ(decltype(clipIDs)({ { UnwrappedTileID{ 2, 0, 0 }, ClipID{ "00000111", "00000001" } }, { UnwrappedTileID{ 2, 0, 1 }, ClipID{ "00000111", "00000010" } }, { UnwrappedTileID{ 2, 0, 2 }, ClipID{ "00000111", "00000011" } }, @@ -150,7 +150,7 @@ TEST(GenerateClipIDs, SevenOnSameLevel) { { UnwrappedTileID{ 2, 1, 2 }, ClipID{ "00000111", "00000110" } }, { UnwrappedTileID{ 2, 2, 0 }, ClipID{ "00000111", "00000111" } }, }), - stencils); + clipIDs); } TEST(GenerateClipIDs, MultipleLevels) { @@ -193,8 +193,8 @@ TEST(GenerateClipIDs, MultipleLevels) { }), renderables); - const auto stencils = generator.getStencils(); - EXPECT_EQ(decltype(stencils)({ + const auto clipIDs = generator.getClipIDs(); + EXPECT_EQ(decltype(clipIDs)({ { UnwrappedTileID{ 2, 1, 0 }, ClipID{ "00001111", "00000010" } }, { UnwrappedTileID{ 3, 0, 0 }, ClipID{ "00001111", "00000011" } }, { UnwrappedTileID{ 3, 1, 0 }, ClipID{ "00001111", "00000101" } }, @@ -206,7 +206,7 @@ TEST(GenerateClipIDs, MultipleLevels) { { UnwrappedTileID{ 4, 1, 2 }, ClipID{ "00001111", "00001011" } }, { UnwrappedTileID{ 4, 1, 3 }, ClipID{ "00001111", "00001100" } }, }), - stencils); + clipIDs); } TEST(GenerateClipIDs, Bug206) { @@ -244,8 +244,8 @@ TEST(GenerateClipIDs, Bug206) { }), renderables); - const auto stencils = generator.getStencils(); - EXPECT_EQ(decltype(stencils)({ + const auto clipIDs = generator.getClipIDs(); + EXPECT_EQ(decltype(clipIDs)({ { UnwrappedTileID{ 10, 162, 395 }, ClipID{ "00001111", "00000001" } }, { UnwrappedTileID{ 10, 162, 396 }, ClipID{ "00001111", "00000010" } }, { UnwrappedTileID{ 10, 163, 395 }, ClipID{ "00001111", "00000011" } }, @@ -258,7 +258,7 @@ TEST(GenerateClipIDs, Bug206) { { UnwrappedTileID{ 12, 655, 1582 }, ClipID{ "00001111", "00001010" } }, { UnwrappedTileID{ 12, 655, 1583 }, ClipID{ "00001111", "00001011" } }, }), - stencils); + clipIDs); } TEST(GenerateClipIDs, MultipleSources) { @@ -312,8 +312,8 @@ TEST(GenerateClipIDs, MultipleSources) { }), renderables3); - const auto stencils = generator.getStencils(); - EXPECT_EQ(decltype(stencils)({ + const auto clipIDs = generator.getClipIDs(); + EXPECT_EQ(decltype(clipIDs)({ { UnwrappedTileID{ 1, 0, 0 }, ClipID{ "11111111", "00101001" } }, { UnwrappedTileID{ 1, 0, 1 }, ClipID{ "11111111", "01001001" } }, { UnwrappedTileID{ 1, 1, 0 }, ClipID{ "11111111", "01101001" } }, @@ -322,7 +322,7 @@ TEST(GenerateClipIDs, MultipleSources) { { UnwrappedTileID{ 2, 2, 1 }, ClipID{ "11111111", "01101011" } }, { UnwrappedTileID{ 2, 2, 2 }, ClipID{ "11111111", "10000100" } }, }), - stencils); + clipIDs); } TEST(GenerateClipIDs, DuplicateIDs) { @@ -351,12 +351,12 @@ TEST(GenerateClipIDs, DuplicateIDs) { }), renderables2); - const auto stencils = generator.getStencils(); - EXPECT_EQ(decltype(stencils)({ + const auto clipIDs = generator.getClipIDs(); + EXPECT_EQ(decltype(clipIDs)({ { UnwrappedTileID{ 2, 0, 0 }, ClipID{ "00000011", "00000001" } }, { UnwrappedTileID{ 2, 0, 1 }, ClipID{ "00000011", "00000010" } }, }), - stencils); + clipIDs); } TEST(GenerateClipIDs, SecondSourceHasParentOfFirstSource) { @@ -390,10 +390,10 @@ TEST(GenerateClipIDs, SecondSourceHasParentOfFirstSource) { }), renderables3); - const auto stencils = generator.getStencils(); - EXPECT_EQ(decltype(stencils)({ + const auto clipIDs = generator.getClipIDs(); + EXPECT_EQ(decltype(clipIDs)({ { UnwrappedTileID{ 0, 0, 0 }, ClipID{ "00000110", "00000110" } }, { UnwrappedTileID{ 1, 0, 0 }, ClipID{ "00000111", "00000101" } }, }), - stencils); + clipIDs); } -- cgit v1.2.1 From e5e9e0cf217a597f5abdf2ed823970a77f2f7c19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Thu, 6 Jul 2017 12:11:11 +0200 Subject: [build] remove .travis.yml to avoid triggering builds that we don't use --- .travis.yml | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c8d5746d68..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -language: cpp - -script: - - true - -notifications: - slack: - secure: HHQYr7sF8M1SzoWSqgKVYtwAgGdLLCyTMsQjFhEEQNYO92ZwURE5s03qWTGH5k8+4Yqn26yrXt3NztLC4JIOpcGervN2mSZyq4dZgFTcWEd61igw0qwSenlwvFfbE1ASK/KYCzfyn9MIfHN+ovwLoRxXZkPwinKDvl3DXjBaFNg= -- cgit v1.2.1 From af22fcd181a8253c1dd41941a6d62aea2c8f4e99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Thu, 6 Jul 2017 12:28:26 +0200 Subject: [core] point status badges to Circle CI --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 94a534a12f..3549fbe014 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,12 @@ This repository hosts the cross-platform Mapbox GL Native library, plus convenie | SDK | Languages | Build status | | --------------------------------------- | ---------------------------------- | ---------------------------------------- | -| [Mapbox GL Native](INSTALL.md) | C++14 | [![Travis](https://travis-ci.org/mapbox/mapbox-gl-native.svg?branch=master)](https://travis-ci.org/mapbox/mapbox-gl-native/builds) [![Coverage Status](https://coveralls.io/repos/github/mapbox/mapbox-gl-native/badge.svg?branch=master)](https://coveralls.io/github/mapbox/mapbox-gl-native?branch=master) | -| [Mapbox Android SDK](platform/android/) | Java | [![Bitrise](https://www.bitrise.io/app/79cdcbdc42de4303.svg?token=_InPF8bII6W7J6kFr-L8QQ&branch=master)](https://www.bitrise.io/app/79cdcbdc42de4303) | +| [Mapbox GL Native](INSTALL.md) | C++14 | [![Circle CI build status](https://circleci.com/gh/mapbox/mapbox-gl-native.svg?style=shield)](https://circleci.com/gh/mapbox/workflows/mapbox-gl-native/tree/master) [![Coverage Status](https://coveralls.io/repos/github/mapbox/mapbox-gl-native/badge.svg?branch=master)](https://coveralls.io/github/mapbox/mapbox-gl-native?branch=master) | +| [Mapbox Android SDK](platform/android/) | Java | [![Circle CI build status](https://circleci.com/gh/mapbox/mapbox-gl-native.svg?style=shield)](https://circleci.com/gh/mapbox/workflows/mapbox-gl-native/tree/master) | | [Mapbox iOS SDK](platform/ios/) | Objective-C or Swift | [![Bitrise](https://www.bitrise.io/app/7514e4cf3da2cc57.svg?token=OwqZE5rSBR9MVWNr_lf4sA&branch=master)](https://www.bitrise.io/app/7514e4cf3da2cc57) | | [Mapbox macOS SDK](platform/macos/) | Objective-C, Swift, or AppleScript | [![Bitrise](https://www.bitrise.io/app/155ef7da24b38dcd.svg?token=4KSOw_gd6WxTnvGE2rMttg&branch=master)](https://www.bitrise.io/app/155ef7da24b38dcd) | -| [node-mapbox-gl-native](platform/node/) | Node.js | [![Linux](https://travis-ci.org/mapbox/mapbox-gl-native.svg?branch=master)](https://travis-ci.org/mapbox/mapbox-gl-native/builds) [![macOS](https://www.bitrise.io/app/55e3a9bf71202106.svg?token=5qf5ZUcKVN3LDnHhW7rO0w)](https://www.bitrise.io/app/55e3a9bf71202106) | -| [Mapbox Qt SDK](platform/qt) | C++03 | [![Travis](https://travis-ci.org/mapbox/mapbox-gl-native.svg?branch=master)](https://travis-ci.org/mapbox/mapbox-gl-native/builds) [![Bitrise](https://www.bitrise.io/app/96cfbc97e0245c22.svg?token=GxsqIOGPXhn0F23sSVSsYA&branch=master)](https://www.bitrise.io/app/96cfbc97e0245c22) | +| [node-mapbox-gl-native](platform/node/) | Node.js | [![Circle CI build status](https://circleci.com/gh/mapbox/mapbox-gl-native.svg?style=shield)](https://circleci.com/gh/mapbox/workflows/mapbox-gl-native/tree/master) | +| [Mapbox Qt SDK](platform/qt) | C++03 | [![Circle CI build status](https://circleci.com/gh/mapbox/mapbox-gl-native.svg?style=shield)](https://circleci.com/gh/mapbox/workflows/mapbox-gl-native/tree/master) | Additional Mapbox GL Native–based libraries for **hybrid applications** are developed outside of this repository: -- cgit v1.2.1 From 754d2f377aa1b8993ca5365109dfec98475e6de4 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Fri, 23 Jun 2017 11:36:54 -0700 Subject: [core] make{Glyph,Image}Atlas only once for any number of symbol layers --- src/mbgl/layout/symbol_layout.hpp | 7 ----- src/mbgl/tile/geometry_tile_worker.cpp | 49 ++++++++++++++++------------------ src/mbgl/tile/geometry_tile_worker.hpp | 2 +- 3 files changed, 24 insertions(+), 34 deletions(-) diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp index 8cdaadff00..4ee52e843f 100644 --- a/src/mbgl/layout/symbol_layout.hpp +++ b/src/mbgl/layout/symbol_layout.hpp @@ -40,13 +40,6 @@ public: bool hasSymbolInstances() const; - enum State { - Pending, // Waiting for the necessary glyphs or icons to be available. - Placed // The final positions have been determined, taking into account prior layers. - }; - - State state = Pending; - std::map> layerPaintProperties; diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp index 12bb84d7e3..c622d82e31 100644 --- a/src/mbgl/tile/geometry_tile_worker.cpp +++ b/src/mbgl/tile/geometry_tile_worker.cpp @@ -144,14 +144,14 @@ void GeometryTileWorker::symbolDependenciesChanged() { try { switch (state) { case Idle: - if (hasPendingSymbolLayouts()) { + if (symbolLayoutsNeedPreparation) { attemptPlacement(); coalesce(); } break; case Coalescing: - if (hasPendingSymbolLayouts()) { + if (symbolLayoutsNeedPreparation) { state = NeedPlacement; } break; @@ -312,6 +312,7 @@ void GeometryTileWorker::redoLayout() { auto layout = leader.as()->createLayout( parameters, group, std::move(geometryLayer), glyphDependencies, imageDependencies); symbolLayoutMap.emplace(leader.getID(), std::move(layout)); + symbolLayoutsNeedPreparation = true; } else { const Filter& filter = leader.baseImpl->filter; const std::string& sourceLayerID = leader.baseImpl->sourceLayer; @@ -359,16 +360,6 @@ void GeometryTileWorker::redoLayout() { attemptPlacement(); } -bool GeometryTileWorker::hasPendingSymbolLayouts() const { - for (const auto& symbolLayout : symbolLayouts) { - if (symbolLayout->state == SymbolLayout::Pending) { - return true; - } - } - - return false; -} - bool GeometryTileWorker::hasPendingSymbolDependencies() const { for (auto& glyphDependency : pendingGlyphDependencies) { if (!glyphDependency.second.empty()) { @@ -378,33 +369,39 @@ bool GeometryTileWorker::hasPendingSymbolDependencies() const { return !pendingImageDependencies.empty(); } - void GeometryTileWorker::attemptPlacement() { if (!data || !layers || !placementConfig || hasPendingSymbolDependencies()) { return; } - auto collisionTile = std::make_unique(*placementConfig); - std::unordered_map> buckets; - optional glyphAtlasImage; optional iconAtlasImage; - for (auto& symbolLayout : symbolLayouts) { - if (obsolete) { - return; - } + if (symbolLayoutsNeedPreparation) { + GlyphAtlas glyphAtlas = makeGlyphAtlas(glyphMap); + ImageAtlas imageAtlas = makeImageAtlas(imageMap); + + glyphAtlasImage = std::move(glyphAtlas.image); + iconAtlasImage = std::move(imageAtlas.image); - if (symbolLayout->state == SymbolLayout::Pending) { - GlyphAtlas glyphAtlas = makeGlyphAtlas(glyphMap); - ImageAtlas imageAtlas = makeImageAtlas(imageMap); + for (auto& symbolLayout : symbolLayouts) { + if (obsolete) { + return; + } symbolLayout->prepare(glyphMap, glyphAtlas.positions, imageMap, imageAtlas.positions); - symbolLayout->state = SymbolLayout::Placed; + } + + symbolLayoutsNeedPreparation = false; + } - glyphAtlasImage = std::move(glyphAtlas.image); - iconAtlasImage = std::move(imageAtlas.image); + auto collisionTile = std::make_unique(*placementConfig); + std::unordered_map> buckets; + + for (auto& symbolLayout : symbolLayouts) { + if (obsolete) { + return; } if (!symbolLayout->hasSymbolInstances()) { diff --git a/src/mbgl/tile/geometry_tile_worker.hpp b/src/mbgl/tile/geometry_tile_worker.hpp index 194477e7b8..7f80c3b4f7 100644 --- a/src/mbgl/tile/geometry_tile_worker.hpp +++ b/src/mbgl/tile/geometry_tile_worker.hpp @@ -52,7 +52,6 @@ private: void symbolDependenciesChanged(); bool hasPendingSymbolDependencies() const; - bool hasPendingSymbolLayouts() const; ActorRef self; ActorRef parent; @@ -77,6 +76,7 @@ private: optional> data; optional placementConfig; + bool symbolLayoutsNeedPreparation = false; std::vector> symbolLayouts; GlyphDependencies pendingGlyphDependencies; ImageDependencies pendingImageDependencies; -- cgit v1.2.1 From a1ed9f879408a12e462196d961075c2ae3d7486e Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Wed, 5 Jul 2017 14:37:49 +0300 Subject: [core] Don't upload empty buckets --- src/mbgl/renderer/bucket.hpp | 5 ++++- src/mbgl/renderer/buckets/symbol_bucket.cpp | 3 +-- test/gl/bucket.test.cpp | 6 ++++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/mbgl/renderer/bucket.hpp b/src/mbgl/renderer/bucket.hpp index 6c391cf014..a411daf3d4 100644 --- a/src/mbgl/renderer/bucket.hpp +++ b/src/mbgl/renderer/bucket.hpp @@ -28,6 +28,9 @@ public: Bucket() = default; virtual ~Bucket() = default; + // Feature geometries are also used to populate the feature index. + // Obtaining these is a costly operation, so we do it only once, and + // pass-by-const-ref the geometries as a second parameter. virtual void addFeature(const GeometryTileFeature&, const GeometryCollection&) {}; @@ -46,7 +49,7 @@ public: }; bool needsUpload() const { - return !uploaded; + return hasData() && !uploaded; } protected: diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp index cbddade899..28e6a47250 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.cpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp @@ -69,8 +69,7 @@ void SymbolBucket::render(Painter& painter, } bool SymbolBucket::hasData() const { - assert(false); // Should be calling SymbolLayout::has{Text,Icon,CollisonBox}Data() instead. - return false; + return hasTextData() || hasIconData() || hasCollisionBoxData(); } bool SymbolBucket::hasTextData() const { diff --git a/test/gl/bucket.test.cpp b/test/gl/bucket.test.cpp index ee9ea54414..feca82998f 100644 --- a/test/gl/bucket.test.cpp +++ b/test/gl/bucket.test.cpp @@ -16,16 +16,19 @@ using namespace mbgl; TEST(Buckets, CircleBucket) { CircleBucket bucket { { {0, 0, 0}, MapMode::Still, 1.0 }, {} }; ASSERT_FALSE(bucket.hasData()); + ASSERT_FALSE(bucket.needsUpload()); } TEST(Buckets, FillBucket) { FillBucket bucket { { {0, 0, 0}, MapMode::Still, 1.0 }, {} }; ASSERT_FALSE(bucket.hasData()); + ASSERT_FALSE(bucket.needsUpload()); } TEST(Buckets, LineBucket) { LineBucket bucket { { {0, 0, 0}, MapMode::Still, 1.0 }, {}, {} }; ASSERT_FALSE(bucket.hasData()); + ASSERT_FALSE(bucket.needsUpload()); } TEST(Buckets, SymbolBucket) { @@ -37,6 +40,8 @@ TEST(Buckets, SymbolBucket) { ASSERT_FALSE(bucket.hasIconData()); ASSERT_FALSE(bucket.hasTextData()); ASSERT_FALSE(bucket.hasCollisionBoxData()); + ASSERT_FALSE(bucket.hasData()); + ASSERT_FALSE(bucket.needsUpload()); } TEST(Buckets, RasterBucket) { @@ -44,6 +49,7 @@ TEST(Buckets, RasterBucket) { UnassociatedImage rgba({ 1, 1 }); RasterBucket bucket = { std::move(rgba) }; + ASSERT_TRUE(bucket.hasData()); ASSERT_TRUE(bucket.needsUpload()); bucket.upload(context); -- cgit v1.2.1 From 0395271b9d900cacf543d9bca6314e50b7cfc7af Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Wed, 5 Jul 2017 14:57:34 +0300 Subject: [test] Reuse StubGeometryTileFeature in MergeLines --- test/src/mbgl/test/stub_geometry_tile_feature.hpp | 7 ++++ test/util/merge_lines.test.cpp | 41 ++++------------------- 2 files changed, 14 insertions(+), 34 deletions(-) diff --git a/test/src/mbgl/test/stub_geometry_tile_feature.hpp b/test/src/mbgl/test/stub_geometry_tile_feature.hpp index 21d198a96b..775d783ead 100644 --- a/test/src/mbgl/test/stub_geometry_tile_feature.hpp +++ b/test/src/mbgl/test/stub_geometry_tile_feature.hpp @@ -9,6 +9,13 @@ public: : properties(std::move(properties_)) { } + StubGeometryTileFeature(optional id_, FeatureType type_, GeometryCollection geometry_, PropertyMap properties_) + : properties(std::move(properties_)), + id(std::move(id_)), + type(type_), + geometry(std::move(geometry_)) { + } + PropertyMap properties; optional id = {}; FeatureType type = FeatureType::Point; diff --git a/test/util/merge_lines.test.cpp b/test/util/merge_lines.test.cpp index 6c8387c451..ff80157354 100644 --- a/test/util/merge_lines.test.cpp +++ b/test/util/merge_lines.test.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -9,40 +10,12 @@ const std::u16string bbb = u"b"; using namespace mbgl; -class GeometryTileFeatureStub : public GeometryTileFeature { -public: - GeometryTileFeatureStub(optional id_, FeatureType type_, GeometryCollection geometry_, - std::unordered_map properties_) : - id(std::move(id_)), - type(type_), - geometry(std::move(geometry_)), - properties(std::move(properties_)) - {} - - FeatureType getType() const override { return type; } - optional getValue(const std::string& key) const override { - auto it = properties.find(key); - if (it != properties.end()) { - return it->second; - } - return {}; - }; - std::unordered_map getProperties() const override { return properties; }; - optional getID() const override { return id; }; - GeometryCollection getGeometries() const override { return geometry; }; - - optional id; - FeatureType type; - GeometryCollection geometry; - std::unordered_map properties; -}; - class SymbolFeatureStub : public SymbolFeature { public: SymbolFeatureStub(optional id_, FeatureType type_, GeometryCollection geometry_, std::unordered_map properties_, optional text_, optional icon_, std::size_t index_) : - SymbolFeature(std::make_unique(id_, type_, geometry_, properties_)) + SymbolFeature(std::make_unique(id_, type_, geometry_, properties_)) { text = text_; icon = icon_; @@ -60,7 +33,7 @@ TEST(MergeLines, SameText) { input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{6, 0}, {7, 0}, {8, 0}}}, {}, aaa, {}, 0)); input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{5, 0}, {6, 0}}}, {}, aaa, {}, 0)); - const std::vector expected1 = { + const std::vector expected1 = { { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}}}, {} }, { {}, FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, {} }, { {}, FeatureType::LineString, {{{5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}}}, {} }, @@ -83,7 +56,7 @@ TEST(MergeLines, BothEnds) { input2.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, {}, aaa, {}, 0 }); input2.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, {}, aaa, {}, 0 }); - const std::vector expected2 = { + const std::vector expected2 = { { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}}}, {} }, { {}, FeatureType::LineString, {{}}, {} }, { {}, FeatureType::LineString, {{}}, {} } @@ -103,7 +76,7 @@ TEST(MergeLines, CircularLines) { input3.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, {}, aaa, {}, 0 }); input3.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{4, 0}, {0, 0}}}, {}, aaa, {}, 0 }); - const std::vector expected3 = { + const std::vector expected3 = { { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {0, 0}}}, {} }, { {}, FeatureType::LineString, {{}}, {} }, { {}, FeatureType::LineString, {{}}, {} } @@ -120,7 +93,7 @@ TEST(MergeLines, EmptyOuterGeometry) { std::vector input; input.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {}, {}, aaa, {}, 0 }); - const std::vector expected = { { {}, FeatureType::LineString, {}, {} } }; + const std::vector expected = { { {}, FeatureType::LineString, {}, {} } }; mbgl::util::mergeLines(input); @@ -131,7 +104,7 @@ TEST(MergeLines, EmptyInnerGeometry) { std::vector input; input.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{}}, {}, aaa, {}, 0 }); - const std::vector expected = { { {}, FeatureType::LineString, {{}}, {} } }; + const std::vector expected = { { {}, FeatureType::LineString, {{}}, {} } }; mbgl::util::mergeLines(input); -- cgit v1.2.1 From 06a0c4ad15a335e1fe8c66886d8b9f75d6e3bdbe Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Wed, 5 Jul 2017 16:31:16 +0300 Subject: [test] Added bucket feature insertion tests --- test/gl/bucket.test.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/test/gl/bucket.test.cpp b/test/gl/bucket.test.cpp index feca82998f..fdff0e990a 100644 --- a/test/gl/bucket.test.cpp +++ b/test/gl/bucket.test.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -14,21 +15,54 @@ using namespace mbgl; TEST(Buckets, CircleBucket) { + gl::Context context; CircleBucket bucket { { {0, 0, 0}, MapMode::Still, 1.0 }, {} }; ASSERT_FALSE(bucket.hasData()); ASSERT_FALSE(bucket.needsUpload()); + + GeometryCollection point { { { 0, 0 } } }; + bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Point, point, {} }, point); + ASSERT_TRUE(bucket.hasData()); + ASSERT_TRUE(bucket.needsUpload()); + + bucket.upload(context); + ASSERT_TRUE(bucket.hasData()); + ASSERT_FALSE(bucket.needsUpload()); } TEST(Buckets, FillBucket) { + gl::Context context; FillBucket bucket { { {0, 0, 0}, MapMode::Still, 1.0 }, {} }; ASSERT_FALSE(bucket.hasData()); ASSERT_FALSE(bucket.needsUpload()); + + GeometryCollection polygon { { { 0, 0 }, { 0, 1 }, { 1, 1 } } }; + bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Polygon, polygon, {} }, polygon); + ASSERT_TRUE(bucket.hasData()); + ASSERT_TRUE(bucket.needsUpload()); + + bucket.upload(context); + ASSERT_FALSE(bucket.needsUpload()); } TEST(Buckets, LineBucket) { + gl::Context context; LineBucket bucket { { {0, 0, 0}, MapMode::Still, 1.0 }, {}, {} }; ASSERT_FALSE(bucket.hasData()); ASSERT_FALSE(bucket.needsUpload()); + + // Ignore invalid feature type. + GeometryCollection point { { { 0, 0 } } }; + bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Point, point, {} }, point); + ASSERT_FALSE(bucket.hasData()); + + GeometryCollection line { { { 0, 0 }, { 1, 1 } } }; + bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::LineString, line, {} }, line); + ASSERT_TRUE(bucket.hasData()); + ASSERT_TRUE(bucket.needsUpload()); + + bucket.upload(context); + ASSERT_FALSE(bucket.needsUpload()); } TEST(Buckets, SymbolBucket) { @@ -36,18 +70,34 @@ TEST(Buckets, SymbolBucket) { bool sdfIcons = false; bool iconsNeedLinear = false; + gl::Context context; SymbolBucket bucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear }; ASSERT_FALSE(bucket.hasIconData()); ASSERT_FALSE(bucket.hasTextData()); ASSERT_FALSE(bucket.hasCollisionBoxData()); ASSERT_FALSE(bucket.hasData()); ASSERT_FALSE(bucket.needsUpload()); + + // SymbolBucket::addFeature() is a no-op. + GeometryCollection point { { { 0, 0 } } }; + bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Point, point, {} }, point); + ASSERT_FALSE(bucket.hasData()); + ASSERT_FALSE(bucket.needsUpload()); + + bucket.text.segments.emplace_back(0, 0); + ASSERT_TRUE(bucket.hasTextData()); + ASSERT_TRUE(bucket.hasData()); + ASSERT_TRUE(bucket.needsUpload()); + + bucket.upload(context); + ASSERT_FALSE(bucket.needsUpload()); } TEST(Buckets, RasterBucket) { gl::Context context; UnassociatedImage rgba({ 1, 1 }); + // RasterBucket::hasData() is always true. RasterBucket bucket = { std::move(rgba) }; ASSERT_TRUE(bucket.hasData()); ASSERT_TRUE(bucket.needsUpload()); -- cgit v1.2.1 From 3800edb133ea0bbeb7fc613dc8f6975d0d6b6513 Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Wed, 5 Jul 2017 13:59:45 -0700 Subject: [core] Bump mapbox-gl-js to get updated circle shader. --- mapbox-gl-js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapbox-gl-js b/mapbox-gl-js index 09bec658e3..3dd4116554 160000 --- a/mapbox-gl-js +++ b/mapbox-gl-js @@ -1 +1 @@ -Subproject commit 09bec658e3f8de18a7964f5633aea9716dcb3919 +Subproject commit 3dd4116554694559e3df2667ed91670438e8d1ae -- cgit v1.2.1 From d5fbcb242acff2ab270b4018b01c2c6be9c4955f Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Wed, 5 Jul 2017 13:59:45 -0700 Subject: [core] Implement circle-pitch-alignment property Closes issue #9349. --- .../style/conversion/make_property_setters.hpp | 2 + include/mbgl/style/layers/circle_layer.hpp | 6 +++ .../mapbox/mapboxsdk/style/layers/CircleLayer.java | 12 ++++++ .../mapbox/mapboxsdk/style/layers/Property.java | 21 ++++++++++ .../mapboxsdk/style/layers/PropertyFactory.java | 22 +++++++++++ .../mapboxsdk/testapp/style/CircleLayerTest.java | 38 ++++++++++++++++++ platform/android/src/style/layers/circle_layer.cpp | 7 ++++ platform/android/src/style/layers/circle_layer.hpp | 2 + platform/darwin/src/MGLCircleStyleLayer.h | 45 ++++++++++++++++++++++ platform/darwin/src/MGLCircleStyleLayer.mm | 32 +++++++++++++++ platform/darwin/test/MGLCircleStyleLayerTests.mm | 42 ++++++++++++++++++++ src/mbgl/programs/circle_program.hpp | 4 +- src/mbgl/programs/symbol_program.hpp | 1 - src/mbgl/programs/uniforms.hpp | 2 + src/mbgl/renderer/painters/painter_circle.cpp | 12 +++--- src/mbgl/shaders/circle.cpp | 28 +++++++++++--- src/mbgl/style/layers/circle_layer.cpp | 27 +++++++++++++ src/mbgl/style/layers/circle_layer_properties.hpp | 5 +++ 18 files changed, 296 insertions(+), 12 deletions(-) diff --git a/include/mbgl/style/conversion/make_property_setters.hpp b/include/mbgl/style/conversion/make_property_setters.hpp index eaea2e89dc..1c26aeb5e4 100644 --- a/include/mbgl/style/conversion/make_property_setters.hpp +++ b/include/mbgl/style/conversion/make_property_setters.hpp @@ -155,6 +155,8 @@ auto makePaintPropertySetters() { result["circle-translate-anchor-transition"] = &setTransition; result["circle-pitch-scale"] = &setProperty, &CircleLayer::setCirclePitchScale>; result["circle-pitch-scale-transition"] = &setTransition; + result["circle-pitch-alignment"] = &setProperty, &CircleLayer::setCirclePitchAlignment>; + result["circle-pitch-alignment-transition"] = &setTransition; result["circle-stroke-width"] = &setProperty, &CircleLayer::setCircleStrokeWidth>; result["circle-stroke-width-transition"] = &setTransition; result["circle-stroke-color"] = &setProperty, &CircleLayer::setCircleStrokeColor>; diff --git a/include/mbgl/style/layers/circle_layer.hpp b/include/mbgl/style/layers/circle_layer.hpp index 275a2e67a5..942dd67503 100644 --- a/include/mbgl/style/layers/circle_layer.hpp +++ b/include/mbgl/style/layers/circle_layer.hpp @@ -78,6 +78,12 @@ public: void setCirclePitchScaleTransition(const TransitionOptions&); TransitionOptions getCirclePitchScaleTransition() const; + static PropertyValue getDefaultCirclePitchAlignment(); + PropertyValue getCirclePitchAlignment() const; + void setCirclePitchAlignment(PropertyValue); + void setCirclePitchAlignmentTransition(const TransitionOptions&); + TransitionOptions getCirclePitchAlignmentTransition() const; + static DataDrivenPropertyValue getDefaultCircleStrokeWidth(); DataDrivenPropertyValue getCircleStrokeWidth() const; void setCircleStrokeWidth(DataDrivenPropertyValue); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java index 1a7df06031..10663142b5 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java @@ -277,6 +277,16 @@ public class CircleLayer extends Layer { return (PropertyValue) new PropertyValue("circle-pitch-scale", nativeGetCirclePitchScale()); } + /** + * Get the CirclePitchAlignment property + * + * @return property wrapper value around String + */ + @SuppressWarnings("unchecked") + public PropertyValue getCirclePitchAlignment() { + return (PropertyValue) new PropertyValue("circle-pitch-alignment", nativeGetCirclePitchAlignment()); + } + /** * Get the CircleStrokeWidth property * @@ -411,6 +421,8 @@ public class CircleLayer extends Layer { private native Object nativeGetCirclePitchScale(); + private native Object nativeGetCirclePitchAlignment(); + private native Object nativeGetCircleStrokeWidth(); private native TransitionOptions nativeGetCircleStrokeWidthTransition(); 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 5e345268f9..d3d0e060dc 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 @@ -446,6 +446,27 @@ public final class Property { @Retention(RetentionPolicy.SOURCE) public @interface CIRCLE_PITCH_SCALE {} + // CIRCLE_PITCH_ALIGNMENT: Orientation of circle when map is pitched. + + /** + * The circle is aligned to the plane of the map. + */ + public static final String CIRCLE_PITCH_ALIGNMENT_MAP = "map"; + /** + * The circle is aligned to the plane of the viewport. + */ + public static final String CIRCLE_PITCH_ALIGNMENT_VIEWPORT = "viewport"; + + /** + * Orientation of circle when map is pitched. + */ + @StringDef({ + CIRCLE_PITCH_ALIGNMENT_MAP, + CIRCLE_PITCH_ALIGNMENT_VIEWPORT, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface CIRCLE_PITCH_ALIGNMENT {} + // FILL_EXTRUSION_TRANSLATE_ANCHOR: Controls the translation reference point. /** 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 73896b7901..c12d6b7133 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 @@ -952,6 +952,28 @@ public class PropertyFactory { return new PaintPropertyValue<>("circle-pitch-scale", function); } + /** + * Orientation of circle when map is pitched. + * + * @param value a String value + * @return property wrapper around String + */ + public static PropertyValue circlePitchAlignment(@Property.CIRCLE_PITCH_ALIGNMENT String value) { + return new PaintPropertyValue<>("circle-pitch-alignment", value); + } + + + /** + * Orientation of circle when map is pitched. + * + * @param the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String + * @return property wrapper around a String function + */ + public static PropertyValue> circlePitchAlignment(CameraFunction function) { + return new PaintPropertyValue<>("circle-pitch-alignment", function); + } + /** * The width of the circle's stroke. Strokes are placed outside of the {@link PropertyFactory#circleRadius}. * diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java index c8f9640433..84f4c16801 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java @@ -1047,6 +1047,44 @@ public class CircleLayerTest extends BaseActivityTest { }); } + @Test + public void testCirclePitchAlignmentAsConstant() { + validateTestSetup(); + setupLayer(); + Timber.i("circle-pitch-alignment"); + assertNotNull(layer); + + // Set and Get + layer.setProperties(circlePitchAlignment(CIRCLE_PITCH_ALIGNMENT_MAP)); + assertEquals((String) layer.getCirclePitchAlignment().getValue(), (String) CIRCLE_PITCH_ALIGNMENT_MAP); + } + + @Test + public void testCirclePitchAlignmentAsCameraFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("circle-pitch-alignment"); + assertNotNull(layer); + + // Set + layer.setProperties( + circlePitchAlignment( + zoom( + interval( + stop(2, circlePitchAlignment(CIRCLE_PITCH_ALIGNMENT_MAP)) + ) + ) + ) + ); + + // Verify + assertNotNull(layer.getCirclePitchAlignment()); + assertNotNull(layer.getCirclePitchAlignment().getFunction()); + assertEquals(CameraFunction.class, layer.getCirclePitchAlignment().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getCirclePitchAlignment().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getCirclePitchAlignment().getFunction().getStops()).size()); + } + @Test public void testCircleStrokeWidthTransition() { validateTestSetup(); diff --git a/platform/android/src/style/layers/circle_layer.cpp b/platform/android/src/style/layers/circle_layer.cpp index 96a9356679..4c7f69e956 100644 --- a/platform/android/src/style/layers/circle_layer.cpp +++ b/platform/android/src/style/layers/circle_layer.cpp @@ -142,6 +142,12 @@ namespace android { return jni::Object(*converted); } + jni::Object CircleLayer::getCirclePitchAlignment(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->CircleLayer::getCirclePitchAlignment()); + return jni::Object(*converted); + } + jni::Object CircleLayer::getCircleStrokeWidth(jni::JNIEnv& env) { using namespace mbgl::android::conversion; Result converted = convert(env, layer.as()->CircleLayer::getCircleStrokeWidth()); @@ -236,6 +242,7 @@ namespace android { METHOD(&CircleLayer::getCircleTranslate, "nativeGetCircleTranslate"), METHOD(&CircleLayer::getCircleTranslateAnchor, "nativeGetCircleTranslateAnchor"), METHOD(&CircleLayer::getCirclePitchScale, "nativeGetCirclePitchScale"), + METHOD(&CircleLayer::getCirclePitchAlignment, "nativeGetCirclePitchAlignment"), METHOD(&CircleLayer::getCircleStrokeWidthTransition, "nativeGetCircleStrokeWidthTransition"), METHOD(&CircleLayer::setCircleStrokeWidthTransition, "nativeSetCircleStrokeWidthTransition"), METHOD(&CircleLayer::getCircleStrokeWidth, "nativeGetCircleStrokeWidth"), diff --git a/platform/android/src/style/layers/circle_layer.hpp b/platform/android/src/style/layers/circle_layer.hpp index 81737e8996..9d323e92bb 100644 --- a/platform/android/src/style/layers/circle_layer.hpp +++ b/platform/android/src/style/layers/circle_layer.hpp @@ -53,6 +53,8 @@ public: jni::Object getCirclePitchScale(jni::JNIEnv&); + jni::Object getCirclePitchAlignment(jni::JNIEnv&); + jni::Object getCircleStrokeWidth(jni::JNIEnv&); void setCircleStrokeWidthTransition(jni::JNIEnv&, jlong duration, jlong delay); jni::Object getCircleStrokeWidthTransition(jni::JNIEnv&); diff --git a/platform/darwin/src/MGLCircleStyleLayer.h b/platform/darwin/src/MGLCircleStyleLayer.h index 789ff7a258..ea95f6beef 100644 --- a/platform/darwin/src/MGLCircleStyleLayer.h +++ b/platform/darwin/src/MGLCircleStyleLayer.h @@ -7,6 +7,23 @@ NS_ASSUME_NONNULL_BEGIN +/** + Orientation of circle when map is pitched. + + Values of this type are used in the `MGLCircleStyleLayer.circlePitchAlignment` + property. + */ +typedef NS_ENUM(NSUInteger, MGLCirclePitchAlignment) { + /** + The circle is aligned to the plane of the map. + */ + MGLCirclePitchAlignmentMap, + /** + The circle is aligned to the plane of the viewport. + */ + MGLCirclePitchAlignmentViewport, +}; + /** Controls the scaling behavior of the circle when the map is pitched. @@ -220,6 +237,21 @@ MGL_EXPORT */ @property (nonatomic) MGLTransition circleOpacityTransition; +/** + Orientation of circle when map is pitched. + + The default value of this property is an `MGLStyleValue` object containing an + `NSValue` object containing `MGLCirclePitchAlignmentViewport`. Set this + property to `nil` to reset it to the default value. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of + `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue *circlePitchAlignment; + /** Circle radius. @@ -490,6 +522,19 @@ MGL_EXPORT #pragma mark Working with Circle Style Layer Attribute Values +/** + Creates a new value object containing the given `MGLCirclePitchAlignment` enumeration. + + @param circlePitchAlignment The value for the new object. + @return A new value object that contains the enumeration value. + */ ++ (instancetype)valueWithMGLCirclePitchAlignment:(MGLCirclePitchAlignment)circlePitchAlignment; + +/** + The `MGLCirclePitchAlignment` enumeration representation of the value. + */ +@property (readonly) MGLCirclePitchAlignment MGLCirclePitchAlignmentValue; + /** Creates a new value object containing the given `MGLCircleScaleAlignment` enumeration. diff --git a/platform/darwin/src/MGLCircleStyleLayer.mm b/platform/darwin/src/MGLCircleStyleLayer.mm index 42961f2e12..71ae37035e 100644 --- a/platform/darwin/src/MGLCircleStyleLayer.mm +++ b/platform/darwin/src/MGLCircleStyleLayer.mm @@ -13,6 +13,11 @@ namespace mbgl { + MBGL_DEFINE_ENUM(MGLCirclePitchAlignment, { + { MGLCirclePitchAlignmentMap, "map" }, + { MGLCirclePitchAlignmentViewport, "viewport" }, + }); + MBGL_DEFINE_ENUM(MGLCircleScaleAlignment, { { MGLCircleScaleAlignmentMap, "map" }, { MGLCircleScaleAlignmentViewport, "viewport" }, @@ -187,6 +192,23 @@ namespace mbgl { return transition; } +- (void)setCirclePitchAlignment:(MGLStyleValue *)circlePitchAlignment { + MGLAssertStyleLayerIsValid(); + + auto mbglValue = MGLStyleValueTransformer().toEnumPropertyValue(circlePitchAlignment); + self.rawLayer->setCirclePitchAlignment(mbglValue); +} + +- (MGLStyleValue *)circlePitchAlignment { + MGLAssertStyleLayerIsValid(); + + auto propertyValue = self.rawLayer->getCirclePitchAlignment(); + if (propertyValue.isUndefined()) { + return MGLStyleValueTransformer().toEnumStyleValue(self.rawLayer->getDefaultCirclePitchAlignment()); + } + return MGLStyleValueTransformer().toEnumStyleValue(propertyValue); +} + - (void)setCircleRadius:(MGLStyleValue *)circleRadius { MGLAssertStyleLayerIsValid(); @@ -421,6 +443,16 @@ namespace mbgl { @implementation NSValue (MGLCircleStyleLayerAdditions) ++ (NSValue *)valueWithMGLCirclePitchAlignment:(MGLCirclePitchAlignment)circlePitchAlignment { + return [NSValue value:&circlePitchAlignment withObjCType:@encode(MGLCirclePitchAlignment)]; +} + +- (MGLCirclePitchAlignment)MGLCirclePitchAlignmentValue { + MGLCirclePitchAlignment circlePitchAlignment; + [self getValue:&circlePitchAlignment]; + return circlePitchAlignment; +} + + (NSValue *)valueWithMGLCircleScaleAlignment:(MGLCircleScaleAlignment)circleScaleAlignment { return [NSValue value:&circleScaleAlignment withObjCType:@encode(MGLCircleScaleAlignment)]; } diff --git a/platform/darwin/test/MGLCircleStyleLayerTests.mm b/platform/darwin/test/MGLCircleStyleLayerTests.mm index 2a2e9f2d4a..c0c503153a 100644 --- a/platform/darwin/test/MGLCircleStyleLayerTests.mm +++ b/platform/darwin/test/MGLCircleStyleLayerTests.mm @@ -246,6 +246,45 @@ XCTAssertEqual(circleOpacityTransition.duration, transitionTest.duration); } + // circle-pitch-alignment + { + XCTAssertTrue(rawLayer->getCirclePitchAlignment().isUndefined(), + @"circle-pitch-alignment should be unset initially."); + MGLStyleValue *defaultStyleValue = layer.circlePitchAlignment; + + MGLStyleValue *constantStyleValue = [MGLStyleValue valueWithRawValue:[NSValue valueWithMGLCirclePitchAlignment:MGLCirclePitchAlignmentViewport]]; + layer.circlePitchAlignment = constantStyleValue; + mbgl::style::PropertyValue propertyValue = { mbgl::style::AlignmentType::Viewport }; + XCTAssertEqual(rawLayer->getCirclePitchAlignment(), propertyValue, + @"Setting circlePitchAlignment to a constant value should update circle-pitch-alignment."); + XCTAssertEqualObjects(layer.circlePitchAlignment, constantStyleValue, + @"circlePitchAlignment should round-trip constant values."); + + MGLStyleValue * functionStyleValue = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.circlePitchAlignment = functionStyleValue; + + mbgl::style::IntervalStops intervalStops = { {{18, mbgl::style::AlignmentType::Viewport}} }; + propertyValue = mbgl::style::CameraFunction { intervalStops }; + + XCTAssertEqual(rawLayer->getCirclePitchAlignment(), propertyValue, + @"Setting circlePitchAlignment to a camera function should update circle-pitch-alignment."); + XCTAssertEqualObjects(layer.circlePitchAlignment, functionStyleValue, + @"circlePitchAlignment should round-trip camera functions."); + + + + layer.circlePitchAlignment = nil; + XCTAssertTrue(rawLayer->getCirclePitchAlignment().isUndefined(), + @"Unsetting circlePitchAlignment should return circle-pitch-alignment to the default value."); + XCTAssertEqualObjects(layer.circlePitchAlignment, defaultStyleValue, + @"circlePitchAlignment should return the default value after being unset."); + + functionStyleValue = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.circlePitchAlignment = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + functionStyleValue = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.circlePitchAlignment = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + } + // circle-radius { XCTAssertTrue(rawLayer->getCircleRadius().isUndefined(), @@ -638,6 +677,7 @@ [self testPropertyName:@"circle-blur" isBoolean:NO]; [self testPropertyName:@"circle-color" isBoolean:NO]; [self testPropertyName:@"circle-opacity" isBoolean:NO]; + [self testPropertyName:@"circle-pitch-alignment" isBoolean:NO]; [self testPropertyName:@"circle-radius" isBoolean:NO]; [self testPropertyName:@"circle-scale-alignment" isBoolean:NO]; [self testPropertyName:@"circle-stroke-color" isBoolean:NO]; @@ -648,6 +688,8 @@ } - (void)testValueAdditions { + XCTAssertEqual([NSValue valueWithMGLCirclePitchAlignment:MGLCirclePitchAlignmentMap].MGLCirclePitchAlignmentValue, MGLCirclePitchAlignmentMap); + XCTAssertEqual([NSValue valueWithMGLCirclePitchAlignment:MGLCirclePitchAlignmentViewport].MGLCirclePitchAlignmentValue, MGLCirclePitchAlignmentViewport); XCTAssertEqual([NSValue valueWithMGLCircleScaleAlignment:MGLCircleScaleAlignmentMap].MGLCircleScaleAlignmentValue, MGLCircleScaleAlignmentMap); XCTAssertEqual([NSValue valueWithMGLCircleScaleAlignment:MGLCircleScaleAlignmentViewport].MGLCircleScaleAlignmentValue, MGLCircleScaleAlignmentViewport); XCTAssertEqual([NSValue valueWithMGLCircleTranslationAnchor:MGLCircleTranslationAnchorMap].MGLCircleTranslationAnchorValue, MGLCircleTranslationAnchorMap); diff --git a/src/mbgl/programs/circle_program.hpp b/src/mbgl/programs/circle_program.hpp index 8f056048b1..3590acbeef 100644 --- a/src/mbgl/programs/circle_program.hpp +++ b/src/mbgl/programs/circle_program.hpp @@ -21,7 +21,9 @@ class CircleProgram : public Program< gl::Uniforms< uniforms::u_matrix, uniforms::u_scale_with_map, - uniforms::u_extrude_scale>, + uniforms::u_extrude_scale, + uniforms::u_camera_to_center_distance, + uniforms::u_pitch_with_map>, style::CirclePaintProperties> { public: diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index e7c428034b..c11e0b5ca1 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -30,7 +30,6 @@ class TransformState; namespace uniforms { MBGL_DEFINE_UNIFORM_SCALAR(bool, u_rotate_with_map); -MBGL_DEFINE_UNIFORM_SCALAR(bool, u_pitch_with_map); MBGL_DEFINE_UNIFORM_SCALAR(gl::TextureUnit, u_texture); MBGL_DEFINE_UNIFORM_SCALAR(gl::TextureUnit, u_fadetexture); MBGL_DEFINE_UNIFORM_SCALAR(float, u_aspect_ratio); diff --git a/src/mbgl/programs/uniforms.hpp b/src/mbgl/programs/uniforms.hpp index f1b2c2fb54..c8f8684ba1 100644 --- a/src/mbgl/programs/uniforms.hpp +++ b/src/mbgl/programs/uniforms.hpp @@ -33,6 +33,8 @@ MBGL_DEFINE_UNIFORM_SCALAR(float, u_gapwidth); MBGL_DEFINE_UNIFORM_SCALAR(float, u_offset); MBGL_DEFINE_UNIFORM_SCALAR(Size, u_world); MBGL_DEFINE_UNIFORM_SCALAR(Size, u_texsize); +MBGL_DEFINE_UNIFORM_SCALAR(bool, u_pitch_with_map); +MBGL_DEFINE_UNIFORM_SCALAR(float, u_camera_to_center_distance); MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_extrude_scale); diff --git a/src/mbgl/renderer/painters/painter_circle.cpp b/src/mbgl/renderer/painters/painter_circle.cpp index 58e384979d..a077f557fc 100644 --- a/src/mbgl/renderer/painters/painter_circle.cpp +++ b/src/mbgl/renderer/painters/painter_circle.cpp @@ -22,6 +22,7 @@ void Painter::renderCircle(PaintParameters& parameters, const CirclePaintProperties::PossiblyEvaluated& properties = layer.evaluated; const bool scaleWithMap = properties.get() == CirclePitchScaleType::Map; + const bool pitchWithMap = properties.get() == AlignmentType::Map; parameters.programs.circle.get(properties).draw( context, @@ -38,12 +39,13 @@ void Painter::renderCircle(PaintParameters& parameters, state) }, uniforms::u_scale_with_map::Value{ scaleWithMap }, - uniforms::u_extrude_scale::Value{ scaleWithMap + uniforms::u_extrude_scale::Value{ pitchWithMap ? std::array {{ - pixelsToGLUnits[0] * state.getCameraToCenterDistance(), - pixelsToGLUnits[1] * state.getCameraToCenterDistance() - }} - : pixelsToGLUnits } + tile.id.pixelsToTileUnits(1, state.getZoom()), + tile.id.pixelsToTileUnits(1, state.getZoom()) }} + : pixelsToGLUnits }, + uniforms::u_camera_to_center_distance::Value{ state.getCameraToCenterDistance() }, + uniforms::u_pitch_with_map::Value{ pitchWithMap } }, *bucket.vertexBuffer, *bucket.indexBuffer, diff --git a/src/mbgl/shaders/circle.cpp b/src/mbgl/shaders/circle.cpp index 2e0c76122c..953e750776 100644 --- a/src/mbgl/shaders/circle.cpp +++ b/src/mbgl/shaders/circle.cpp @@ -9,7 +9,9 @@ const char* circle::name = "circle"; const char* circle::vertexSource = R"MBGL_SHADER( uniform mat4 u_matrix; uniform bool u_scale_with_map; +uniform bool u_pitch_with_map; uniform vec2 u_extrude_scale; +uniform highp float u_camera_to_center_distance; attribute vec2 a_pos; @@ -121,12 +123,28 @@ void main(void) { // multiply a_pos by 0.5, since we had it * 2 in order to sneak // in extrusion data - gl_Position = u_matrix * vec4(floor(a_pos * 0.5), 0, 1); - - if (u_scale_with_map) { - gl_Position.xy += extrude * (radius + stroke_width) * u_extrude_scale; + vec2 circle_center = floor(a_pos * 0.5); + if (u_pitch_with_map) { + vec2 corner_position = circle_center; + if (u_scale_with_map) { + corner_position += extrude * (radius + stroke_width) * u_extrude_scale; + } else { + // Pitching the circle with the map effectively scales it with the map + // To counteract the effect for pitch-scale: viewport, we rescale the + // whole circle based on the pitch scaling effect at its central point + vec4 projected_center = u_matrix * vec4(circle_center, 0, 1); + corner_position += extrude * (radius + stroke_width) * u_extrude_scale * (projected_center.w / u_camera_to_center_distance); + } + + gl_Position = u_matrix * vec4(corner_position, 0, 1); } else { - gl_Position.xy += extrude * (radius + stroke_width) * u_extrude_scale * gl_Position.w; + gl_Position = u_matrix * vec4(circle_center, 0, 1); + + if (u_scale_with_map) { + gl_Position.xy += extrude * (radius + stroke_width) * u_extrude_scale * u_camera_to_center_distance; + } else { + gl_Position.xy += extrude * (radius + stroke_width) * u_extrude_scale * gl_Position.w; + } } // This is a minimum blur distance that serves as a faux-antialiasing for diff --git a/src/mbgl/style/layers/circle_layer.cpp b/src/mbgl/style/layers/circle_layer.cpp index 3bba135c84..9854932699 100644 --- a/src/mbgl/style/layers/circle_layer.cpp +++ b/src/mbgl/style/layers/circle_layer.cpp @@ -283,6 +283,33 @@ TransitionOptions CircleLayer::getCirclePitchScaleTransition() const { return impl().paint.template get().options; } +PropertyValue CircleLayer::getDefaultCirclePitchAlignment() { + return { AlignmentType::Viewport }; +} + +PropertyValue CircleLayer::getCirclePitchAlignment() const { + return impl().paint.template get().value; +} + +void CircleLayer::setCirclePitchAlignment(PropertyValue value) { + if (value == getCirclePitchAlignment()) + return; + auto impl_ = mutableImpl(); + impl_->paint.template get().value = value; + baseImpl = std::move(impl_); + observer->onLayerChanged(*this); +} + +void CircleLayer::setCirclePitchAlignmentTransition(const TransitionOptions& options) { + auto impl_ = mutableImpl(); + impl_->paint.template get().options = options; + baseImpl = std::move(impl_); +} + +TransitionOptions CircleLayer::getCirclePitchAlignmentTransition() const { + return impl().paint.template get().options; +} + DataDrivenPropertyValue CircleLayer::getDefaultCircleStrokeWidth() { return { 0 }; } diff --git a/src/mbgl/style/layers/circle_layer_properties.hpp b/src/mbgl/style/layers/circle_layer_properties.hpp index 73b7028465..bc0c961e75 100644 --- a/src/mbgl/style/layers/circle_layer_properties.hpp +++ b/src/mbgl/style/layers/circle_layer_properties.hpp @@ -40,6 +40,10 @@ struct CirclePitchScale : PaintProperty { static CirclePitchScaleType defaultValue() { return CirclePitchScaleType::Map; } }; +struct CirclePitchAlignment : PaintProperty { + static AlignmentType defaultValue() { return AlignmentType::Viewport; } +}; + struct CircleStrokeWidth : DataDrivenPaintProperty { static float defaultValue() { return 0; } }; @@ -60,6 +64,7 @@ class CirclePaintProperties : public Properties< CircleTranslate, CircleTranslateAnchor, CirclePitchScale, + CirclePitchAlignment, CircleStrokeWidth, CircleStrokeColor, CircleStrokeOpacity -- cgit v1.2.1 From 9ba3dc92494791fb41b6f20fe11ddd950f381a5f Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Thu, 6 Jul 2017 16:40:04 +0300 Subject: [build] add node-benchmark target and xcode scheme --- Makefile | 8 ++++++++ cmake/node.cmake | 11 +++++++++++ 2 files changed, 19 insertions(+) diff --git a/Makefile b/Makefile index f694d19b52..3a710a1cc1 100644 --- a/Makefile +++ b/Makefile @@ -108,6 +108,14 @@ run-benchmark: run-benchmark-. run-benchmark-%: benchmark $(MACOS_OUTPUT_PATH)/$(BUILDTYPE)/mbgl-benchmark --benchmark_filter=$* +.PHONY: node-benchmark +node-benchmark: $(MACOS_PROJ_PATH) + set -o pipefail && $(MACOS_XCODEBUILD) -scheme 'node-benchmark' build $(XCPRETTY) + +.PHONY: run-node-benchmark +run-node-benchmark: node-benchmark + node platform/node/test/benchmark.js + .PHONY: glfw-app glfw-app: $(MACOS_PROJ_PATH) set -o pipefail && $(MACOS_XCODEBUILD) -scheme 'mbgl-glfw' build $(XCPRETTY) diff --git a/cmake/node.cmake b/cmake/node.cmake index 8626534271..502edd8293 100644 --- a/cmake/node.cmake +++ b/cmake/node.cmake @@ -87,3 +87,14 @@ xcode_create_scheme( "group" "test" ) + +xcode_create_scheme( + TARGET mbgl-node + TYPE node + NAME "node-benchmark" + ARGS + "platform/node/test/benchmark.js" + OPTIONAL_ARGS + "group" + "test" +) -- cgit v1.2.1 From 2fe3dd64c016c676d7aa35c510cf7d96df8b91dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Fri, 30 Jun 2017 00:36:40 -0700 Subject: [core] Updated script detection for Unicode 10 Updated script detection code to reflect changes in Unicode 10 and UTR 50 revision 17. --- src/mbgl/util/i18n.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/mbgl/util/i18n.cpp b/src/mbgl/util/i18n.cpp index ada6f6526c..16f1d669f3 100644 --- a/src/mbgl/util/i18n.cpp +++ b/src/mbgl/util/i18n.cpp @@ -15,7 +15,7 @@ namespace { return codepoint >= first && codepoint <= last; \ } -// The following table comes from . +// The following table comes from . // Keep it synchronized with . // DEFINE_IS_IN_UNICODE_BLOCK(BasicLatin, 0x0000, 0x007F) @@ -37,6 +37,7 @@ DEFINE_IS_IN_UNICODE_BLOCK(ArabicSupplement, 0x0750, 0x077F) // DEFINE_IS_IN_UNICODE_BLOCK(NKo, 0x07C0, 0x07FF) // DEFINE_IS_IN_UNICODE_BLOCK(Samaritan, 0x0800, 0x083F) // DEFINE_IS_IN_UNICODE_BLOCK(Mandaic, 0x0840, 0x085F) +// DEFINE_IS_IN_UNICODE_BLOCK(Syriac Supplement, 0x0860, 0x086F) DEFINE_IS_IN_UNICODE_BLOCK(ArabicExtendedA, 0x08A0, 0x08FF) // DEFINE_IS_IN_UNICODE_BLOCK(Devanagari, 0x0900, 0x097F) // DEFINE_IS_IN_UNICODE_BLOCK(Bengali, 0x0980, 0x09FF) @@ -239,9 +240,12 @@ DEFINE_IS_IN_UNICODE_BLOCK(HalfwidthandFullwidthForms, 0xFF00, 0xFFEF) // DEFINE_IS_IN_UNICODE_BLOCK(Takri, 0x11680, 0x116CF) // DEFINE_IS_IN_UNICODE_BLOCK(Ahom, 0x11700, 0x1173F) // DEFINE_IS_IN_UNICODE_BLOCK(WarangCiti, 0x118A0, 0x118FF) +// DEFINE_IS_IN_UNICODE_BLOCK(ZanabazarSquare, 0x11A00, 0x11A4F) +// DEFINE_IS_IN_UNICODE_BLOCK(Soyombo, 0x11A50, 0x11AAF) // DEFINE_IS_IN_UNICODE_BLOCK(PauCinHau, 0x11AC0, 0x11AFF) // DEFINE_IS_IN_UNICODE_BLOCK(Bhaiksuki, 0x11C00, 0x11C6F) // DEFINE_IS_IN_UNICODE_BLOCK(Marchen, 0x11C70, 0x11CBF) +// DEFINE_IS_IN_UNICODE_BLOCK(MasaramGondi, 0x11D00, 0x11D5F) // DEFINE_IS_IN_UNICODE_BLOCK(Cuneiform, 0x12000, 0x123FF) // DEFINE_IS_IN_UNICODE_BLOCK(CuneiformNumbersandPunctuation, 0x12400, 0x1247F) // DEFINE_IS_IN_UNICODE_BLOCK(EarlyDynasticCuneiform, 0x12480, 0x1254F) @@ -256,6 +260,8 @@ DEFINE_IS_IN_UNICODE_BLOCK(HalfwidthandFullwidthForms, 0xFF00, 0xFFEF) // DEFINE_IS_IN_UNICODE_BLOCK(Tangut, 0x17000, 0x187FF) // DEFINE_IS_IN_UNICODE_BLOCK(TangutComponents, 0x18800, 0x18AFF) // DEFINE_IS_IN_UNICODE_BLOCK(KanaSupplement, 0x1B000, 0x1B0FF) +// DEFINE_IS_IN_UNICODE_BLOCK(KanaExtendedA, 0x1B100, 0x1B12F) +// DEFINE_IS_IN_UNICODE_BLOCK(Nushu, 0x1B170, 0x1B2FF) // DEFINE_IS_IN_UNICODE_BLOCK(Duployan, 0x1BC00, 0x1BC9F) // DEFINE_IS_IN_UNICODE_BLOCK(ShorthandFormatControls, 0x1BCA0, 0x1BCAF) // DEFINE_IS_IN_UNICODE_BLOCK(ByzantineMusicalSymbols, 0x1D000, 0x1D0FF) @@ -286,6 +292,7 @@ DEFINE_IS_IN_UNICODE_BLOCK(HalfwidthandFullwidthForms, 0xFF00, 0xFFEF) // DEFINE_IS_IN_UNICODE_BLOCK(CJKUnifiedIdeographsExtensionC, 0x2A700, 0x2B73F) // DEFINE_IS_IN_UNICODE_BLOCK(CJKUnifiedIdeographsExtensionD, 0x2B740, 0x2B81F) // DEFINE_IS_IN_UNICODE_BLOCK(CJKUnifiedIdeographsExtensionE, 0x2B820, 0x2CEAF) +// DEFINE_IS_IN_UNICODE_BLOCK(CJKUnifiedIdeographsExtensionF, 0x2CEB0, 0x2EBEF) // DEFINE_IS_IN_UNICODE_BLOCK(CJKCompatibilityIdeographsSupplement, 0x2F800, 0x2FA1F) // DEFINE_IS_IN_UNICODE_BLOCK(Tags, 0xE0000, 0xE007F) // DEFINE_IS_IN_UNICODE_BLOCK(VariationSelectorsSupplement, 0xE0100, 0xE01EF) @@ -375,11 +382,13 @@ bool allowsIdeographicBreaking(char16_t chr) { // return (isInTangut(chr) // || isInTangutComponents(chr) // || isInIdeographicSymbolsandPunctuation(chr) + // || isInNushu(chr) // || isInEnclosedIdeographicSupplement(chr) // || isInCJKUnifiedIdeographsExtensionB(chr) // || isInCJKUnifiedIdeographsExtensionC(chr) // || isInCJKUnifiedIdeographsExtensionD(chr) // || isInCJKUnifiedIdeographsExtensionE(chr) + // || isInCJKUnifiedIdeographsExtensionF(chr) // || isInCJKCompatibilityIdeographsSupplement(chr)); } @@ -393,7 +402,7 @@ bool allowsVerticalWritingMode(const std::u16string& string) { } // The following logic comes from -// . +// . // The data file denotes with “U” or “Tu” any codepoint that may be drawn // upright in vertical text but does not distinguish between upright and // “neutral” characters. @@ -457,6 +466,8 @@ bool hasUprightVerticalOrientation(char16_t chr) { // if (isInTangut(chr)) return true; // if (isInTangutComponents(chr)) return true; // if (isInKanaSupplement(chr)) return true; + // if (isInKanaExtendedA(chr)) return true; + // if (isInNushu(chr)) return true; // if (isInByzantineMusicalSymbols(chr)) return true; // if (isInMusicalSymbols(chr)) return true; // if (isInTaiXuanJingSymbols(chr)) return true; @@ -478,6 +489,7 @@ bool hasUprightVerticalOrientation(char16_t chr) { // if (isInCJKUnifiedIdeographsExtensionC(chr)) return true; // if (isInCJKUnifiedIdeographsExtensionD(chr)) return true; // if (isInCJKUnifiedIdeographsExtensionE(chr)) return true; + // if (isInCJKUnifiedIdeographsExtensionF(chr)) return true; // if (isInCJKCompatibilityIdeographsSupplement(chr)) return true; return false; -- cgit v1.2.1 From 957829e8c468a7fc70653f43302a59274be8c752 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Thu, 6 Jul 2017 21:04:30 +0200 Subject: [android] - validate if platform implementation doesn't return a null motion event (#9434) --- .../main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) 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 3607703ab1..17eb506b97 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 @@ -3,7 +3,6 @@ package com.mapbox.mapboxsdk.maps; import android.content.Context; import android.graphics.PointF; import android.location.Location; -import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.view.GestureDetectorCompat; import android.support.v4.view.ScaleGestureDetectorCompat; @@ -134,7 +133,12 @@ final class MapGestureDetector { * @param event the MotionEvent * @return True if touch event is handled */ - boolean onTouchEvent(@NonNull MotionEvent event) { + boolean onTouchEvent(MotionEvent event) { + // framework can return null motion events in edge cases #9432 + if (event == null) { + return false; + } + // Check and ignore non touch or left clicks if ((event.getButtonState() != 0) && (event.getButtonState() != MotionEvent.BUTTON_PRIMARY)) { return false; -- cgit v1.2.1 From 721557bba2fd857974ff0908e2e673f70fd93aef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 6 Jul 2017 21:05:04 +0200 Subject: [android] - map's visible region fix #9427 (#9428) --- .../src/main/java/com/mapbox/mapboxsdk/maps/Projection.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java index ff466c436c..e0a634521b 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java @@ -80,10 +80,10 @@ public class Projection { public VisibleRegion getVisibleRegion() { LatLngBounds.Builder builder = new LatLngBounds.Builder(); - float left = contentPadding[0]; - float right = nativeMapView.getWidth() - contentPadding[2]; - float top = contentPadding[1]; - float bottom = nativeMapView.getHeight() - contentPadding[3]; + float left = 0; + float right = nativeMapView.getWidth(); + float top = 0; + float bottom = nativeMapView.getHeight(); LatLng topLeft = fromScreenLocation(new PointF(left, top)); LatLng topRight = fromScreenLocation(new PointF(right, top)); -- cgit v1.2.1 From 950ab7eb8aed1c288acea128771bd0c5b16eaeff Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 7 Jul 2017 10:36:46 +0200 Subject: [android] - add Map change & visibility test activities (#9425) --- .../src/main/AndroidManifest.xml | 22 ++++ .../activity/maplayout/MapChangeActivity.java | 111 ++++++++++++++++ .../maplayout/VisibilityChangeActivity.java | 146 +++++++++++++++++++++ .../main/res/layout/activity_map_visibility.xml | 17 +++ .../src/main/res/values/strings.xml | 4 + 5 files changed, 300 insertions(+) create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapChangeActivity.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/VisibilityChangeActivity.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_map_visibility.xml diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml index d57136755f..93ac4101d4 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml @@ -414,6 +414,28 @@ android:name="android.support.PARENT_ACTIVITY" android:value=".activity.FeatureOverviewActivity"/> + + + + + + + + mapChangeMap = buildMapChangeStringValueSparseArray(); + mapView = (MapView) findViewById(R.id.mapView); + mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() { + @Override + public void onMapChanged(int change) { + Timber.e("OnMapChange: %s, %s", change, mapChangeMap.get(change)); + } + }); + + mapView.onCreate(savedInstanceState); + mapView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(MapboxMap map) { + mapboxMap = map; + mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom( + new LatLng(55.754020, 37.620948), 12), 9000); + } + }); + } + + private LongSparseArray buildMapChangeStringValueSparseArray() { + LongSparseArray mapChangeArray = new LongSparseArray<>(); + mapChangeArray.put(MapView.REGION_WILL_CHANGE, "Region will change"); + mapChangeArray.put(MapView.REGION_WILL_CHANGE_ANIMATED, "Region will change animated"); + mapChangeArray.put(MapView.REGION_IS_CHANGING, "Region is changing"); + mapChangeArray.put(MapView.REGION_DID_CHANGE, "Region did change"); + mapChangeArray.put(MapView.REGION_DID_CHANGE_ANIMATED, "Region did change animated"); + mapChangeArray.put(MapView.WILL_START_LOADING_MAP, "Will start loading map"); + mapChangeArray.put(MapView.DID_FINISH_LOADING_MAP, "Did finish loading map"); + mapChangeArray.put(MapView.DID_FAIL_LOADING_MAP, "Did fail loading map"); + mapChangeArray.put(MapView.WILL_START_RENDERING_FRAME, "Will start rendering frame"); + mapChangeArray.put(MapView.DID_FINISH_RENDERING_FRAME, "Did finish rendering frame"); + mapChangeArray.put(MapView.DID_FINISH_RENDERING_FRAME_FULLY_RENDERED, "Did finish rendering frame fully rendered"); + mapChangeArray.put(MapView.WILL_START_RENDERING_MAP, "Will start rendering map"); + mapChangeArray.put(MapView.DID_FINISH_RENDERING_MAP, "Did finish rendering map"); + mapChangeArray.put(MapView.DID_FINISH_RENDERING_MAP_FULLY_RENDERED, "Did finish rendering map fully rendered"); + mapChangeArray.put(MapView.DID_FINISH_LOADING_STYLE, "Did finish loading style"); + mapChangeArray.put(MapView.SOURCE_DID_CHANGE, "Source did change"); + return mapChangeArray; + } + + @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() { + super.onDestroy(); + mapView.onDestroy(); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + mapView.onSaveInstanceState(outState); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/VisibilityChangeActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/VisibilityChangeActivity.java new file mode 100644 index 0000000000..393abb7cd4 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/VisibilityChangeActivity.java @@ -0,0 +1,146 @@ +package com.mapbox.mapboxsdk.testapp.activity.maplayout; + +import android.os.Bundle; +import android.os.Handler; +import android.support.v7.app.AppCompatActivity; +import android.view.View; + +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.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.testapp.R; + +/** + * Test activity showcasing visibility changes to the mapview. + */ +public class VisibilityChangeActivity extends AppCompatActivity { + + private MapView mapView; + private MapboxMap mapboxMap; + private Handler handler = new Handler(); + private Runnable runnable; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_map_visibility); + + mapView = (MapView) findViewById(R.id.mapView); + mapView.onCreate(savedInstanceState); + mapView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(MapboxMap map) { + mapboxMap = map; + mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom( + new LatLng(55.754020, 37.620948), 12), 9000); + } + }); + } + + @Override + protected void onStart() { + super.onStart(); + mapView.onStart(); + handler.post(runnable = new VisibilityRunner(mapView, findViewById(R.id.viewParent), handler)); + } + + @Override + protected void onResume() { + super.onResume(); + mapView.onResume(); + } + + private static class VisibilityRunner implements Runnable { + + private MapView mapView; + private View viewParent; + private Handler handler; + private int currentStep; + + VisibilityRunner(MapView mapView, View viewParent, Handler handler) { + this.mapView = mapView; + this.viewParent = viewParent; + this.handler = handler; + } + + @Override + public void run() { + if (isViewHiearchyReady()) { + if (isEvenStep()) { + viewParent.setVisibility(View.VISIBLE); + mapView.setVisibility(View.VISIBLE); + } else if (isFirstOrThirdStep()) { + mapView.setVisibility(getVisibilityForStep()); + } else if (isFifthOrSeventhStep()) { + viewParent.setVisibility(getVisibilityForStep()); + } + updateStep(); + } + handler.postDelayed(this, 1500); + } + + private void updateStep() { + if (currentStep == 7) { + currentStep = 0; + } else { + currentStep++; + } + } + + private int getVisibilityForStep() { + return (currentStep == 1 || currentStep == 5) ? View.GONE : View.INVISIBLE; + } + + private boolean isFifthOrSeventhStep() { + return currentStep == 5 || currentStep == 7; + } + + private boolean isFirstOrThirdStep() { + return currentStep == 1 || currentStep == 3; + } + + private boolean isEvenStep() { + return currentStep == 0 || currentStep % 2 == 0; + } + + private boolean isViewHiearchyReady() { + return mapView != null && viewParent != null; + } + } + + @Override + protected void onPause() { + super.onPause(); + mapView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + if (runnable != null) { + handler.removeCallbacks(runnable); + runnable = null; + } + mapView.onStop(); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapView.onDestroy(); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + mapView.onSaveInstanceState(outState); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_map_visibility.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_map_visibility.xml new file mode 100644 index 0000000000..c33034181c --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_map_visibility.xml @@ -0,0 +1,17 @@ + + + + + + diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml index 7f9a08fd30..09f0c307ab 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml @@ -53,6 +53,8 @@ Add Custom Sprite Android SDK View integration Simple Map + Map Change Events + Visibility Map Dialog with map Marker views in rectangle Url transform @@ -109,6 +111,8 @@ Hightligh buildings in box Query source for features Shows a simple map + Logs map change events to Logcat + Changes visibility of map and view parent Based on zoom level Use a local file as the style Display a map inside a dialog fragment -- cgit v1.2.1 From 2876db72f2d235a02e5670329c4f8dcb2a65a8ed Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 7 Jul 2017 12:28:19 +0200 Subject: Hit test Marker and MarkerViews (#9424) * [android] - hit test Marker and MarkerViews * fixup --- .../mapbox/mapboxsdk/maps/AnnotationManager.java | 201 +++++++++++++-------- .../com/mapbox/mapboxsdk/maps/IconManager.java | 4 + .../mapbox/mapboxsdk/maps/MapGestureDetector.java | 2 +- .../com/mapbox/mapboxsdk/maps/MarkerContainer.java | 1 + .../src/main/res/drawable/ic_check_box.xml | 9 + 5 files changed, 141 insertions(+), 76 deletions(-) create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_check_box.xml diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java index 7e7947047e..f3573c78ba 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java @@ -1,10 +1,13 @@ package com.mapbox.mapboxsdk.maps; +import android.graphics.Bitmap; import android.graphics.PointF; +import android.graphics.Rect; import android.graphics.RectF; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.util.LongSparseArray; +import android.view.View; import com.mapbox.mapboxsdk.annotations.Annotation; import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions; @@ -18,7 +21,6 @@ import com.mapbox.mapboxsdk.annotations.Polyline; import com.mapbox.mapboxsdk.annotations.PolylineOptions; import java.util.ArrayList; -import java.util.Collections; import java.util.List; /** @@ -34,7 +36,6 @@ import java.util.List; */ class AnnotationManager { - private final NativeMapView nativeMapView; private final MapView mapView; private final IconManager iconManager; private final InfoWindowManager infoWindowManager = new InfoWindowManager(); @@ -52,7 +53,6 @@ class AnnotationManager { AnnotationManager(NativeMapView view, MapView mapView, LongSparseArray annotationsArray, MarkerViewManager markerViewManager, IconManager iconManager, Annotations annotations, Markers markers, Polygons polygons, Polylines polylines) { - this.nativeMapView = view; this.mapView = mapView; this.annotationsArray = annotationsArray; this.markerViewManager = markerViewManager; @@ -63,7 +63,7 @@ class AnnotationManager { this.polylines = polylines; if (view != null) { // null checking needed for unit tests - nativeMapView.addOnMapChangedListener(markerViewManager); + view.addOnMapChangedListener(markerViewManager); } } @@ -329,84 +329,135 @@ class AnnotationManager { // Click event // - boolean onTap(PointF tapPoint, float screenDensity) { - float toleranceSides = 4 * screenDensity; - float toleranceTopBottom = 10 * screenDensity; - boolean handledDefaultClick = false; - - RectF tapRect = new RectF(tapPoint.x - iconManager.getAverageIconWidth() / 2 - toleranceSides, - tapPoint.y - iconManager.getAverageIconHeight() / 2 - toleranceTopBottom, - tapPoint.x + iconManager.getAverageIconWidth() / 2 + toleranceSides, - tapPoint.y + iconManager.getAverageIconHeight() / 2 + toleranceTopBottom); - - List nearbyMarkers = getMarkersInRect(tapRect); - long newSelectedMarkerId = -1; - - // find a Marker that isn't selected yet - if (nearbyMarkers.size() > 0) { - Collections.sort(nearbyMarkers); - for (Marker nearbyMarker : nearbyMarkers) { - boolean found = false; - for (Marker selectedMarker : selectedMarkers) { - if (selectedMarker.equals(nearbyMarker)) { - found = true; - } - } - if (!found) { - newSelectedMarkerId = nearbyMarker.getId(); - break; + boolean onTap(PointF tapPoint) { + MarkerHit markerHit = getMarkerHitFromTouchArea(tapPoint); + long markerId = new MarkerHitResolver(markerViewManager, mapboxMap.getProjection()).execute(markerHit); + return markerId >= 0 && isClickHandledForMarker(markerId); + } + + private MarkerHit getMarkerHitFromTouchArea(PointF tapPoint) { + int averageIconWidthOffset = iconManager.getAverageIconWidth() / 2; + int averageIconHeightOffset = iconManager.getAverageIconHeight() / 2; + final RectF tapRect = new RectF(tapPoint.x - averageIconWidthOffset, + tapPoint.y - averageIconHeightOffset, + tapPoint.x + averageIconWidthOffset, + tapPoint.y + averageIconHeightOffset + ); + return new MarkerHit(tapRect, getMarkersInRect(tapRect)); + } + + private boolean isClickHandledForMarker(long markerId) { + boolean handledDefaultClick; + Marker marker = (Marker) getAnnotation(markerId); + if (marker instanceof MarkerView) { + handledDefaultClick = markerViewManager.onClickMarkerView((MarkerView) marker); + } else { + handledDefaultClick = onClickMarker(marker); + } + + if (!handledDefaultClick) { + setMarkerSelectionState(marker); + } + return true; + } + + private boolean onClickMarker(Marker marker) { + return onMarkerClickListener != null && onMarkerClickListener.onMarkerClick(marker); + } + + private void setMarkerSelectionState(Marker marker) { + if (!selectedMarkers.contains(marker)) { + selectMarker(marker); + } else { + deselectMarker(marker); + } + } + + private static class MarkerHitResolver { + + private final MarkerViewManager markerViewManager; + private final Projection projection; + + private View view; + private Bitmap bitmap; + private PointF markerLocation; + + private Rect hitRectView = new Rect(); + private RectF hitRectMarker = new RectF(); + private RectF highestSurfaceIntersection = new RectF(); + + private long closestMarkerId = -1; + + MarkerHitResolver(@NonNull MarkerViewManager markerViewManager, @NonNull Projection projection) { + this.markerViewManager = markerViewManager; + this.projection = projection; + } + + public long execute(MarkerHit markerHit) { + resolveForMarkers(markerHit); + return closestMarkerId; + } + + private void resolveForMarkers(MarkerHit markerHit) { + for (Marker marker : markerHit.markers) { + if (marker instanceof MarkerView) { + resolveForMarkerView(markerHit, (MarkerView) marker); + } else { + resolveForMarker(markerHit, marker); } } } - // if unselected marker found - if (newSelectedMarkerId >= 0) { - List annotations = getAnnotations(); - int count = annotations.size(); - for (int i = 0; i < count; i++) { - Annotation annotation = annotations.get(i); - if (annotation instanceof Marker) { - if (annotation.getId() == newSelectedMarkerId) { - Marker marker = (Marker) annotation; - - if (marker instanceof MarkerView) { - handledDefaultClick = markerViewManager.onClickMarkerView((MarkerView) marker); - } else { - if (onMarkerClickListener != null) { - // end developer has provided a custom click listener - handledDefaultClick = onMarkerClickListener.onMarkerClick(marker); - } - } - - if (!handledDefaultClick) { - // only select marker if user didn't handle the click event themselves - selectMarker(marker); - } - - return true; - } - } + private void resolveForMarkerView(MarkerHit markerHit, MarkerView markerView) { + view = markerViewManager.getView(markerView); + if (view != null) { + view.getHitRect(hitRectView); + hitRectMarker = new RectF(hitRectView); + hitTestMarker(markerHit, markerView, hitRectMarker); } - } else if (nearbyMarkers.size() > 0) { - // we didn't find an unselected marker, check if we can close an already open markers - for (Marker nearbyMarker : nearbyMarkers) { - for (Marker selectedMarker : selectedMarkers) { - if (nearbyMarker.equals(selectedMarker)) { - if (nearbyMarker instanceof MarkerView) { - handledDefaultClick = markerViewManager.onClickMarkerView((MarkerView) nearbyMarker); - } else if (onMarkerClickListener != null) { - handledDefaultClick = onMarkerClickListener.onMarkerClick(nearbyMarker); - } - - if (!handledDefaultClick) { - // only deselect marker if user didn't handle the click event themselves - deselectMarker(nearbyMarker); - } - return true; - } + } + + private void resolveForMarker(MarkerHit markerHit, Marker marker) { + markerLocation = projection.toScreenLocation(marker.getPosition()); + bitmap = marker.getIcon().getBitmap(); + hitRectMarker.set(0, 0, bitmap.getWidth(), bitmap.getHeight()); + hitRectMarker.offsetTo( + markerLocation.x - bitmap.getWidth() / 2, + markerLocation.y - bitmap.getHeight() / 2 + ); + hitTestMarker(markerHit, marker, hitRectMarker); + } + + private void hitTestMarker(MarkerHit markerHit, Marker marker, RectF hitRectMarker) { + if (hitRectMarker.contains(markerHit.getTapPointX(), markerHit.getTapPointY())) { + hitRectMarker.intersect(markerHit.tapRect); + if (isRectangleHighestSurfaceIntersection(hitRectMarker)) { + highestSurfaceIntersection = new RectF(hitRectMarker); + closestMarkerId = marker.getId(); } } } - return false; + + private boolean isRectangleHighestSurfaceIntersection(RectF rectF) { + return rectF.width() * rectF.height() > highestSurfaceIntersection.width() * highestSurfaceIntersection.height(); + } + } + + private static class MarkerHit { + private final RectF tapRect; + private final List markers; + + MarkerHit(RectF tapRect, List markers) { + this.tapRect = tapRect; + this.markers = markers; + } + + float getTapPointX() { + return tapRect.centerX(); + } + + float getTapPointY() { + return tapRect.centerY(); + } } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java index 9f4171aee8..b5da5f59aa 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java @@ -12,6 +12,8 @@ import com.mapbox.mapboxsdk.exceptions.IconBitmapChangedException; import java.util.ArrayList; import java.util.List; +import timber.log.Timber; + /** * Responsible for managing icons added to the Map. *

      @@ -105,6 +107,8 @@ class IconManager { int iconSize = icons.size() + 1; averageIconHeight = averageIconHeight + (height - averageIconHeight) / iconSize; averageIconWidth = averageIconWidth + (width - averageIconWidth) / iconSize; + Timber.e("OnUpdateAverageSizeIcon with: %s %s", width, height); + Timber.e("OnUpdateAverageSizeIcon now: %s %s", averageIconWidth, averageIconHeight); } private void loadIcon(Icon icon) { 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 17eb506b97..330e09cf32 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 @@ -315,7 +315,7 @@ final class MapGestureDetector { @Override public boolean onSingleTapConfirmed(MotionEvent motionEvent) { PointF tapPoint = new PointF(motionEvent.getX(), motionEvent.getY()); - boolean tapHandled = annotationManager.onTap(tapPoint, uiSettings.getPixelRatio()); + boolean tapHandled = annotationManager.onTap(tapPoint); if (!tapHandled) { if (uiSettings.isDeselectMarkersOnTap()) { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MarkerContainer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MarkerContainer.java index 306ad59b8d..ef8054d70e 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MarkerContainer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MarkerContainer.java @@ -261,6 +261,7 @@ class MarkerContainer implements Markers { if (icon == null) { icon = IconFactory.getInstance(mapView.getContext()).defaultMarkerView(); } + iconManager.loadIconForMarkerView(marker); marker.setIcon(icon); return marker; } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_check_box.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_check_box.xml new file mode 100644 index 0000000000..cf8bfa24b5 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_check_box.xml @@ -0,0 +1,9 @@ + + + -- cgit v1.2.1 From 407fbc70b1dc6dab6b7aa5a4b9c57b4e08906c79 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Sun, 15 Jan 2017 11:27:52 -0500 Subject: [core] Prefetch low resolution tiles --- include/mbgl/map/map.hpp | 9 +++++++++ include/mbgl/util/constants.hpp | 2 ++ src/mbgl/map/map.cpp | 15 ++++++++++++++- src/mbgl/renderer/render_style.cpp | 3 ++- src/mbgl/renderer/tile_parameters.hpp | 1 + src/mbgl/renderer/tile_pyramid.cpp | 28 ++++++++++++++++++++++++++-- src/mbgl/renderer/update_parameters.hpp | 2 ++ 7 files changed, 56 insertions(+), 4 deletions(-) diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index 1b45c87c28..158e9d733d 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -156,6 +156,15 @@ public: AnnotationIDs queryPointAnnotations(const ScreenBox&); + // Tile prefetching + // + // When loading a map, if `PrefetchZoomDelta` is set to any number greater than 0, the map will + // first request a tile for `zoom = getZoom() - delta` in a attempt to display a full map at + // lower resolution as quick as possible. It will get clamped at the tile source minimum zoom. + // The default `delta` is 4. + void setPrefetchZoomDelta(uint8_t delta); + uint8_t getPrefetchZoomDelta() const; + // Memory void onLowMemory(); diff --git a/include/mbgl/util/constants.hpp b/include/mbgl/util/constants.hpp index 14aaa752bc..c2250c6f2e 100644 --- a/include/mbgl/util/constants.hpp +++ b/include/mbgl/util/constants.hpp @@ -38,6 +38,8 @@ constexpr double MAX_ZOOM = 25.5; constexpr float MIN_ZOOM_F = MIN_ZOOM; constexpr float MAX_ZOOM_F = MAX_ZOOM; +constexpr uint8_t DEFAULT_PREFETCH_ZOOM_DELTA = 4; + constexpr uint64_t DEFAULT_MAX_CACHE_SIZE = 50 * 1024 * 1024; constexpr Duration DEFAULT_TRANSITION_DURATION = Milliseconds(300); diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 034e43f260..565d39c515 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -92,6 +93,9 @@ public: std::unique_ptr renderStyle; bool cameraMutated = false; + + uint8_t prefetchZoomDelta = util::DEFAULT_PREFETCH_ZOOM_DELTA; + bool loading = false; util::AsyncTask asyncInvalidate; @@ -245,7 +249,8 @@ void Map::Impl::render(View& view) { style->impl->getLayerImpls(), scheduler, fileSource, - annotationManager + annotationManager, + prefetchZoomDelta }); bool loaded = style->impl->isLoaded() && renderStyle->isLoaded(); @@ -823,6 +828,14 @@ bool Map::isFullyLoaded() const { return impl->style->impl->isLoaded() && impl->renderStyle && impl->renderStyle->isLoaded(); } +void Map::setPrefetchZoomDelta(uint8_t delta) { + impl->prefetchZoomDelta = delta; +} + +uint8_t Map::getPrefetchZoomDelta() const { + return impl->prefetchZoomDelta; +} + void Map::onLowMemory() { if (impl->painter) { BackendScope guard(impl->backend); diff --git a/src/mbgl/renderer/render_style.cpp b/src/mbgl/renderer/render_style.cpp index bae879dca7..aacabe563d 100644 --- a/src/mbgl/renderer/render_style.cpp +++ b/src/mbgl/renderer/render_style.cpp @@ -105,7 +105,8 @@ void RenderStyle::update(const UpdateParameters& parameters) { parameters.mode, parameters.annotationManager, *imageManager, - *glyphManager + *glyphManager, + parameters.prefetchZoomDelta }; glyphManager->setURL(parameters.glyphURL); diff --git a/src/mbgl/renderer/tile_parameters.hpp b/src/mbgl/renderer/tile_parameters.hpp index cf7a5b100a..9769ae6897 100644 --- a/src/mbgl/renderer/tile_parameters.hpp +++ b/src/mbgl/renderer/tile_parameters.hpp @@ -22,6 +22,7 @@ public: AnnotationManager& annotationManager; ImageManager& imageManager; GlyphManager& glyphManager; + const uint8_t prefetchZoomDelta = 0; }; } // namespace mbgl diff --git a/src/mbgl/renderer/tile_pyramid.cpp b/src/mbgl/renderer/tile_pyramid.cpp index caf55d64e8..a8e6c128ba 100644 --- a/src/mbgl/renderer/tile_pyramid.cpp +++ b/src/mbgl/renderer/tile_pyramid.cpp @@ -88,14 +88,30 @@ void TilePyramid::update(const std::vector>& layer // Determine the overzooming/underzooming amounts and required tiles. int32_t overscaledZoom = util::coveringZoomLevel(parameters.transformState.getZoom(), type, tileSize); int32_t tileZoom = overscaledZoom; + int32_t panZoom = zoomRange.max; std::vector idealTiles; + std::vector panTiles; + if (overscaledZoom >= zoomRange.min) { int32_t idealZoom = std::min(zoomRange.max, overscaledZoom); // Make sure we're not reparsing overzoomed raster tiles. if (type == SourceType::Raster) { tileZoom = idealZoom; + + // FIXME: Prefetching is only enabled for raster + // tiles until we fix #7026. + + // Request lower zoom level tiles (if configure to do so) in an attempt + // to show something on the screen faster at the cost of a little of bandwidth. + if (parameters.prefetchZoomDelta) { + panZoom = std::max(tileZoom - parameters.prefetchZoomDelta, zoomRange.min); + } + + if (panZoom < tileZoom) { + panTiles = util::tileCover(parameters.transformState, panZoom); + } } idealTiles = util::tileCover(parameters.transformState, idealZoom); @@ -108,8 +124,10 @@ void TilePyramid::update(const std::vector>& layer std::set retain; auto retainTileFn = [&](Tile& tile, Resource::Necessity necessity) -> void { - retain.emplace(tile.id); - tile.setNecessity(necessity); + if (retain.emplace(tile.id).second) { + tile.setNecessity(necessity); + } + if (needsRelayout) { tile.setLayers(layers); } @@ -137,6 +155,12 @@ void TilePyramid::update(const std::vector>& layer }; renderTiles.clear(); + + if (!panTiles.empty()) { + algorithm::updateRenderables(getTileFn, createTileFn, retainTileFn, + [](const UnwrappedTileID&, Tile&) {}, panTiles, zoomRange, panZoom); + } + algorithm::updateRenderables(getTileFn, createTileFn, retainTileFn, renderTileFn, idealTiles, zoomRange, tileZoom); diff --git a/src/mbgl/renderer/update_parameters.hpp b/src/mbgl/renderer/update_parameters.hpp index ce79a4f31b..8ebcd11e21 100644 --- a/src/mbgl/renderer/update_parameters.hpp +++ b/src/mbgl/renderer/update_parameters.hpp @@ -33,6 +33,8 @@ public: Scheduler& scheduler; FileSource& fileSource; AnnotationManager& annotationManager; + + const uint8_t prefetchZoomDelta = 0; }; } // namespace mbgl -- cgit v1.2.1 From 69c8f602de9ab087dd841dfabf33a72d46672673 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Tue, 24 Jan 2017 14:39:08 +0200 Subject: [tests] Add unit test for tile prefetching --- cmake/test-files.cmake | 1 + test/fixtures/map/prefetch/empty.json | 5 ++ test/fixtures/map/prefetch/expected.png | Bin 0 -> 2198 bytes test/fixtures/map/prefetch/style.json | 24 ++++++++ test/fixtures/map/prefetch/tile_green.png | Bin 0 -> 659 bytes test/fixtures/map/prefetch/tile_red.png | Bin 0 -> 659 bytes test/map/prefetch.test.cpp | 93 ++++++++++++++++++++++++++++++ 7 files changed, 123 insertions(+) create mode 100644 test/fixtures/map/prefetch/empty.json create mode 100644 test/fixtures/map/prefetch/expected.png create mode 100644 test/fixtures/map/prefetch/style.json create mode 100644 test/fixtures/map/prefetch/tile_green.png create mode 100644 test/fixtures/map/prefetch/tile_red.png create mode 100644 test/map/prefetch.test.cpp diff --git a/cmake/test-files.cmake b/cmake/test-files.cmake index edbf100fe2..4dec9e403d 100644 --- a/cmake/test-files.cmake +++ b/cmake/test-files.cmake @@ -28,6 +28,7 @@ set(MBGL_TEST_FILES # map test/map/map.test.cpp + test/map/prefetch.test.cpp test/map/transform.test.cpp # math diff --git a/test/fixtures/map/prefetch/empty.json b/test/fixtures/map/prefetch/empty.json new file mode 100644 index 0000000000..61a8fadcdb --- /dev/null +++ b/test/fixtures/map/prefetch/empty.json @@ -0,0 +1,5 @@ +{ + "version": 8, + "sources": {}, + "layers": [] +} diff --git a/test/fixtures/map/prefetch/expected.png b/test/fixtures/map/prefetch/expected.png new file mode 100644 index 0000000000..e1111b37f7 Binary files /dev/null and b/test/fixtures/map/prefetch/expected.png differ diff --git a/test/fixtures/map/prefetch/style.json b/test/fixtures/map/prefetch/style.json new file mode 100644 index 0000000000..b4e163888c --- /dev/null +++ b/test/fixtures/map/prefetch/style.json @@ -0,0 +1,24 @@ +{ + "version": 8, + "name": "Test", + "sources": { + "raster": { + "type": "raster", + "tiles": [ "{z}" ], + "tileSize": 256, + "maxzoom": 20, + "minzoom": 0 + } + }, + "layers": [{ + "id": "background", + "type": "background", + "paint": { + "background-color": "blue" + } + }, { + "id": "raster", + "type": "raster", + "source": "raster" + }] +} diff --git a/test/fixtures/map/prefetch/tile_green.png b/test/fixtures/map/prefetch/tile_green.png new file mode 100644 index 0000000000..553cd10cd1 Binary files /dev/null and b/test/fixtures/map/prefetch/tile_green.png differ diff --git a/test/fixtures/map/prefetch/tile_red.png b/test/fixtures/map/prefetch/tile_red.png new file mode 100644 index 0000000000..5fa561fb92 Binary files /dev/null and b/test/fixtures/map/prefetch/tile_red.png differ diff --git a/test/map/prefetch.test.cpp b/test/map/prefetch.test.cpp new file mode 100644 index 0000000000..af2cd4e92f --- /dev/null +++ b/test/map/prefetch.test.cpp @@ -0,0 +1,93 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace mbgl; +using namespace mbgl::style; +using namespace std::literals::string_literals; + +TEST(Map, PrefetchTiles) { + util::RunLoop runLoop; + HeadlessBackend backend(test::sharedDisplay()); + BackendScope scope(backend); + OffscreenView view(backend.getContext(), { 512, 512 }); + ThreadPool threadPool(4); + StubFileSource fileSource; + Map map(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still); + + std::vector tiles; + + fileSource.response = [&] (const Resource& res) -> optional { + Response response; + + auto zoom = std::stoi(res.url); + tiles.push_back(zoom); + + // Return a red tile for prefetched tiles or green to the actual tile. + // The end rendering result should be all green because the map is only + // considered fully rendered when only ideal tiles are shown. + if (zoom == int(map.getZoom()) + 1) { + response.data = std::make_shared( + util::read_file("test/fixtures/map/prefetch/tile_green.png")); + } else { + response.data = std::make_shared( + util::read_file("test/fixtures/map/prefetch/tile_red.png")); + } + + return { std::move(response) }; + }; + + auto checkTilesForZoom = [&](int zoom, const std::vector& expected) { + tiles.clear(); + + // Force tile reloading. + map.getStyle().loadJSON(util::read_file("test/fixtures/map/prefetch/empty.json")); + map.getStyle().loadJSON(util::read_file("test/fixtures/map/prefetch/style.json")); + + map.setLatLngZoom({ 40.726989, -73.992857 }, zoom); // Manhattan + + // Should always render the ideal tiles (i.e. a green map) + test::checkImage("test/fixtures/map/prefetch", test::render(map, view)); + + ASSERT_TRUE(std::is_permutation(tiles.begin(), tiles.end(), expected.begin())); + ASSERT_FALSE(tiles.empty()); + }; + + // Check defaults, should be 4. + ASSERT_EQ(map.getPrefetchZoomDelta(), 4); + checkTilesForZoom(12, { 13, 13, 13, 13, 13, 13, 13, 13, 13, 9 }); + + // Setting it to 0 disables prefetching. + map.setPrefetchZoomDelta(0); + + // No prefetching, raster tiles will use ideal + // tiles instead of the actual zoom level, that is + // why the zoom levels for non-prefetched tiles are + // not the same. + checkTilesForZoom(10, { 11, 11, 11, 11, 11, 11, 11, 11, 11 }); + + map.setPrefetchZoomDelta(5); + checkTilesForZoom(12, { 13, 13, 13, 13, 13, 13, 13, 13, 13, 8 }); + + // Should clamp at `minzoom`. + map.setPrefetchZoomDelta(20); + checkTilesForZoom(10, { 11, 11, 11, 11, 11, 11, 11, 11, 11, 0 }); + + // Disabled again. + map.setPrefetchZoomDelta(0); + checkTilesForZoom(13, { 14, 14, 14, 14, 14, 14, 14, 14, 14 }); +} -- cgit v1.2.1 From e962b79b0f434ab80556cede425bdc1daf7730b2 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Thu, 6 Jul 2017 15:49:22 +0200 Subject: [core] Fix sorting order for render tiles Sort by z order, so lower res tiles don't get rendered over high res tiles. --- src/mbgl/renderer/render_style.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mbgl/renderer/render_style.cpp b/src/mbgl/renderer/render_style.cpp index aacabe563d..25dbba76f6 100644 --- a/src/mbgl/renderer/render_style.cpp +++ b/src/mbgl/renderer/render_style.cpp @@ -326,6 +326,9 @@ RenderData RenderStyle::getRenderData(MapDebugOptions debugOptions, float angle) return std::tie(par.y, par.x) < std::tie(pbr.y, pbr.x); }); + } else { + std::sort(sortedTiles.begin(), sortedTiles.end(), + [](const auto& a, const auto& b) { return a.get().id < b.get().id; }); } std::vector> sortedTilesForInsertion; -- cgit v1.2.1 From f734126416ee9748d66d439918471b2c1a0019a5 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Fri, 7 Jul 2017 16:36:13 +0300 Subject: [core] Fix conditional unitialized jump on RenderGeoJSONSource ``` ==24942== Conditional jump or move depends on uninitialised value(s) ==24942== at 0x7D943D: mbgl::RenderGeoJSONSource::update(mbgl::Immutable, std::vector, std::allocator > > const&, bool, bool, mbgl::TileParameters const&) (in /home/tmpsantos/Projects/mapbox-gl-native/build/linux-x86_64/Release/mbgl-test) ==24942== by 0x796445: mbgl::RenderStyle::update(mbgl::UpdateParameters const&) (in /home/tmpsantos/Projects/mapbox-gl-native/build/linux-x86_64/Release/mbgl-test) ==24942== by 0x77E29D: mbgl::Map::Impl::render(mbgl::View&) (in /home/tmpsantos/Projects/mapbox-gl-native/build/linux-x86_64/Release/mbgl-test) ==24942== by 0x77E559: mbgl::Map::Impl::renderStill() (in /home/tmpsantos/Projects/mapbox-gl-native/build/linux-x86_64/Release/mbgl-test) ==24942== by 0xA39772: uv__async_event (async.c:98) ==24942== by 0xA398F8: uv__async_io (async.c:138) ==24942== by 0xA4375F: uv__io_poll (linux-core.c:380) ==24942== by 0xA3A1F2: uv_run (core.c:354) ==24942== by 0x61BADC: API_ZoomHistory_Test::TestBody() (in /home/tmpsantos/Projects/mapbox-gl-native/build/linux-x86_64/Release/mbgl-test) ==24942== by 0x89FDE9: void testing::internal::HandleExceptionsInMethodIfSupported(testing::Test*, void (testing::Test::*)(), char const*) (in /home/tmpsantos/Projects/mapbox-gl-native/build/linux-x86_64/Release/mbgl-test) ==24942== by 0x885450: testing::Test::Run() (in /home/tmpsantos/Projects/mapbox-gl-native/build/linux-x86_64/Release/mbgl-test) ==24942== by 0x88642F: testing::TestInfo::Run() (in /home/tmpsantos/Projects/mapbox-gl-native/build/linux-x86_64/Release/mbgl-test) ==24942== ``` --- src/mbgl/renderer/sources/render_geojson_source.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mbgl/renderer/sources/render_geojson_source.hpp b/src/mbgl/renderer/sources/render_geojson_source.hpp index 8d4154112f..bb390a71e3 100644 --- a/src/mbgl/renderer/sources/render_geojson_source.hpp +++ b/src/mbgl/renderer/sources/render_geojson_source.hpp @@ -43,7 +43,7 @@ private: const style::GeoJSONSource::Impl& impl() const; TilePyramid tilePyramid; - style::GeoJSONData* data; + style::GeoJSONData* data = nullptr; }; template <> -- cgit v1.2.1 From 6b5f8fd6ef845fbf834968d94ec26cf26f645838 Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Fri, 7 Jul 2017 15:57:48 +0300 Subject: [benchmark] update cache db and style --- benchmark/fixtures/api/cache.db | Bin 405504 -> 1298432 bytes benchmark/fixtures/api/query_style.json | 15298 ++++++++---------------------- 2 files changed, 3989 insertions(+), 11309 deletions(-) diff --git a/benchmark/fixtures/api/cache.db b/benchmark/fixtures/api/cache.db index a62a3b0f00..c2ada1fbd5 100644 Binary files a/benchmark/fixtures/api/cache.db and b/benchmark/fixtures/api/cache.db differ diff --git a/benchmark/fixtures/api/query_style.json b/benchmark/fixtures/api/query_style.json index 54899c3951..cf88aeb6ed 100644 --- a/benchmark/fixtures/api/query_style.json +++ b/benchmark/fixtures/api/query_style.json @@ -1,11313 +1,3993 @@ { - "created": 0, - "draft": false, - "glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf", - "id": "streets-v9", - "layers": [ - { - "id": "background", - "layout": {}, - "paint": { - "background-color": { - "base": 1, - "stops": [ - [ - 11, - "hsl(35, 32%, 91%)" - ], - [ - 13, - "hsl(35, 12%, 89%)" - ] - ] - } - }, - "type": "background" - }, - { - "filter": [ - "==", - "class", - "snow" - ], - "id": "landcover_snow", - "layout": {}, - "metadata": { - "mapbox:group": "1456970288113.8113" - }, - "paint": { - "fill-antialias": false, - "fill-color": "hsl(0, 0%, 100%)", - "fill-opacity": 0.2 - }, - "source": "composite", - "source-layer": "landcover", - "type": "fill" - }, - { - "filter": [ - "==", - "class", - "wood" - ], - "id": "landcover_wood", - "layout": {}, - "maxzoom": 14, - "metadata": { - "mapbox:group": "1456970288113.8113" - }, - "paint": { - "fill-antialias": false, - "fill-color": "hsl(75, 62%, 81%)", - "fill-opacity": { - "base": 1.5, - "stops": [ - [ - 2, - 0.3 - ], - [ - 7, - 0 - ] - ] - } - }, - "source": "composite", - "source-layer": "landcover", - "type": "fill" - }, - { - "filter": [ - "==", - "class", - "scrub" - ], - "id": "landcover_scrub", - "layout": {}, - "maxzoom": 14, - "metadata": { - "mapbox:group": "1456970288113.8113" - }, - "paint": { - "fill-antialias": false, - "fill-color": "hsl(75, 62%, 81%)", - "fill-opacity": { - "base": 1.5, - "stops": [ - [ - 2, - 0.3 - ], - [ - 7, - 0 - ] - ] - } - }, - "source": "composite", - "source-layer": "landcover", - "type": "fill" - }, - { - "filter": [ - "==", - "class", - "grass" - ], - "id": "landcover_grass", - "layout": {}, - "maxzoom": 14, - "metadata": { - "mapbox:group": "1456970288113.8113" - }, - "paint": { - "fill-antialias": false, - "fill-color": "hsl(75, 62%, 81%)", - "fill-opacity": { - "base": 1.5, - "stops": [ - [ - 2, - 0.3 - ], - [ - 7, - 0 - ] - ] - } - }, - "source": "composite", - "source-layer": "landcover", - "type": "fill" - }, - { - "filter": [ - "==", - "class", - "crop" - ], - "id": "landcover_crop", - "layout": {}, - "maxzoom": 14, - "metadata": { - "mapbox:group": "1456970288113.8113" - }, - "paint": { - "fill-antialias": false, - "fill-color": "hsl(75, 62%, 81%)", - "fill-opacity": { - "base": 1.5, - "stops": [ - [ - 2, - 0.3 - ], - [ - 7, - 0 - ] - ] - } - }, - "source": "composite", - "source-layer": "landcover", - "type": "fill" - }, - { - "filter": [ - "==", - "class", - "national_park" - ], - "id": "national_park", - "layout": {}, - "paint": { - "fill-color": "hsl(100, 58%, 76%)", - "fill-opacity": { - "base": 1, - "stops": [ - [ - 5, - 0 - ], - [ - 6, - 0.5 - ] - ] - } - }, - "source": "composite", - "source-layer": "landuse_overlay", - "type": "fill" - }, - { - "filter": [ - "==", - "class", - "hospital" - ], - "id": "hospital", - "layout": {}, - "paint": { - "fill-color": { - "base": 1, - "stops": [ - [ - 15.5, - "hsl(340, 37%, 87%)" - ], - [ - 16, - "hsl(340, 63%, 89%)" - ] - ] - } - }, - "source": "composite", - "source-layer": "landuse", - "type": "fill" - }, - { - "filter": [ - "==", - "class", - "school" - ], - "id": "school", - "layout": {}, - "paint": { - "fill-color": { - "base": 1, - "stops": [ - [ - 15.5, - "hsl(50, 47%, 81%)" - ], - [ - 16, - "hsl(50, 63%, 84%)" - ] - ] - } - }, - "source": "composite", - "source-layer": "landuse", - "type": "fill" - }, - { - "filter": [ - "==", - "class", - "park" - ], - "id": "park", - "layout": {}, - "paint": { - "fill-color": "hsl(100, 58%, 76%)", - "fill-opacity": { - "base": 1, - "stops": [ - [ - 5, - 0 - ], - [ - 6, - 1 - ] - ] - } - }, - "source": "composite", - "source-layer": "landuse", - "type": "fill" - }, - { - "filter": [ - "==", - "class", - "pitch" - ], - "id": "pitch", - "layout": {}, - "paint": { - "fill-color": "hsl(100, 57%, 72%)" - }, - "source": "composite", - "source-layer": "landuse", - "type": "fill" - }, - { - "filter": [ - "==", - "class", - "pitch" - ], - "id": "pitch-line", - "layout": { - "line-join": "miter" - }, - "minzoom": 15, - "paint": { - "line-color": "hsl(75, 57%, 84%)" - }, - "source": "composite", - "source-layer": "landuse", - "type": "line" - }, - { - "filter": [ - "==", - "class", - "cemetery" - ], - "id": "cemetery", - "layout": {}, - "paint": { - "fill-color": "hsl(75, 37%, 81%)" - }, - "source": "composite", - "source-layer": "landuse", - "type": "fill" - }, - { - "filter": [ - "==", - "class", - "industrial" - ], - "id": "industrial", - "layout": {}, - "paint": { - "fill-color": { - "base": 1, - "stops": [ - [ - 15.5, - "hsl(230, 15%, 86%)" - ], - [ - 16, - "hsl(230, 29%, 89%)" - ] - ] - } - }, - "source": "composite", - "source-layer": "landuse", - "type": "fill" - }, - { - "filter": [ - "==", - "class", - "sand" - ], - "id": "sand", - "layout": {}, - "paint": { - "fill-color": "hsl(60, 46%, 87%)" - }, - "source": "composite", - "source-layer": "landuse", - "type": "fill" - }, - { - "filter": [ - "==", - "level", - 94 - ], - "id": "hillshade_highlight_bright", - "layout": {}, - "maxzoom": 16, - "metadata": { - "mapbox:group": "1456969573402.7817" - }, - "paint": { - "fill-antialias": false, - "fill-color": "hsl(0, 0%, 100%)", - "fill-opacity": { - "stops": [ - [ - 14, - 0.12 - ], - [ - 16, - 0 - ] - ] - } - }, - "source": "composite", - "source-layer": "hillshade", - "type": "fill" - }, - { - "filter": [ - "==", - "level", - 90 - ], - "id": "hillshade_highlight_med", - "layout": {}, - "maxzoom": 16, - "metadata": { - "mapbox:group": "1456969573402.7817" - }, - "paint": { - "fill-antialias": false, - "fill-color": "hsl(0, 0%, 100%)", - "fill-opacity": { - "stops": [ - [ - 14, - 0.12 - ], - [ - 16, - 0 - ] - ] - } - }, - "source": "composite", - "source-layer": "hillshade", - "type": "fill" - }, - { - "filter": [ - "==", - "level", - 89 - ], - "id": "hillshade_shadow_faint", - "layout": {}, - "maxzoom": 16, - "metadata": { - "mapbox:group": "1456969573402.7817" - }, - "paint": { - "fill-antialias": false, - "fill-color": "hsl(56, 59%, 22%)", - "fill-opacity": { - "stops": [ - [ - 14, - 0.05 - ], - [ - 16, - 0 - ] - ] - } - }, - "source": "composite", - "source-layer": "hillshade", - "type": "fill" - }, - { - "filter": [ - "==", - "level", - 78 - ], - "id": "hillshade_shadow_med", - "layout": {}, - "maxzoom": 16, - "metadata": { - "mapbox:group": "1456969573402.7817" - }, - "paint": { - "fill-antialias": false, - "fill-color": "hsl(56, 59%, 22%)", - "fill-opacity": { - "stops": [ - [ - 14, - 0.05 - ], - [ - 16, - 0 - ] - ] - } - }, - "source": "composite", - "source-layer": "hillshade", - "type": "fill" - }, - { - "filter": [ - "==", - "level", - 67 - ], - "id": "hillshade_shadow_dark", - "layout": {}, - "maxzoom": 16, - "metadata": { - "mapbox:group": "1456969573402.7817" - }, - "paint": { - "fill-antialias": false, - "fill-color": "hsl(56, 59%, 22%)", - "fill-opacity": { - "stops": [ - [ - 14, - 0.06 - ], - [ - 16, - 0 - ] - ] - } - }, - "source": "composite", - "source-layer": "hillshade", - "type": "fill" - }, - { - "filter": [ - "==", - "level", - 56 - ], - "id": "hillshade_shadow_extreme", - "layout": {}, - "maxzoom": 16, - "metadata": { - "mapbox:group": "1456969573402.7817" - }, - "paint": { - "fill-antialias": false, - "fill-color": "hsl(56, 59%, 22%)", - "fill-opacity": { - "stops": [ - [ - 14, - 0.06 - ], - [ - 16, - 0 - ] - ] - } - }, - "source": "composite", - "source-layer": "hillshade", - "type": "fill" - }, - { - "filter": [ - "in", - "class", - "canal", - "river" - ], - "id": "waterway-river-canal", - "layout": { - "line-cap": { - "base": 1, - "stops": [ - [ - 0, - "butt" - ], - [ - 11, - "round" - ] - ] - }, - "line-join": "round" - }, - "minzoom": 8, - "paint": { - "line-color": "hsl(205, 87%, 76%)", - "line-opacity": { - "base": 1, - "stops": [ - [ - 8, - 0 - ], - [ - 8.5, - 1 - ] - ] - }, - "line-width": { - "base": 1.3, - "stops": [ - [ - 8.5, - 0.1 - ], - [ - 20, - 8 - ] - ] - } - }, - "source": "composite", - "source-layer": "waterway", - "type": "line" - }, - { - "filter": [ - "!in", - "class", - "canal", - "river" - ], - "id": "waterway-small", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "minzoom": 13, - "paint": { - "line-color": "hsl(205, 87%, 76%)", - "line-opacity": { - "base": 1, - "stops": [ - [ - 13, - 0 - ], - [ - 13.5, - 1 - ] - ] - }, - "line-width": { - "base": 1.35, - "stops": [ - [ - 13.5, - 0.1 - ], - [ - 20, - 3 - ] - ] - } - }, - "source": "composite", - "source-layer": "waterway", - "type": "line" - }, - { - "id": "water-shadow", - "layout": {}, - "paint": { - "fill-color": "hsl(215, 84%, 69%)", - "fill-opacity": 1, - "fill-translate": { - "base": 1.2, - "stops": [ - [ - 7, - [ - 0, - 0 - ] - ], - [ - 16, - [ - -1, - -1 - ] - ] - ] - }, - "fill-translate-anchor": "viewport" - }, - "source": "composite", - "source-layer": "water", - "type": "fill" - }, - { - "id": "water", - "paint": { - "fill-color": "hsl(196, 80%, 70%)" - }, - "ref": "water-shadow" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "Polygon" - ], - [ - "==", - "class", - "land" - ] - ], - "id": "barrier_line-land-polygon", - "layout": {}, - "paint": { - "fill-color": "hsl(35, 12%, 89%)" - }, - "source": "composite", - "source-layer": "barrier_line", - "type": "fill" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "==", - "class", - "land" - ] - ], - "id": "barrier_line-land-line", - "layout": { - "line-cap": "round" - }, - "paint": { - "line-color": "hsl(35, 12%, 89%)", - "line-width": { - "base": 1.99, - "stops": [ - [ - 14, - 0.75 - ], - [ - 20, - 40 - ] - ] - } - }, - "source": "composite", - "source-layer": "barrier_line", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "Polygon" - ], - [ - "!=", - "type", - "apron" - ] - ], - "id": "aeroway-polygon", - "layout": {}, - "metadata": { - "mapbox:group": "1444934828655.3389" - }, - "minzoom": 11, - "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 - ] - ] - } - }, - "source": "composite", - "source-layer": "aeroway", - "type": "fill" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "==", - "type", - "runway" - ] - ], - "id": "aeroway-runway", - "layout": {}, - "metadata": { - "mapbox:group": "1444934828655.3389" - }, - "minzoom": 9, - "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 - ] - ] - } - }, - "source": "composite", - "source-layer": "aeroway", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "==", - "type", - "taxiway" - ] - ], - "id": "aeroway-taxiway", - "layout": {}, - "metadata": { - "mapbox:group": "1444934828655.3389" - }, - "minzoom": 9, - "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 - ] - ] - } - }, - "source": "composite", - "source-layer": "aeroway", - "type": "line" - }, - { - "filter": [ - "all", - [ - "!=", - "type", - "building:part" - ], - [ - "==", - "underground", - "false" - ] - ], - "id": "building-line", - "layout": {}, - "minzoom": 15, - "paint": { - "line-color": "hsl(35, 6%, 79%)", - "line-opacity": { - "base": 1, - "stops": [ - [ - 15.5, - 0 - ], - [ - 16, - 1 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 15, - 0.75 - ], - [ - 20, - 3 - ] - ] - } - }, - "source": "composite", - "source-layer": "building", - "type": "line" - }, - { - "filter": [ - "all", - [ - "!=", - "type", - "building:part" - ], - [ - "==", - "underground", - "false" - ] - ], - "id": "building", - "layout": {}, - "minzoom": 15, - "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%)" - }, - "source": "composite", - "source-layer": "building", - "type": "fill" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "street" - ], - [ - "==", - "structure", - "tunnel" - ] - ] - ], - "id": "tunnel-street-low", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "minzoom": 11, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-opacity": { - "stops": [ - [ - 11.5, - 0 - ], - [ - 12, - 1 - ], - [ - 14, - 1 - ], - [ - 14.01, - 0 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12.5, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "street_limited" - ], - [ - "==", - "structure", - "tunnel" - ] - ] - ], - "id": "tunnel-street_limited-low", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "minzoom": 11, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-opacity": { - "stops": [ - [ - 11.5, - 0 - ], - [ - 12, - 1 - ], - [ - 14, - 1 - ], - [ - 14.01, - 0 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12.5, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "in", - "class", - "link", - "service", - "track" - ], - [ - "==", - "structure", - "tunnel" - ], - [ - "!=", - "type", - "trunk_link" - ] - ] - ], - "id": "tunnel-service-link-track-case", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "minzoom": 14, - "paint": { - "line-color": "hsl(230, 19%, 75%)", - "line-dasharray": [ - 3, - 3 - ], - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 14, - 0.5 - ], - [ - 18, - 12 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.75 - ], - [ - 20, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "id": "tunnel-street_limited-case", - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "paint": { - "line-color": "hsl(230, 19%, 75%)", - "line-dasharray": [ - 3, - 3 - ], - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 13, - 0 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - }, - "line-opacity": { - "base": 1, - "stops": [ - [ - 13.99, - 0 - ], - [ - 14, - 1 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.75 - ], - [ - 20, - 2 - ] - ] - } - }, - "ref": "tunnel-street_limited-low" - }, - { - "id": "tunnel-street-case", - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "paint": { - "line-color": "hsl(230, 19%, 75%)", - "line-dasharray": [ - 3, - 3 - ], - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 13, - 0 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - }, - "line-opacity": { - "base": 1, - "stops": [ - [ - 13.99, - 0 - ], - [ - 14, - 1 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.75 - ], - [ - 20, - 2 - ] - ] - } - }, - "ref": "tunnel-street-low" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "in", - "class", - "secondary", - "tertiary" - ], - [ - "==", - "structure", - "tunnel" - ] - ] - ], - "id": "tunnel-secondary-tertiary-case", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "paint": { - "line-color": "hsl(230, 19%, 75%)", - "line-dasharray": [ - 3, - 3 - ], - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 8.5, - 0.5 - ], - [ - 10, - 0.75 - ], - [ - 18, - 26 - ] - ] - }, - "line-width": { - "base": 1.2, - "stops": [ - [ - 10, - 0.75 - ], - [ - 18, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "primary" - ], - [ - "==", - "structure", - "tunnel" - ] - ] - ], - "id": "tunnel-primary-case", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "paint": { - "line-color": "hsl(230, 19%, 75%)", - "line-dasharray": [ - 3, - 3 - ], - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 10, - 1 - ], - [ - 16, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "structure", - "tunnel" - ], - [ - "==", - "type", - "trunk_link" - ] - ] - ], - "id": "tunnel-trunk_link-case", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "minzoom": 13, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-dasharray": [ - 3, - 3 - ], - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.75 - ], - [ - 20, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "motorway_link" - ], - [ - "==", - "structure", - "tunnel" - ] - ] - ], - "id": "tunnel-motorway_link-case", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "minzoom": 13, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-dasharray": [ - 3, - 3 - ], - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.75 - ], - [ - 20, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "structure", - "tunnel" - ], - [ - "==", - "type", - "trunk" - ] - ] - ], - "id": "tunnel-trunk-case", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-dasharray": [ - 3, - 3 - ], - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - }, - "line-opacity": 1, - "line-width": { - "base": 1.5, - "stops": [ - [ - 10, - 1 - ], - [ - 16, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "motorway" - ], - [ - "==", - "structure", - "tunnel" - ] - ] - ], - "id": "tunnel-motorway-case", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-dasharray": [ - 3, - 3 - ], - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - }, - "line-opacity": 1, - "line-width": { - "base": 1.5, - "stops": [ - [ - 10, - 1 - ], - [ - 16, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "construction" - ], - [ - "==", - "structure", - "tunnel" - ] - ] - ], - "id": "tunnel-construction", - "layout": { - "line-join": "miter" - }, - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "minzoom": 14, - "paint": { - "line-color": "hsl(230, 24%, 87%)", - "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 - ] - ] - ] - }, - "line-opacity": { - "base": 1, - "stops": [ - [ - 13.99, - 0 - ], - [ - 14, - 1 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12.5, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "path" - ], - [ - "==", - "structure", - "tunnel" - ], - [ - "!=", - "type", - "steps" - ] - ] - ], - "id": "tunnel-path", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "paint": { - "line-color": "hsl(35, 26%, 95%)", - "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 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 15, - 1 - ], - [ - 18, - 4 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "structure", - "tunnel" - ], - [ - "==", - "type", - "steps" - ] - ] - ], - "id": "tunnel-steps", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "paint": { - "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 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 15, - 1 - ], - [ - 16, - 1.6 - ], - [ - 18, - 6 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "id": "tunnel-trunk_link", - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "paint": { - "line-color": "hsl(46, 77%, 78%)", - "line-dasharray": [ - 1, - 0 - ], - "line-opacity": 1, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "ref": "tunnel-trunk_link-case" - }, - { - "id": "tunnel-motorway_link", - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "paint": { - "line-color": "hsl(26, 100%, 78%)", - "line-dasharray": [ - 1, - 0 - ], - "line-opacity": 1, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "ref": "tunnel-motorway_link-case" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "pedestrian" - ], - [ - "==", - "structure", - "tunnel" - ] - ] - ], - "id": "tunnel-pedestrian", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "minzoom": 13, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-dasharray": { - "base": 1, - "stops": [ - [ - 14, - [ - 1, - 0 - ] - ], - [ - 15, - [ - 1.5, - 0.4 - ] - ], - [ - 16, - [ - 1, - 0.2 - ] - ] - ] - }, - "line-opacity": 1, - "line-width": { - "base": 1.5, - "stops": [ - [ - 14, - 0.5 - ], - [ - 18, - 12 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "id": "tunnel-service-link-track", - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-dasharray": [ - 1, - 0 - ], - "line-width": { - "base": 1.5, - "stops": [ - [ - 14, - 0.5 - ], - [ - 18, - 12 - ] - ] - } - }, - "ref": "tunnel-service-link-track-case" - }, - { - "id": "tunnel-street_limited", - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "paint": { - "line-color": "hsl(35, 14%, 93%)", - "line-opacity": { - "base": 1, - "stops": [ - [ - 13.99, - 0 - ], - [ - 14, - 1 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12.5, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "ref": "tunnel-street_limited-low" - }, - { - "id": "tunnel-street", - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-opacity": { - "base": 1, - "stops": [ - [ - 13.99, - 0 - ], - [ - 14, - 1 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12.5, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "ref": "tunnel-street-low" - }, - { - "id": "tunnel-secondary-tertiary", - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "paint": { - "line-blur": 0, - "line-color": "hsl(0, 0%, 100%)", - "line-dasharray": [ - 1, - 0 - ], - "line-opacity": 1, - "line-width": { - "base": 1.5, - "stops": [ - [ - 8.5, - 0.5 - ], - [ - 10, - 0.75 - ], - [ - 18, - 26 - ] - ] - } - }, - "ref": "tunnel-secondary-tertiary-case" - }, - { - "id": "tunnel-primary", - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "paint": { - "line-blur": 0, - "line-color": "hsl(0, 0%, 100%)", - "line-dasharray": [ - 1, - 0 - ], - "line-opacity": 1, - "line-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - } - }, - "ref": "tunnel-primary-case" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "in", - "class", - "link", - "path", - "pedestrian", - "service", - "track" - ], - [ - "==", - "oneway", - "true" - ], - [ - "==", - "structure", - "tunnel" - ], - [ - "!=", - "type", - "trunk_link" - ] - ] - ], - "id": "tunnel-oneway-arrows-blue-minor", - "layout": { - "icon-image": { - "base": 1, - "stops": [ - [ - 17, - "oneway-small" - ], - [ - 18, - "oneway-large" - ] - ] - }, - "icon-padding": 2, - "symbol-placement": "line", - "symbol-spacing": 200 - }, - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "minzoom": 16, - "paint": {}, - "source": "composite", - "source-layer": "road", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "in", - "class", - "primary", - "secondary", - "street", - "street_limited", - "tertiary" - ], - [ - "==", - "oneway", - "true" - ], - [ - "==", - "structure", - "tunnel" - ], - [ - "!=", - "type", - "trunk_link" - ] - ] - ], - "id": "tunnel-oneway-arrows-blue-major", - "layout": { - "icon-image": { - "base": 1, - "stops": [ - [ - 16, - "oneway-small" - ], - [ - 17, - "oneway-large" - ] - ] - }, - "icon-padding": 2, - "symbol-placement": "line", - "symbol-spacing": 200 - }, - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "minzoom": 15, - "paint": {}, - "source": "composite", - "source-layer": "road", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "trunk" - ], - [ - "==", - "structure", - "tunnel" - ] - ] - ], - "id": "tunnel-trunk", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "paint": { - "line-color": "hsl(46, 77%, 78%)", - "line-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "id": "tunnel-motorway", - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "paint": { - "line-blur": 0, - "line-color": "hsl(26, 100%, 78%)", - "line-dasharray": [ - 1, - 0 - ], - "line-opacity": 1, - "line-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - } - }, - "ref": "tunnel-motorway-case" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "in", - "class", - "link", - "motorway", - "motorway_link", - "trunk" - ], - [ - "==", - "oneway", - "true" - ], - [ - "==", - "structure", - "tunnel" - ], - [ - "!in", - "type", - "primary_link", - "secondary_link", - "tertiary_link" - ] - ] - ], - "id": "tunnel-oneway-arrows-white", - "layout": { - "icon-image": { - "base": 1, - "stops": [ - [ - 16, - "oneway-white-small" - ], - [ - 17, - "oneway-white-large" - ] - ] - }, - "icon-padding": 2, - "symbol-placement": "line", - "symbol-spacing": 200 - }, - "metadata": { - "mapbox:group": "1444855769305.6016" - }, - "minzoom": 16, - "paint": {}, - "source": "composite", - "source-layer": "road", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "==", - "type", - "ferry" - ] - ], - "id": "ferry", - "layout": { - "line-join": "round" - }, - "paint": { - "line-color": { - "base": 1, - "stops": [ - [ - 15, - "hsl(205, 73%, 63%)" - ], - [ - 17, - "hsl(230, 73%, 63%)" - ] - ] - }, - "line-dasharray": { - "base": 1, - "stops": [ - [ - 12, - [ - 1, - 0 - ] - ], - [ - 13, - [ - 12, - 4 - ] - ] - ] - }, - "line-opacity": 1, - "line-width": { - "base": 1.5, - "stops": [ - [ - 14, - 0.5 - ], - [ - 20, - 1 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "==", - "type", - "ferry_auto" - ] - ], - "id": "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 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "path" - ], - [ - "!in", - "structure", - "bridge", - "tunnel" - ], - [ - "!in", - "type", - "crossing", - "sidewalk", - "steps" - ] - ] - ], - "id": "road-path-bg", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "line-blur": 0, - "line-color": "hsl(230, 17%, 82%)", - "line-dasharray": [ - 1, - 0 - ], - "line-opacity": { - "base": 1, - "stops": [ - [ - 14, - 0 - ], - [ - 14.25, - 0.75 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 15, - 2 - ], - [ - 18, - 7 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "!in", - "structure", - "bridge", - "tunnel" - ], - [ - "==", - "type", - "steps" - ] - ] - ], - "id": "road-steps-bg", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "line-color": "hsl(230, 17%, 82%)", - "line-dasharray": [ - 1, - 0 - ], - "line-opacity": { - "base": 1, - "stops": [ - [ - 14, - 0 - ], - [ - 14.25, - 0.75 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 15, - 2 - ], - [ - 17, - 4.6 - ], - [ - 18, - 7 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "!in", - "structure", - "bridge", - "tunnel" - ], - [ - "in", - "type", - "crossing", - "sidewalk" - ] - ] - ], - "id": "road-sidewalk-bg", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "minzoom": 16, - "paint": { - "line-blur": 0, - "line-color": "hsl(230, 17%, 82%)", - "line-dasharray": [ - 1, - 0 - ], - "line-opacity": { - "base": 1, - "stops": [ - [ - 16, - 0 - ], - [ - 16.25, - 0.75 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 15, - 2 - ], - [ - 18, - 7 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "Point" - ], - [ - "in", - "class", - "turning_circle", - "turning_loop" - ] - ], - "id": "turning-features-outline", - "layout": { - "icon-allow-overlap": true, - "icon-ignore-placement": true, - "icon-image": "turning-circle-outline", - "icon-padding": 0, - "icon-rotation-alignment": "map", - "icon-size": { - "base": 1.5, - "stops": [ - [ - 14, - 0.122 - ], - [ - 18, - 0.969 - ], - [ - 20, - 1 - ] - ] - } - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "minzoom": 15, - "paint": {}, - "source": "composite", - "source-layer": "road", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "pedestrian" - ], - [ - "==", - "structure", - "none" - ] - ] - ], - "id": "road-pedestrian-case", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "minzoom": 12, - "paint": { - "line-color": "hsl(230, 24%, 87%)", - "line-gap-width": 0, - "line-opacity": { - "base": 1, - "stops": [ - [ - 13.99, - 0 - ], - [ - 14, - 1 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 14, - 2 - ], - [ - 18, - 14.5 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "street" - ], - [ - "==", - "structure", - "none" - ] - ] - ], - "id": "road-street-low", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "minzoom": 11, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-opacity": { - "stops": [ - [ - 11, - 0 - ], - [ - 11.25, - 1 - ], - [ - 14, - 1 - ], - [ - 14.01, - 0 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12.5, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "street_limited" - ], - [ - "==", - "structure", - "none" - ] - ] - ], - "id": "road-street_limited-low", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "minzoom": 11, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-opacity": { - "stops": [ - [ - 11, - 0 - ], - [ - 11.25, - 1 - ], - [ - 14, - 1 - ], - [ - 14.01, - 0 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12.5, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "in", - "class", - "link", - "service", - "track" - ], - [ - "!in", - "structure", - "bridge", - "tunnel" - ], - [ - "!=", - "type", - "trunk_link" - ] - ] - ], - "id": "road-service-link-track-case", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "minzoom": 14, - "paint": { - "line-color": "hsl(230, 24%, 87%)", - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 14, - 0.5 - ], - [ - 18, - 12 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.75 - ], - [ - 20, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "id": "road-street_limited-case", - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "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 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.75 - ], - [ - 20, - 2 - ] - ] - } - }, - "ref": "road-street_limited-low" - }, - { - "id": "road-street-case", - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "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 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.75 - ], - [ - 20, - 2 - ] - ] - } - }, - "ref": "road-street-low" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "in", - "class", - "secondary", - "tertiary" - ], - [ - "!in", - "structure", - "bridge", - "tunnel" - ] - ] - ], - "id": "road-secondary-tertiary-case", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "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 - ] - ] - }, - "line-width": { - "base": 1.2, - "stops": [ - [ - 10, - 0.75 - ], - [ - 18, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "primary" - ], - [ - "!in", - "structure", - "bridge", - "tunnel" - ] - ] - ], - "id": "road-primary-case", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "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 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 10, - 1 - ], - [ - 16, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "motorway_link" - ], - [ - "!in", - "structure", - "bridge", - "tunnel" - ] - ] - ], - "id": "road-motorway_link-case", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "minzoom": 10, - "paint": { - "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 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.75 - ], - [ - 20, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "!in", - "structure", - "bridge", - "tunnel" - ], - [ - "==", - "type", - "trunk_link" - ] - ] - ], - "id": "road-trunk_link-case", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "minzoom": 11, - "paint": { - "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 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.75 - ], - [ - 20, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "trunk" - ], - [ - "!in", - "structure", - "bridge", - "tunnel" - ] - ] - ], - "id": "road-trunk-case", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "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 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 10, - 1 - ], - [ - 16, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "motorway" - ], - [ - "!in", - "structure", - "bridge", - "tunnel" - ] - ] - ], - "id": "road-motorway-case", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 10, - 1 - ], - [ - 16, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "construction" - ], - [ - "==", - "structure", - "none" - ] - ] - ], - "id": "road-construction", - "layout": { - "line-join": "miter" - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "minzoom": 14, - "paint": { - "line-color": "hsl(230, 24%, 87%)", - "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 - ] - ] - ] - }, - "line-opacity": { - "base": 1, - "stops": [ - [ - 13.99, - 0 - ], - [ - 14, - 1 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12.5, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "id": "road-sidewalks", - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "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 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 15, - 1 - ], - [ - 18, - 4 - ] - ] - } - }, - "ref": "road-sidewalk-bg" - }, - { - "id": "road-path", - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "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 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 15, - 1 - ], - [ - 18, - 4 - ] - ] - } - }, - "ref": "road-path-bg" - }, - { - "id": "road-steps", - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "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 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 15, - 1 - ], - [ - 16, - 1.6 - ], - [ - 18, - 6 - ] - ] - } - }, - "ref": "road-steps-bg" - }, - { - "id": "road-trunk_link", - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "line-color": "hsl(46, 85%, 67%)", - "line-opacity": 1, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "ref": "road-trunk_link-case" - }, - { - "id": "road-motorway_link", - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "line-color": "hsl(26, 100%, 68%)", - "line-opacity": 1, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "ref": "road-motorway_link-case" - }, - { - "id": "road-pedestrian", - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-dasharray": { - "base": 1, - "stops": [ - [ - 14, - [ - 1, - 0 - ] - ], - [ - 15, - [ - 1.5, - 0.4 - ] - ], - [ - 16, - [ - 1, - 0.2 - ] - ] - ] - }, - "line-opacity": 1, - "line-width": { - "base": 1.5, - "stops": [ - [ - 14, - 0.5 - ], - [ - 18, - 12 - ] - ] - } - }, - "ref": "road-pedestrian-case" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "Polygon" - ], - [ - "all", - [ - "in", - "class", - "path", - "pedestrian" - ], - [ - "==", - "structure", - "none" - ] - ] - ], - "id": "road-pedestrian-polygon-fill", - "layout": {}, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "minzoom": 12, - "paint": { - "fill-color": { - "base": 1, - "stops": [ - [ - 16, - "hsl(230, 16%, 94%)" - ], - [ - 16.25, - "hsl(230, 50%, 98%)" - ] - ] - }, - "fill-opacity": 1, - "fill-outline-color": "hsl(230, 26%, 88%)" - }, - "source": "composite", - "source-layer": "road", - "type": "fill" - }, - { - "id": "road-pedestrian-polygon-pattern", - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "fill-color": "hsl(0, 0%, 100%)", - "fill-opacity": { - "base": 1, - "stops": [ - [ - 16, - 0 - ], - [ - 16.25, - 1 - ] - ] - }, - "fill-outline-color": "hsl(35, 10%, 83%)", - "fill-pattern": "pedestrian-polygon" - }, - "ref": "road-pedestrian-polygon-fill" - }, - { - "id": "road-service-link-track", - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-width": { - "base": 1.5, - "stops": [ - [ - 14, - 0.5 - ], - [ - 18, - 12 - ] - ] - } - }, - "ref": "road-service-link-track-case" - }, - { - "id": "road-street_limited", - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "line-color": "hsl(35, 14%, 93%)", - "line-opacity": { - "base": 1, - "stops": [ - [ - 13.99, - 0 - ], - [ - 14, - 1 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12.5, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "ref": "road-street_limited-low" - }, - { - "id": "road-street", - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-opacity": { - "base": 1, - "stops": [ - [ - 13.99, - 0 - ], - [ - 14, - 1 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12.5, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "ref": "road-street-low" - }, - { - "id": "road-secondary-tertiary", - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "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 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 8.5, - 0.5 - ], - [ - 10, - 0.75 - ], - [ - 18, - 26 - ] - ] - } - }, - "ref": "road-secondary-tertiary-case" - }, - { - "id": "road-primary", - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "line-color": { - "base": 1, - "stops": [ - [ - 5, - "hsl(35, 32%, 91%)" - ], - [ - 7, - "hsl(0, 0%, 100%)" - ] - ] - }, - "line-opacity": 1, - "line-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - } - }, - "ref": "road-primary-case" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "in", - "class", - "link", - "path", - "pedestrian", - "service", - "track" - ], - [ - "==", - "oneway", - "true" - ], - [ - "!in", - "structure", - "bridge", - "tunnel" - ], - [ - "!=", - "type", - "trunk_link" - ] - ] - ], - "id": "road-oneway-arrows-blue-minor", - "layout": { - "icon-image": { - "base": 1, - "stops": [ - [ - 17, - "oneway-small" - ], - [ - 18, - "oneway-large" - ] - ] - }, - "icon-padding": 2, - "icon-rotation-alignment": "map", - "symbol-placement": "line", - "symbol-spacing": 200 - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "minzoom": 16, - "paint": {}, - "source": "composite", - "source-layer": "road", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "in", - "class", - "primary", - "secondary", - "street", - "street_limited", - "tertiary" - ], - [ - "==", - "oneway", - "true" - ], - [ - "!in", - "structure", - "bridge", - "tunnel" - ], - [ - "!=", - "type", - "trunk_link" - ] - ] - ], - "id": "road-oneway-arrows-blue-major", - "layout": { - "icon-image": { - "base": 1, - "stops": [ - [ - 16, - "oneway-small" - ], - [ - 17, - "oneway-large" - ] - ] - }, - "icon-padding": 2, - "icon-rotation-alignment": "map", - "symbol-placement": "line", - "symbol-spacing": 200 - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "minzoom": 15, - "paint": {}, - "source": "composite", - "source-layer": "road", - "type": "symbol" - }, - { - "id": "road-trunk", - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "line-color": { - "base": 1, - "stops": [ - [ - 6, - "hsl(0, 0%, 100%)" - ], - [ - 6.1, - "hsl(46, 80%, 60%)" - ], - [ - 9, - "hsl(46, 85%, 67%)" - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - } - }, - "ref": "road-trunk-case" - }, - { - "id": "road-motorway", - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "line-color": { - "base": 1, - "stops": [ - [ - 8, - "hsl(26, 87%, 62%)" - ], - [ - 9, - "hsl(26, 100%, 68%)" - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - } - }, - "ref": "road-motorway-case" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "in", - "class", - "major_rail", - "minor_rail" - ], - [ - "!in", - "structure", - "bridge", - "tunnel" - ] - ] - ], - "id": "road-rail", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "minzoom": 13, - "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 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "id": "road-rail-tracks", - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "paint": { - "line-color": { - "stops": [ - [ - 13, - "hsl(50, 17%, 82%)" - ], - [ - 16, - "hsl(230, 10%, 74%)" - ] - ] - }, - "line-dasharray": [ - 0.1, - 15 - ], - "line-opacity": { - "base": 1, - "stops": [ - [ - 13.75, - 0 - ], - [ - 14, - 1 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 14, - 4 - ], - [ - 20, - 8 - ] - ] - } - }, - "ref": "road-rail" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "in", - "class", - "link", - "motorway", - "motorway_link", - "trunk" - ], - [ - "==", - "oneway", - "true" - ], - [ - "!in", - "structure", - "bridge", - "tunnel" - ], - [ - "!in", - "type", - "primary_link", - "secondary_link", - "tertiary_link" - ] - ] - ], - "id": "road-oneway-arrows-white", - "layout": { - "icon-image": { - "base": 1, - "stops": [ - [ - 16, - "oneway-white-small" - ], - [ - 17, - "oneway-white-large" - ] - ] - }, - "icon-padding": 2, - "symbol-placement": "line", - "symbol-spacing": 200 - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "minzoom": 16, - "paint": {}, - "source": "composite", - "source-layer": "road", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "Point" - ], - [ - "in", - "class", - "turning_circle", - "turning_loop" - ] - ], - "id": "turning-features", - "layout": { - "icon-allow-overlap": true, - "icon-ignore-placement": true, - "icon-image": "turning-circle", - "icon-padding": 0, - "icon-rotation-alignment": "map", - "icon-size": { - "base": 1.5, - "stops": [ - [ - 14, - 0.095 - ], - [ - 18, - 1 - ] - ] - } - }, - "metadata": { - "mapbox:group": "1444855786460.0557" - }, - "minzoom": 15, - "paint": {}, - "source": "composite", - "source-layer": "road", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "path" - ], - [ - "==", - "structure", - "bridge" - ], - [ - "!=", - "type", - "steps" - ] - ] - ], - "id": "bridge-path-bg", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "line-blur": 0, - "line-color": "hsl(230, 17%, 82%)", - "line-dasharray": [ - 1, - 0 - ], - "line-opacity": { - "base": 1, - "stops": [ - [ - 15, - 0 - ], - [ - 15.25, - 1 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 15, - 2 - ], - [ - 18, - 7 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "structure", - "bridge" - ], - [ - "==", - "type", - "steps" - ] - ] - ], - "id": "bridge-steps-bg", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "line-color": "hsl(230, 17%, 82%)", - "line-dasharray": [ - 1, - 0 - ], - "line-opacity": { - "base": 1, - "stops": [ - [ - 14, - 0 - ], - [ - 14.25, - 0.75 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 15, - 2 - ], - [ - 17, - 4.6 - ], - [ - 18, - 7 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "pedestrian" - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-pedestrian-case", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 13, - "paint": { - "line-color": "hsl(230, 24%, 87%)", - "line-gap-width": 0, - "line-opacity": { - "base": 1, - "stops": [ - [ - 13.99, - 0 - ], - [ - 14, - 1 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 14, - 2 - ], - [ - 18, - 14.5 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "street" - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-street-low", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 11, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-opacity": { - "stops": [ - [ - 11.5, - 0 - ], - [ - 12, - 1 - ], - [ - 14, - 1 - ], - [ - 14.01, - 0 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12.5, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "street_limited" - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-street_limited-low", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 11, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-opacity": { - "stops": [ - [ - 11.5, - 0 - ], - [ - 12, - 1 - ], - [ - 14, - 1 - ], - [ - 14.01, - 0 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12.5, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "in", - "class", - "link", - "service", - "track" - ], - [ - "==", - "structure", - "bridge" - ], - [ - "!=", - "type", - "trunk_link" - ] - ] - ], - "id": "bridge-service-link-track-case", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 14, - "paint": { - "line-color": "hsl(230, 24%, 87%)", - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 14, - 0.5 - ], - [ - 18, - 12 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.75 - ], - [ - 20, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "street_limited" - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-street_limited-case", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 11, - "paint": { - "line-color": "hsl(230, 24%, 87%)", - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 13, - 0 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.75 - ], - [ - 20, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "street" - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-street-case", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 11, - "paint": { - "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 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.75 - ], - [ - 20, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "in", - "class", - "secondary", - "tertiary" - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-secondary-tertiary-case", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "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 - ], - "line-width": { - "base": 1.2, - "stops": [ - [ - 10, - 0.75 - ], - [ - 18, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "primary" - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-primary-case", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "line-color": "hsl(230, 24%, 87%)", - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - }, - "line-translate": [ - 0, - 0 - ], - "line-width": { - "base": 1.5, - "stops": [ - [ - 10, - 1 - ], - [ - 16, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "!in", - "layer", - 2, - 3, - 4, - 5 - ], - [ - "==", - "structure", - "bridge" - ], - [ - "==", - "type", - "trunk_link" - ] - ] - ], - "id": "bridge-trunk_link-case", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 13, - "paint": { - "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 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.75 - ], - [ - 20, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "motorway_link" - ], - [ - "!in", - "layer", - 2, - 3, - 4, - 5 - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-motorway_link-case", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 13, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - }, - "line-opacity": 1, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.75 - ], - [ - 20, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "trunk" - ], - [ - "!in", - "layer", - 2, - 3, - 4, - 5 - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-trunk-case", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 10, - 1 - ], - [ - 16, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "motorway" - ], - [ - "!in", - "layer", - 2, - 3, - 4, - 5 - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-motorway-case", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 10, - 1 - ], - [ - 16, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "construction" - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-construction", - "layout": { - "line-join": "miter" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 14, - "paint": { - "line-color": "hsl(230, 24%, 87%)", - "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 - ] - ] - ] - }, - "line-opacity": { - "base": 1, - "stops": [ - [ - 13.99, - 0 - ], - [ - 14, - 1 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12.5, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "path" - ], - [ - "==", - "structure", - "bridge" - ], - [ - "!=", - "type", - "steps" - ] - ] - ], - "id": "bridge-path", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "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 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 15, - 1 - ], - [ - 18, - 4 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "id": "bridge-steps", - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "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 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 15, - 1 - ], - [ - 16, - 1.6 - ], - [ - 18, - 6 - ] - ] - } - }, - "ref": "bridge-steps-bg" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "!in", - "layer", - 2, - 3, - 4, - 5 - ], - [ - "==", - "structure", - "bridge" - ], - [ - "==", - "type", - "trunk_link" - ] - ] - ], - "id": "bridge-trunk_link", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 13, - "paint": { - "line-color": "hsl(46, 85%, 67%)", - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "motorway_link" - ], - [ - "!in", - "layer", - 2, - 3, - 4, - 5 - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-motorway_link", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 13, - "paint": { - "line-color": "hsl(26, 100%, 68%)", - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "id": "bridge-pedestrian", - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-dasharray": { - "base": 1, - "stops": [ - [ - 14, - [ - 1, - 0 - ] - ], - [ - 15, - [ - 1.5, - 0.4 - ] - ], - [ - 16, - [ - 1, - 0.2 - ] - ] - ] - }, - "line-opacity": 1, - "line-width": { - "base": 1.5, - "stops": [ - [ - 14, - 0.5 - ], - [ - 18, - 12 - ] - ] - } - }, - "ref": "bridge-pedestrian-case" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "in", - "class", - "link", - "service", - "track" - ], - [ - "==", - "structure", - "bridge" - ], - [ - "!=", - "type", - "trunk_link" - ] - ] - ], - "id": "bridge-service-link-track", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 14, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-width": { - "base": 1.5, - "stops": [ - [ - 14, - 0.5 - ], - [ - 18, - 12 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "id": "bridge-street_limited", - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "line-color": "hsl(35, 14%, 93%)", - "line-opacity": { - "base": 1, - "stops": [ - [ - 13.99, - 0 - ], - [ - 14, - 1 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12.5, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "ref": "bridge-street_limited-low" - }, - { - "id": "bridge-street", - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-opacity": { - "base": 1, - "stops": [ - [ - 13.99, - 0 - ], - [ - 14, - 1 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12.5, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "ref": "bridge-street-low" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "structure", - "bridge" - ], - [ - "in", - "type", - "secondary", - "tertiary" - ] - ] - ], - "id": "bridge-secondary-tertiary", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-opacity": { - "base": 1.2, - "stops": [ - [ - 5, - 0 - ], - [ - 5.5, - 1 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 8.5, - 0.5 - ], - [ - 10, - 0.75 - ], - [ - 18, - 26 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "structure", - "bridge" - ], - [ - "==", - "type", - "primary" - ] - ] - ], - "id": "bridge-primary", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-opacity": 1, - "line-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "in", - "class", - "link", - "path", - "pedestrian", - "service", - "track" - ], - [ - "==", - "oneway", - "true" - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-oneway-arrows-blue-minor", - "layout": { - "icon-image": { - "base": 1, - "stops": [ - [ - 17, - "oneway-small" - ], - [ - 18, - "oneway-large" - ] - ] - }, - "icon-padding": 2, - "icon-rotation-alignment": "map", - "symbol-placement": "line", - "symbol-spacing": 200 - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 16, - "paint": {}, - "source": "composite", - "source-layer": "road", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "in", - "class", - "primary", - "secondary", - "street", - "street_limited", - "tertiary" - ], - [ - "==", - "oneway", - "true" - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-oneway-arrows-blue-major", - "layout": { - "icon-image": { - "base": 1, - "stops": [ - [ - 16, - "oneway-small" - ], - [ - 17, - "oneway-large" - ] - ] - }, - "icon-padding": 2, - "icon-rotation-alignment": "map", - "symbol-placement": "line", - "symbol-spacing": 200 - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 15, - "paint": {}, - "source": "composite", - "source-layer": "road", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "trunk" - ], - [ - "!in", - "layer", - 2, - 3, - 4, - 5 - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-trunk", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "line-color": "hsl(46, 85%, 67%)", - "line-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "motorway" - ], - [ - "!in", - "layer", - 2, - 3, - 4, - 5 - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-motorway", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "line-color": "hsl(26, 100%, 68%)", - "line-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "in", - "class", - "major_rail", - "minor_rail" - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-rail", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 13, - "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 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "id": "bridge-rail-tracks", - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "line-color": { - "stops": [ - [ - 13, - "hsl(50, 17%, 82%)" - ], - [ - 16, - "hsl(230, 10%, 74%)" - ] - ] - }, - "line-dasharray": [ - 0.1, - 15 - ], - "line-opacity": { - "base": 1, - "stops": [ - [ - 13.75, - 0 - ], - [ - 20, - 1 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 14, - 4 - ], - [ - 20, - 8 - ] - ] - } - }, - "ref": "bridge-rail" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - ">=", - "layer", - 2 - ], - [ - "==", - "structure", - "bridge" - ], - [ - "==", - "type", - "trunk_link" - ] - ] - ], - "id": "bridge-trunk_link-2-case", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 13, - "paint": { - "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 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.75 - ], - [ - 20, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "motorway_link" - ], - [ - ">=", - "layer", - 2 - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-motorway_link-2-case", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 13, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - }, - "line-opacity": 1, - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.75 - ], - [ - 20, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "trunk" - ], - [ - ">=", - "layer", - 2 - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-trunk-2-case", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 10, - 1 - ], - [ - 16, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "motorway" - ], - [ - ">=", - "layer", - 2 - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-motorway-2-case", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "line-color": "hsl(0, 0%, 100%)", - "line-gap-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - }, - "line-width": { - "base": 1.5, - "stops": [ - [ - 10, - 1 - ], - [ - 16, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - ">=", - "layer", - 2 - ], - [ - "==", - "structure", - "bridge" - ], - [ - "==", - "type", - "trunk_link" - ] - ] - ], - "id": "bridge-trunk_link-2", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 13, - "paint": { - "line-color": "hsl(46, 85%, 67%)", - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "motorway_link" - ], - [ - ">=", - "layer", - 2 - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-motorway_link-2", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 13, - "paint": { - "line-color": "hsl(26, 100%, 68%)", - "line-width": { - "base": 1.5, - "stops": [ - [ - 12, - 0.5 - ], - [ - 14, - 2 - ], - [ - 18, - 18 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "trunk" - ], - [ - ">=", - "layer", - 2 - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-trunk-2", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "line-color": "hsl(46, 85%, 67%)", - "line-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "==", - "class", - "motorway" - ], - [ - ">=", - "layer", - 2 - ], - [ - "==", - "structure", - "bridge" - ] - ] - ], - "id": "bridge-motorway-2", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "paint": { - "line-color": "hsl(26, 100%, 68%)", - "line-width": { - "base": 1.5, - "stops": [ - [ - 5, - 0.75 - ], - [ - 18, - 32 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "all", - [ - "in", - "class", - "link", - "motorway", - "motorway_link", - "trunk" - ], - [ - "==", - "oneway", - "true" - ], - [ - "==", - "structure", - "bridge" - ], - [ - "!in", - "type", - "primary_link", - "secondary_link", - "tertiary_link" - ] - ] - ], - "id": "bridge-oneway-arrows-white", - "layout": { - "icon-image": { - "base": 1, - "stops": [ - [ - 16, - "oneway-white-small" - ], - [ - 17, - "oneway-white-large" - ] - ] - }, - "icon-padding": 2, - "symbol-placement": "line", - "symbol-spacing": 200 - }, - "metadata": { - "mapbox:group": "1444855799204.86" - }, - "minzoom": 16, - "paint": {}, - "source": "composite", - "source-layer": "road", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "==", - "class", - "aerialway" - ] - ], - "id": "aerialway", - "layout": { - "line-join": "round" - }, - "minzoom": 13, - "paint": { - "line-color": "hsl(230, 10%, 74%)", - "line-width": { - "base": 1.5, - "stops": [ - [ - 14, - 0.5 - ], - [ - 20, - 1 - ] - ] - } - }, - "source": "composite", - "source-layer": "road", - "type": "line" - }, - { - "filter": [ - "all", - [ - ">=", - "admin_level", - 3 - ], - [ - "==", - "maritime", - 0 - ] - ], - "id": "admin-3-4-boundaries-bg", - "layout": { - "line-join": "bevel" - }, - "metadata": { - "mapbox:group": "1444934295202.7542" - }, - "paint": { - "line-blur": { - "base": 1, - "stops": [ - [ - 3, - 0 - ], - [ - 8, - 3 - ] - ] - }, - "line-color": { - "base": 1, - "stops": [ - [ - 8, - "hsl(35, 12%, 89%)" - ], - [ - 16, - "hsl(230, 49%, 90%)" - ] - ] - }, - "line-dasharray": [ - 1, - 0 - ], - "line-opacity": { - "base": 1, - "stops": [ - [ - 7, - 0 - ], - [ - 8, - 0.75 - ] - ] - }, - "line-translate": [ - 0, - 0 - ], - "line-width": { - "base": 1, - "stops": [ - [ - 7, - 3.75 - ], - [ - 12, - 5.5 - ] - ] - } - }, - "source": "composite", - "source-layer": "admin", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "admin_level", - 2 - ], - [ - "==", - "maritime", - 0 - ] - ], - "id": "admin-2-boundaries-bg", - "layout": { - "line-join": "miter" - }, - "metadata": { - "mapbox:group": "1444934295202.7542" - }, - "minzoom": 1, - "paint": { - "line-blur": { - "base": 1, - "stops": [ - [ - 3, - 0 - ], - [ - 10, - 2 - ] - ] - }, - "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-width": { - "base": 1, - "stops": [ - [ - 3, - 3.5 - ], - [ - 10, - 8 - ] - ] - } - }, - "source": "composite", - "source-layer": "admin", - "type": "line" - }, - { - "filter": [ - "all", - [ - ">=", - "admin_level", - 3 - ], - [ - "==", - "maritime", - 0 - ] - ], - "id": "admin-3-4-boundaries", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444934295202.7542" - }, - "paint": { - "line-color": { - "base": 1, - "stops": [ - [ - 3, - "hsl(230, 14%, 77%)" - ], - [ - 7, - "hsl(230, 8%, 62%)" - ] - ] - }, - "line-dasharray": { - "base": 1, - "stops": [ - [ - 6, - [ - 2, - 0 - ] - ], - [ - 7, - [ - 2, - 2, - 6, - 2 - ] - ] - ] - }, - "line-opacity": { - "base": 1, - "stops": [ - [ - 2, - 0 - ], - [ - 3, - 1 - ] - ] - }, - "line-width": { - "base": 1, - "stops": [ - [ - 7, - 0.75 - ], - [ - 12, - 1.5 - ] - ] - } - }, - "source": "composite", - "source-layer": "admin", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "admin_level", - 2 - ], - [ - "==", - "disputed", - 0 - ], - [ - "==", - "maritime", - 0 - ] - ], - "id": "admin-2-boundaries", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444934295202.7542" - }, - "minzoom": 1, - "paint": { - "line-color": "hsl(230, 8%, 51%)", - "line-width": { - "base": 1, - "stops": [ - [ - 3, - 0.5 - ], - [ - 10, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "admin", - "type": "line" - }, - { - "filter": [ - "all", - [ - "==", - "admin_level", - 2 - ], - [ - "==", - "disputed", - 1 - ], - [ - "==", - "maritime", - 0 - ] - ], - "id": "admin-2-boundaries-dispute", - "layout": { - "line-join": "round" - }, - "metadata": { - "mapbox:group": "1444934295202.7542" - }, - "minzoom": 1, - "paint": { - "line-color": "hsl(230, 8%, 51%)", - "line-dasharray": [ - 1.5, - 1.5 - ], - "line-width": { - "base": 1, - "stops": [ - [ - 3, - 0.5 - ], - [ - 10, - 2 - ] - ] - } - }, - "source": "composite", - "source-layer": "admin", - "type": "line" - }, - { - "id": "housenum-label", - "layout": { - "text-field": "{house_num}", - "text-font": [ - "DIN Offc Pro Italic", - "Arial Unicode MS Regular" - ], - "text-max-width": 7, - "text-padding": 4, - "text-size": 9.5 - }, - "minzoom": 17, - "paint": { - "text-color": "hsl(35, 2%, 69%)", - "text-halo-blur": 0, - "text-halo-color": "hsl(35, 8%, 85%)", - "text-halo-width": 0.5 - }, - "source": "composite", - "source-layer": "housenum_label", - "type": "symbol" - }, - { - "filter": [ - "in", - "class", - "canal", - "river" - ], - "id": "waterway-label", - "layout": { - "symbol-placement": "line", - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Italic", - "Arial Unicode MS Regular" - ], - "text-max-angle": 30, - "text-size": { - "base": 1, - "stops": [ - [ - 13, - 12 - ], - [ - 18, - 16 - ] - ] - } - }, - "minzoom": 12, - "paint": { - "text-color": "hsl(230, 48%, 44%)", - "text-halo-blur": 0.5, - "text-halo-color": "hsl(196, 80%, 70%)", - "text-halo-width": 0.5 - }, - "source": "composite", - "source-layer": "waterway_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - ">=", - "localrank", - 15 - ], - [ - "!in", - "maki", - "campsite", - "cemetery", - "dog-park", - "garden", - "golf", - "park", - "picnic-site", - "playground", - "zoo" - ], - [ - "==", - "scalerank", - 4 - ] - ], - "id": "poi-scalerank4-l15", - "layout": { - "icon-image": "{maki}-11", - "symbol-spacing": 250, - "text-anchor": "top", - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Medium", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.01, - "text-line-height": 1.1, - "text-max-angle": 38, - "text-max-width": 8, - "text-offset": [ - 0, - 0.65 - ], - "text-padding": 2, - "text-rotation-alignment": "viewport", - "text-size": { - "base": 1, - "stops": [ - [ - 16, - 11 - ], - [ - 20, - 13 - ] - ] - } - }, - "metadata": { - "mapbox:group": "1444933456003.5437" - }, - "minzoom": 17, - "paint": { - "text-color": "hsl(26, 25%, 32%)", - "text-halo-blur": 0.5, - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 0.5 - }, - "source": "composite", - "source-layer": "poi_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "<=", - "localrank", - 14 - ], - [ - "!in", - "maki", - "campsite", - "cemetery", - "dog-park", - "garden", - "golf", - "park", - "picnic-site", - "playground", - "zoo" - ], - [ - "==", - "scalerank", - 4 - ] - ], - "id": "poi-scalerank4-l1", - "layout": { - "icon-image": "{maki}-11", - "symbol-spacing": 250, - "text-anchor": "top", - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Medium", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.01, - "text-line-height": 1.1, - "text-max-angle": 38, - "text-max-width": 8, - "text-offset": [ - 0, - 0.65 - ], - "text-padding": 1, - "text-rotation-alignment": "viewport", - "text-size": { - "base": 1, - "stops": [ - [ - 16, - 11 - ], - [ - 20, - 13 - ] - ] - } - }, - "metadata": { - "mapbox:group": "1444933456003.5437" - }, - "minzoom": 15, - "paint": { - "text-color": "hsl(26, 25%, 32%)", - "text-halo-blur": 0.5, - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 0.5 - }, - "source": "composite", - "source-layer": "poi_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "in", - "maki", - "campsite", - "cemetery", - "dog-park", - "garden", - "golf", - "park", - "picnic-site", - "playground", - "zoo" - ], - [ - "==", - "scalerank", - 4 - ] - ], - "id": "poi-parks_scalerank4", - "layout": { - "icon-image": "{maki}-11", - "symbol-spacing": 250, - "text-anchor": "top", - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Medium", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.01, - "text-line-height": 1.1, - "text-max-angle": 38, - "text-max-width": 8, - "text-offset": [ - 0, - 0.65 - ], - "text-padding": 1, - "text-rotation-alignment": "viewport", - "text-size": { - "base": 1, - "stops": [ - [ - 16, - 11 - ], - [ - 20, - 13 - ] - ] - } - }, - "metadata": { - "mapbox:group": "1444933456003.5437" - }, - "minzoom": 15, - "paint": { - "text-color": "hsl(100, 100%, 20%)", - "text-halo-blur": 0.5, - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 0.5 - }, - "source": "composite", - "source-layer": "poi_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "!in", - "maki", - "campsite", - "cemetery", - "dog-park", - "garden", - "golf", - "park", - "picnic-site", - "playground", - "zoo" - ], - [ - "==", - "scalerank", - 3 - ] - ], - "id": "poi-scalerank3", - "layout": { - "icon-image": "{maki}-11", - "symbol-spacing": 250, - "text-anchor": "top", - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Medium", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.01, - "text-line-height": 1.1, - "text-max-angle": 38, - "text-max-width": 8, - "text-offset": [ - 0, - 0.65 - ], - "text-padding": 1, - "text-rotation-alignment": "viewport", - "text-size": { - "base": 1, - "stops": [ - [ - 16, - 11 - ], - [ - 20, - 13 - ] - ] - } - }, - "metadata": { - "mapbox:group": "1444933372896.5967" - }, - "paint": { - "text-color": "hsl(26, 25%, 32%)", - "text-halo-blur": 0.5, - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 0.5 - }, - "source": "composite", - "source-layer": "poi_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "in", - "maki", - "campsite", - "cemetery", - "dog-park", - "garden", - "golf", - "park", - "picnic-site", - "playground", - "zoo" - ], - [ - "==", - "scalerank", - 3 - ] - ], - "id": "poi-parks-scalerank3", - "layout": { - "icon-image": "{maki}-11", - "symbol-spacing": 250, - "text-anchor": "top", - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Medium", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.01, - "text-line-height": 1.1, - "text-max-angle": 38, - "text-max-width": 8, - "text-offset": [ - 0, - 0.65 - ], - "text-padding": 2, - "text-rotation-alignment": "viewport", - "text-size": { - "base": 1, - "stops": [ - [ - 16, - 11 - ], - [ - 20, - 13 - ] - ] - } - }, - "metadata": { - "mapbox:group": "1444933372896.5967" - }, - "paint": { - "text-color": "hsl(100, 100%, 20%)", - "text-halo-blur": 0.5, - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 0.5 - }, - "source": "composite", - "source-layer": "poi_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "!in", - "class", - "link", - "motorway", - "pedestrian", - "primary", - "secondary", - "street", - "street_limited", - "tertiary", - "trunk" - ] - ], - "id": "road-label-small", - "layout": { - "symbol-placement": "line", - "symbol-spacing": 250, - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Regular", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.01, - "text-max-angle": 30, - "text-padding": 1, - "text-rotation-alignment": "map", - "text-size": { - "base": 1, - "stops": [ - [ - 15, - 10 - ], - [ - 20, - 13 - ] - ] - } - }, - "metadata": { - "mapbox:group": "1444933721429.3076" - }, - "minzoom": 15, - "paint": { - "text-color": "hsl(0, 0%, 0%)", - "text-halo-blur": 1, - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 1.25 - }, - "source": "composite", - "source-layer": "road_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "in", - "class", - "link", - "pedestrian", - "street", - "street_limited" - ] - ], - "id": "road-label-medium", - "layout": { - "symbol-placement": "line", - "symbol-spacing": 250, - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Regular", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.01, - "text-max-angle": 30, - "text-padding": 1, - "text-rotation-alignment": "map", - "text-size": { - "base": 1, - "stops": [ - [ - 11, - 10 - ], - [ - 20, - 14 - ] - ] - } - }, - "metadata": { - "mapbox:group": "1444933721429.3076" - }, - "minzoom": 11, - "paint": { - "text-color": "hsl(0, 0%, 0%)", - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 1 - }, - "source": "composite", - "source-layer": "road_label", - "type": "symbol" - }, - { - "filter": [ - "in", - "class", - "motorway", - "primary", - "secondary", - "tertiary", - "trunk" - ], - "id": "road-label-large", - "layout": { - "symbol-placement": "line", - "symbol-spacing": 250, - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Regular", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.01, - "text-max-angle": 30, - "text-padding": 1, - "text-rotation-alignment": "map", - "text-size": { - "base": 1, - "stops": [ - [ - 9, - 10 - ], - [ - 20, - 16 - ] - ] - } - }, - "metadata": { - "mapbox:group": "1444933721429.3076" - }, - "paint": { - "text-color": "hsl(0, 0%, 0%)", - "text-halo-blur": 1, - "text-halo-color": "hsla(0, 0%, 100%, 0.75)", - "text-halo-width": 1 - }, - "source": "composite", - "source-layer": "road_label", - "type": "symbol" - }, - { - "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" - ] - ], - "id": "road-shields-black", - "layout": { - "icon-image": "{shield}-{reflen}", - "icon-padding": 2, - "icon-rotation-alignment": "viewport", - "symbol-placement": { - "base": 1, - "stops": [ - [ - 10, - "point" - ], - [ - 11, - "line" - ] - ] - }, - "symbol-spacing": { - "base": 1, - "stops": [ - [ - 11, - 150 - ], - [ - 14, - 200 - ] - ] - }, - "text-field": "{ref}", - "text-font": [ - "DIN Offc Pro Bold", - "Arial Unicode MS Bold" - ], - "text-letter-spacing": 0.05, - "text-max-angle": 38, - "text-padding": 2, - "text-rotation-alignment": "viewport", - "text-size": 9 - }, - "metadata": { - "mapbox:group": "1444933575858.6992" - }, - "paint": { - "icon-color": "white", - "icon-halo-color": "rgba(0, 0, 0, 1)", - "icon-halo-width": 1, - "text-color": "hsl(0, 0%, 7%)", - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 0, - "text-opacity": 1 - }, - "source": "composite", - "source-layer": "road_label", - "type": "symbol" - }, - { - "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" - ] - ], - "id": "road-shields-white", - "layout": { - "icon-image": "{shield}-{reflen}", - "icon-padding": 2, - "icon-rotation-alignment": "viewport", - "symbol-placement": { - "base": 1, - "stops": [ - [ - 10, - "point" - ], - [ - 11, - "line" - ] - ] - }, - "symbol-spacing": { - "base": 1, - "stops": [ - [ - 11, - 150 - ], - [ - 14, - 200 - ] - ] - }, - "text-field": "{ref}", - "text-font": [ - "DIN Offc Pro Bold", - "Arial Unicode MS Bold" - ], - "text-letter-spacing": 0.05, - "text-max-angle": 38, - "text-padding": 2, - "text-rotation-alignment": "viewport", - "text-size": 9 - }, - "metadata": { - "mapbox:group": "1444933575858.6992" - }, - "paint": { - "icon-color": "white", - "icon-halo-color": "rgba(0, 0, 0, 1)", - "icon-halo-width": 1, - "text-color": "hsl(0, 0%, 100%)", - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 0, - "text-opacity": 1 - }, - "source": "composite", - "source-layer": "road_label", - "type": "symbol" - }, - { - "filter": [ - ">", - "reflen", - 0 - ], - "id": "motorway-junction", - "layout": { - "icon-image": "motorway-exit-{reflen}", - "text-field": "{ref}", - "text-font": [ - "DIN Offc Pro Bold", - "Arial Unicode MS Bold" - ], - "text-size": 9 - }, - "metadata": { - "mapbox:group": "1444933575858.6992" - }, - "minzoom": 14, - "paint": { - "text-color": "hsl(0, 0%, 100%)", - "text-translate": [ - 0, - 0 - ] - }, - "source": "composite", - "source-layer": "motorway_junction", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "!in", - "maki", - "campsite", - "cemetery", - "dog-park", - "garden", - "golf", - "park", - "picnic-site", - "playground", - "zoo" - ], - [ - "==", - "scalerank", - 2 - ] - ], - "id": "poi-scalerank2", - "layout": { - "icon-image": { - "stops": [ - [ - 14, - "{maki}-11" - ], - [ - 15, - "{maki}-15" - ] - ] - }, - "symbol-spacing": 250, - "text-anchor": "top", - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Medium", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.01, - "text-line-height": 1.1, - "text-max-angle": 38, - "text-max-width": 8, - "text-offset": [ - 0, - 0.65 - ], - "text-padding": 2, - "text-rotation-alignment": "viewport", - "text-size": { - "base": 1, - "stops": [ - [ - 14, - 11 - ], - [ - 20, - 14 - ] - ] - } - }, - "metadata": { - "mapbox:group": "1444933358918.2366" - }, - "paint": { - "text-color": "hsl(26, 25%, 32%)", - "text-halo-blur": 0.5, - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 0.5 - }, - "source": "composite", - "source-layer": "poi_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "in", - "maki", - "campsite", - "cemetery", - "dog-park", - "garden", - "golf", - "park", - "picnic-site", - "playground", - "zoo" - ], - [ - "==", - "scalerank", - 2 - ] - ], - "id": "poi-parks-scalerank2", - "layout": { - "icon-image": { - "stops": [ - [ - 14, - "{maki}-11" - ], - [ - 15, - "{maki}-15" - ] - ] - }, - "symbol-spacing": 250, - "text-anchor": "top", - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Medium", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.01, - "text-line-height": 1.1, - "text-max-angle": 38, - "text-max-width": 8, - "text-offset": [ - 0, - 0.65 - ], - "text-padding": 2, - "text-rotation-alignment": "viewport", - "text-size": { - "base": 1, - "stops": [ - [ - 14, - 11 - ], - [ - 20, - 14 - ] - ] - } - }, - "metadata": { - "mapbox:group": "1444933358918.2366" - }, - "paint": { - "text-color": "hsl(100, 100%, 20%)", - "text-halo-blur": 0.5, - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 0.5 - }, - "source": "composite", - "source-layer": "poi_label", - "type": "symbol" - }, - { - "filter": [ - "!=", - "maki", - "entrance" - ], - "id": "rail-label", - "layout": { - "icon-image": "{network}", - "icon-padding": 0, - "symbol-spacing": 250, - "text-anchor": "top", - "text-field": { - "base": 1, - "stops": [ - [ - 0, - "" - ], - [ - 13, - "{name_en}" - ] - ] - }, - "text-font": [ - "DIN Offc Pro Medium", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.01, - "text-line-height": 1.1, - "text-max-width": 7, - "text-offset": [ - 0, - 0.85 - ], - "text-rotation-alignment": "viewport", - "text-size": { - "base": 1, - "stops": [ - [ - 16, - 11 - ], - [ - 20, - 13 - ] - ] - } - }, - "minzoom": 12, - "paint": { - "icon-halo-color": "#fff", - "icon-halo-width": 4, - "text-color": "hsl(230, 48%, 44%)", - "text-halo-blur": 0.5, - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 0.5, - "text-opacity": { - "base": 1, - "stops": [ - [ - 13.99, - 0 - ], - [ - 14, - 1 - ] - ] - } - }, - "source": "composite", - "source-layer": "rail_station_label", - "type": "symbol" - }, - { - "filter": [ - "<=", - "area", - 10000 - ], - "id": "water-label-sm", - "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 - ] - ] - } - }, - "metadata": { - "mapbox:group": "1444933808272.805" - }, - "minzoom": 15, - "paint": { - "text-color": "hsl(230, 48%, 44%)" - }, - "source": "composite", - "source-layer": "water_label", - "type": "symbol" - }, - { - "filter": [ - ">", - "area", - 10000 - ], - "id": "water-label", - "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 - ] - ] - } - }, - "metadata": { - "mapbox:group": "1444933808272.805" - }, - "minzoom": 5, - "paint": { - "text-color": "hsl(230, 48%, 44%)" - }, - "source": "composite", - "source-layer": "water_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "in", - "$type", - "LineString", - "Point", - "Polygon" - ], - [ - "all", - [ - "<=", - "localrank", - 10 - ], - [ - "==", - "type", - "residential" - ] - ] - ], - "id": "place-residential", - "layout": { - "symbol-spacing": 250, - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Regular", - "Arial Unicode MS Regular" - ], - "text-line-height": 1.2, - "text-max-angle": 38, - "text-max-width": 7, - "text-offset": [ - 0, - 0 - ], - "text-padding": 2, - "text-rotation-alignment": "viewport", - "text-size": { - "base": 1, - "stops": [ - [ - 10, - 11 - ], - [ - 18, - 14 - ] - ] - }, - "visibility": "none" - }, - "maxzoom": 18, - "minzoom": 16, - "paint": { - "text-color": "hsl(26, 25%, 32%)", - "text-halo-blur": 0.5, - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 1 - }, - "source": "composite", - "source-layer": "place_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "in", - "maki", - "campsite", - "cemetery", - "dog-park", - "garden", - "golf", - "park", - "picnic-site", - "playground", - "zoo" - ], - [ - "<=", - "scalerank", - 1 - ] - ], - "id": "poi-parks-scalerank1", - "layout": { - "icon-image": { - "stops": [ - [ - 13, - "{maki}-11" - ], - [ - 14, - "{maki}-15" - ] - ] - }, - "symbol-spacing": 250, - "text-anchor": "top", - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Medium", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.01, - "text-line-height": 1.1, - "text-max-angle": 38, - "text-max-width": 8, - "text-offset": [ - 0, - 0.65 - ], - "text-padding": 2, - "text-rotation-alignment": "viewport", - "text-size": { - "base": 1, - "stops": [ - [ - 10, - 11 - ], - [ - 18, - 14 - ] - ] - } - }, - "metadata": { - "mapbox:group": "1444933322393.2852" - }, - "paint": { - "text-color": "hsl(100, 100%, 20%)", - "text-halo-blur": 0.5, - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 0.5 - }, - "source": "composite", - "source-layer": "poi_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "!in", - "maki", - "campsite", - "cemetery", - "dog-park", - "garden", - "golf", - "park", - "picnic-site", - "playground", - "zoo" - ], - [ - "<=", - "scalerank", - 1 - ] - ], - "id": "poi-scalerank1", - "layout": { - "icon-image": { - "stops": [ - [ - 13, - "{maki}-11" - ], - [ - 14, - "{maki}-15" - ] - ] - }, - "symbol-spacing": 250, - "text-anchor": "top", - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Medium", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.01, - "text-line-height": 1.1, - "text-max-angle": 38, - "text-max-width": 8, - "text-offset": [ - 0, - 0.65 - ], - "text-padding": 2, - "text-rotation-alignment": "viewport", - "text-size": { - "base": 1, - "stops": [ - [ - 10, - 11 - ], - [ - 18, - 14 - ] - ] - } - }, - "metadata": { - "mapbox:group": "1444933322393.2852" - }, - "paint": { - "text-color": "hsl(26, 25%, 32%)", - "text-halo-blur": 0.5, - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 0.5 - }, - "source": "composite", - "source-layer": "poi_label", - "type": "symbol" - }, - { - "filter": [ - "<=", - "scalerank", - 2 - ], - "id": "airport-label", - "layout": { - "icon-image": { - "stops": [ - [ - 12, - "{maki}-11" - ], - [ - 13, - "{maki}-15" - ] - ] - }, - "symbol-spacing": 250, - "text-anchor": "top", - "text-field": { - "stops": [ - [ - 11, - "{ref}" - ], - [ - 12, - "{name_en}" - ] - ] - }, - "text-font": [ - "DIN Offc Pro Medium", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.01, - "text-line-height": 1.1, - "text-max-width": 9, - "text-offset": [ - 0, - 0.75 - ], - "text-padding": 2, - "text-rotation-alignment": "viewport", - "text-size": { - "base": 1, - "stops": [ - [ - 10, - 12 - ], - [ - 18, - 18 - ] - ] - } - }, - "minzoom": 9, - "paint": { - "text-color": "hsl(230, 48%, 44%)", - "text-halo-blur": 0.5, - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 0.5 - }, - "source": "composite", - "source-layer": "airport_label", - "type": "symbol" - }, - { - "filter": [ - "in", - "type", - "aboriginal_lands", - "archipelago", - "islet" - ], - "id": "place-islet-archipelago-aboriginal", - "layout": { - "symbol-spacing": 250, - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Regular", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.01, - "text-line-height": 1.2, - "text-max-angle": 38, - "text-max-width": 8, - "text-offset": [ - 0, - 0 - ], - "text-padding": 2, - "text-rotation-alignment": "viewport", - "text-size": { - "base": 1, - "stops": [ - [ - 10, - 11 - ], - [ - 18, - 16 - ] - ] - } - }, - "maxzoom": 16, - "paint": { - "text-color": "hsl(230, 29%, 35%)", - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 1 - }, - "source": "composite", - "source-layer": "place_label", - "type": "symbol" - }, - { - "filter": [ - "==", - "type", - "neighbourhood" - ], - "id": "place-neighbourhood", - "layout": { - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Regular", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.1, - "text-max-width": 7, - "text-padding": 3, - "text-size": { - "base": 1, - "stops": [ - [ - 12, - 11 - ], - [ - 16, - 16 - ] - ] - }, - "text-transform": "uppercase" - }, - "maxzoom": 16, - "minzoom": 10, - "paint": { - "text-color": "hsl(230, 29%, 35%)", - "text-halo-blur": 0.5, - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 1 - }, - "source": "composite", - "source-layer": "place_label", - "type": "symbol" - }, - { - "filter": [ - "==", - "type", - "suburb" - ], - "id": "place-suburb", - "layout": { - "text-field": "{name_en}", - "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 - ] - ] - }, - "text-transform": "uppercase" - }, - "maxzoom": 16, - "minzoom": 10, - "paint": { - "text-color": "hsl(230, 29%, 35%)", - "text-halo-blur": 0.5, - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 1 - }, - "source": "composite", - "source-layer": "place_label", - "type": "symbol" - }, - { - "filter": [ - "==", - "type", - "hamlet" - ], - "id": "place-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 - ] - ] - } - }, - "maxzoom": 16, - "minzoom": 10, - "paint": { - "text-color": "hsl(0, 0%, 0%)", - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 1.25 - }, - "source": "composite", - "source-layer": "place_label", - "type": "symbol" - }, - { - "filter": [ - "==", - "type", - "village" - ], - "id": "place-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 - ] - ] - } - }, - "maxzoom": 15, - "minzoom": 8, - "paint": { - "text-color": "hsl(0, 0%, 0%)", - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 1.25 - }, - "source": "composite", - "source-layer": "place_label", - "type": "symbol" - }, - { - "filter": [ - "==", - "type", - "town" - ], - "id": "place-town", - "layout": { - "icon-image": "dot-9", - "text-anchor": { - "base": 1, - "stops": [ - [ - 7, - "bottom" - ], - [ - 8, - "center" - ] - ] - }, - "text-field": "{name_en}", - "text-font": { - "base": 1, - "stops": [ - [ - 11, - [ - "DIN Offc Pro Regular", - "Arial Unicode MS Regular" - ] - ], - [ - 12, - [ - "DIN Offc Pro Medium", - "Arial Unicode MS Regular" - ] - ] - ] - }, - "text-max-width": 7, - "text-offset": { - "base": 1, - "stops": [ - [ - 7, - [ - 0, - -0.15 - ] - ], - [ - 8, - [ - 0, - 0 - ] - ] - ] - }, - "text-size": { - "base": 1, - "stops": [ - [ - 7, - 11.5 - ], - [ - 15, - 20 - ] - ] - } - }, - "maxzoom": 15, - "minzoom": 6, - "paint": { - "icon-opacity": { - "base": 1, - "stops": [ - [ - 7.99, - 1 - ], - [ - 8, - 0 - ] - ] - }, - "text-color": "hsl(0, 0%, 0%)", - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 1.25 - }, - "source": "composite", - "source-layer": "place_label", - "type": "symbol" - }, - { - "filter": [ - "==", - "type", - "island" - ], - "id": "place-island", - "layout": { - "symbol-spacing": 250, - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Regular", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.01, - "text-line-height": 1.2, - "text-max-angle": 38, - "text-max-width": 7, - "text-offset": [ - 0, - 0 - ], - "text-padding": 2, - "text-rotation-alignment": "viewport", - "text-size": { - "base": 1, - "stops": [ - [ - 10, - 11 - ], - [ - 18, - 16 - ] - ] - } - }, - "maxzoom": 16, - "paint": { - "text-color": "hsl(230, 29%, 35%)", - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 1 - }, - "source": "composite", - "source-layer": "place_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "!in", - "scalerank", - 0, - 1, - 2, - 3, - 4, - 5 - ], - [ - "==", - "type", - "city" - ] - ], - "id": "place-city-sm", - "layout": { - "icon-image": "dot-9", - "text-anchor": { - "base": 1, - "stops": [ - [ - 7, - "bottom" - ], - [ - 8, - "center" - ] - ] - }, - "text-field": "{name_en}", - "text-font": { - "base": 1, - "stops": [ - [ - 7, - [ - "DIN Offc Pro Regular", - "Arial Unicode MS Regular" - ] - ], - [ - 8, - [ - "DIN Offc Pro Medium", - "Arial Unicode MS Regular" - ] - ] - ] - }, - "text-max-width": 7, - "text-offset": { - "base": 1, - "stops": [ - [ - 7.99, - [ - 0, - -0.2 - ] - ], - [ - 8, - [ - 0, - 0 - ] - ] - ] - }, - "text-size": { - "base": 1, - "stops": [ - [ - 6, - 12 - ], - [ - 14, - 22 - ] - ] - } - }, - "maxzoom": 14, - "metadata": { - "mapbox:group": "1444862510685.128" - }, - "paint": { - "icon-opacity": { - "base": 1, - "stops": [ - [ - 7.99, - 1 - ], - [ - 8, - 0 - ] - ] - }, - "text-color": "hsl(0, 0%, 0%)", - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 1.25 - }, - "source": "composite", - "source-layer": "place_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "in", - "ldir", - "E", - "S", - "SE", - "SW" - ], - [ - "in", - "scalerank", - 3, - 4, - 5 - ], - [ - "==", - "type", - "city" - ] - ], - "id": "place-city-md-s", - "layout": { - "icon-image": "dot-10", - "text-anchor": { - "base": 1, - "stops": [ - [ - 7, - "top" - ], - [ - 8, - "center" - ] - ] - }, - "text-field": "{name_en}", - "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.1 - ] - ], - [ - 8, - [ - 0, - 0 - ] - ] - ] - }, - "text-size": { - "base": 0.9, - "stops": [ - [ - 5, - 12 - ], - [ - 12, - 22 - ] - ] - } - }, - "maxzoom": 14, - "metadata": { - "mapbox:group": "1444862510685.128" - }, - "paint": { - "icon-opacity": { - "base": 1, - "stops": [ - [ - 7.99, - 1 - ], - [ - 8, - 0 - ] - ] - }, - "text-color": "hsl(0, 0%, 0%)", - "text-halo-blur": 1, - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 1 - }, - "source": "composite", - "source-layer": "place_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "in", - "ldir", - "N", - "NE", - "NW", - "W" - ], - [ - "in", - "scalerank", - 3, - 4, - 5 - ], - [ - "==", - "type", - "city" - ] - ], - "id": "place-city-md-n", - "layout": { - "icon-image": "dot-10", - "text-anchor": { - "base": 1, - "stops": [ - [ - 7, - "bottom" - ], - [ - 8, - "center" - ] - ] - }, - "text-field": "{name_en}", - "text-font": { - "base": 1, - "stops": [ - [ - 7, - [ - "DIN Offc Pro Regular", - "Arial Unicode MS Regular" - ] - ], - [ - 8, - [ - "DIN Offc Pro Medium", - "Arial Unicode MS Regular" - ] - ] - ] - }, - "text-max-width": 7, - "text-offset": { - "base": 1, - "stops": [ - [ - 7.99, - [ - 0, - -0.25 - ] - ], - [ - 8, - [ - 0, - 0 - ] - ] - ] - }, - "text-size": { - "base": 0.9, - "stops": [ - [ - 5, - 12 - ], - [ - 12, - 22 - ] - ] - } - }, - "maxzoom": 14, - "metadata": { - "mapbox:group": "1444862510685.128" - }, - "paint": { - "icon-opacity": { - "base": 1, - "stops": [ - [ - 7.99, - 1 - ], - [ - 8, - 0 - ] - ] - }, - "text-color": "hsl(0, 0%, 0%)", - "text-halo-blur": 1, - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 1 - }, - "source": "composite", - "source-layer": "place_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "in", - "ldir", - "E", - "S", - "SE", - "SW" - ], - [ - "<=", - "scalerank", - 2 - ], - [ - "==", - "type", - "city" - ] - ], - "id": "place-city-lg-s", - "layout": { - "icon-image": "dot-11", - "text-anchor": { - "base": 1, - "stops": [ - [ - 7, - "top" - ], - [ - 8, - "center" - ] - ] - }, - "text-field": "{name_en}", - "text-font": { - "base": 1, - "stops": [ - [ - 7, - [ - "DIN Offc Pro Regular", - "Arial Unicode MS Regular" - ] - ], - [ - 8, - [ - "DIN Offc Pro Medium", - "Arial Unicode MS Regular" - ] - ] - ] - }, - "text-max-width": 7, - "text-offset": { - "base": 1, - "stops": [ - [ - 7.99, - [ - 0, - 0.15 - ] - ], - [ - 8, - [ - 0, - 0 - ] - ] - ] - }, - "text-size": { - "base": 0.9, - "stops": [ - [ - 4, - 12 - ], - [ - 10, - 22 - ] - ] - } - }, - "maxzoom": 14, - "metadata": { - "mapbox:group": "1444862510685.128" - }, - "minzoom": 1, - "paint": { - "icon-opacity": { - "base": 1, - "stops": [ - [ - 7.99, - 1 - ], - [ - 8, - 0 - ] - ] - }, - "text-color": "hsl(0, 0%, 0%)", - "text-halo-blur": 1, - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 1 - }, - "source": "composite", - "source-layer": "place_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "in", - "ldir", - "N", - "NE", - "NW", - "W" - ], - [ - "<=", - "scalerank", - 2 - ], - [ - "==", - "type", - "city" - ] - ], - "id": "place-city-lg-n", - "layout": { - "icon-image": "dot-11", - "text-anchor": { - "base": 1, - "stops": [ - [ - 7, - "bottom" - ], - [ - 8, - "center" - ] - ] - }, - "text-field": "{name_en}", - "text-font": { - "base": 1, - "stops": [ - [ - 7, - [ - "DIN Offc Pro Regular", - "Arial Unicode MS Regular" - ] - ], - [ - 8, - [ - "DIN Offc Pro Medium", - "Arial Unicode MS Regular" - ] - ] - ] - }, - "text-max-width": 7, - "text-offset": { - "base": 1, - "stops": [ - [ - 7.99, - [ - 0, - -0.25 - ] - ], - [ - 8, - [ - 0, - 0 - ] - ] - ] - }, - "text-size": { - "base": 0.9, - "stops": [ - [ - 4, - 12 - ], - [ - 10, - 22 - ] - ] - } - }, - "maxzoom": 14, - "metadata": { - "mapbox:group": "1444862510685.128" - }, - "minzoom": 1, - "paint": { - "icon-opacity": { - "base": 1, - "stops": [ - [ - 7.99, - 1 - ], - [ - 8, - 0 - ] - ] - }, - "text-color": "hsl(0, 0%, 0%)", - "text-halo-blur": 1, - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 1, - "text-opacity": 1 - }, - "source": "composite", - "source-layer": "place_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - ">=", - "labelrank", - 4 - ] - ], - "id": "marine-label-sm-ln", - "layout": { - "symbol-placement": "line", - "symbol-spacing": { - "base": 1, - "stops": [ - [ - 4, - 100 - ], - [ - 6, - 400 - ] - ] - }, - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Italic", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.1, - "text-line-height": 1.1, - "text-max-width": 5, - "text-size": { - "base": 1, - "stops": [ - [ - 3, - 12 - ], - [ - 6, - 16 - ] - ] - } - }, - "maxzoom": 10, - "metadata": { - "mapbox:group": "1444856087950.3635" - }, - "minzoom": 3, - "paint": { - "text-color": "hsl(205, 83%, 88%)" - }, - "source": "composite", - "source-layer": "marine_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "Point" - ], - [ - ">=", - "labelrank", - 4 - ] - ], - "id": "marine-label-sm-pt", - "layout": { - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Italic", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.1, - "text-line-height": 1.5, - "text-max-width": 5, - "text-size": { - "base": 1, - "stops": [ - [ - 3, - 12 - ], - [ - 6, - 16 - ] - ] - } - }, - "maxzoom": 10, - "metadata": { - "mapbox:group": "1444856087950.3635" - }, - "minzoom": 3, - "paint": { - "text-color": "hsl(205, 83%, 88%)" - }, - "source": "composite", - "source-layer": "marine_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "in", - "labelrank", - 2, - 3 - ] - ], - "id": "marine-label-md-ln", - "layout": { - "symbol-placement": "line", - "symbol-spacing": 250, - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Italic", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.15, - "text-line-height": 1.1, - "text-max-width": 5, - "text-size": { - "base": 1.1, - "stops": [ - [ - 2, - 12 - ], - [ - 5, - 20 - ] - ] - } - }, - "maxzoom": 8, - "metadata": { - "mapbox:group": "1444856087950.3635" - }, - "minzoom": 2, - "paint": { - "text-color": "hsl(205, 83%, 88%)" - }, - "source": "composite", - "source-layer": "marine_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "Point" - ], - [ - "in", - "labelrank", - 2, - 3 - ] - ], - "id": "marine-label-md-pt", - "layout": { - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Italic", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.15, - "text-line-height": 1.5, - "text-max-width": 5, - "text-size": { - "base": 1.1, - "stops": [ - [ - 2, - 14 - ], - [ - 5, - 20 - ] - ] - } - }, - "maxzoom": 8, - "metadata": { - "mapbox:group": "1444856087950.3635" - }, - "minzoom": 2, - "paint": { - "text-color": "hsl(205, 83%, 88%)" - }, - "source": "composite", - "source-layer": "marine_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "LineString" - ], - [ - "==", - "labelrank", - 1 - ] - ], - "id": "marine-label-lg-ln", - "layout": { - "symbol-placement": "line", - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Italic", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.25, - "text-line-height": 1.1, - "text-max-width": 4, - "text-size": { - "base": 1, - "stops": [ - [ - 1, - 14 - ], - [ - 4, - 30 - ] - ] - } - }, - "maxzoom": 4, - "metadata": { - "mapbox:group": "1444856087950.3635" - }, - "minzoom": 1, - "paint": { - "text-color": "hsl(205, 83%, 88%)" - }, - "source": "composite", - "source-layer": "marine_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "==", - "$type", - "Point" - ], - [ - "==", - "labelrank", - 1 - ] - ], - "id": "marine-label-lg-pt", - "layout": { - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Italic", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": 0.25, - "text-line-height": 1.5, - "text-max-width": 4, - "text-size": { - "base": 1, - "stops": [ - [ - 1, - 14 - ], - [ - 4, - 30 - ] - ] - } - }, - "maxzoom": 4, - "metadata": { - "mapbox:group": "1444856087950.3635" - }, - "minzoom": 1, - "paint": { - "text-color": "hsl(205, 83%, 88%)" - }, - "source": "composite", - "source-layer": "marine_label", - "type": "symbol" - }, - { - "filter": [ - "<", - "area", - 20000 - ], - "id": "state-label-sm", - "layout": { - "text-field": { - "base": 1, - "stops": [ - [ - 0, - "{abbr}" - ], - [ - 6, - "{name_en}" - ] - ] - }, - "text-font": [ - "DIN Offc Pro Bold", - "Arial Unicode MS Bold" - ], - "text-letter-spacing": 0.15, - "text-max-width": 5, - "text-size": { - "base": 1, - "stops": [ - [ - 6, - 10 - ], - [ - 9, - 14 - ] - ] - }, - "text-transform": "uppercase" - }, - "maxzoom": 9, - "metadata": { - "mapbox:group": "1444856151690.9143" - }, - "minzoom": 3, - "paint": { - "text-color": "hsl(0, 0%, 0%)", - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 1, - "text-opacity": 1 - }, - "source": "composite", - "source-layer": "state_label", - "type": "symbol" - }, - { - "filter": [ - "all", - [ - "<", - "area", - 80000 - ], - [ - ">=", - "area", - 20000 - ] - ], - "id": "state-label-md", - "layout": { - "text-field": { - "base": 1, - "stops": [ - [ - 0, - "{abbr}" - ], - [ - 5, - "{name_en}" - ] - ] - }, - "text-font": [ - "DIN Offc Pro Bold", - "Arial Unicode MS Bold" - ], - "text-letter-spacing": 0.15, - "text-max-width": 6, - "text-size": { - "base": 1, - "stops": [ - [ - 5, - 10 - ], - [ - 8, - 16 - ] - ] - }, - "text-transform": "uppercase" - }, - "maxzoom": 8, - "metadata": { - "mapbox:group": "1444856151690.9143" - }, - "minzoom": 3, - "paint": { - "text-color": "hsl(0, 0%, 0%)", - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 1, - "text-opacity": 1 - }, - "source": "composite", - "source-layer": "state_label", - "type": "symbol" - }, - { - "filter": [ - ">=", - "area", - 80000 - ], - "id": "state-label-lg", - "layout": { - "text-field": { - "base": 1, - "stops": [ - [ - 0, - "{abbr}" - ], - [ - 4, - "{name_en}" - ] - ] - }, - "text-font": [ - "DIN Offc Pro Bold", - "Arial Unicode MS Bold" - ], - "text-letter-spacing": 0.15, - "text-max-width": 6, - "text-padding": 1, - "text-size": { - "base": 1, - "stops": [ - [ - 4, - 10 - ], - [ - 7, - 18 - ] - ] - }, - "text-transform": "uppercase" - }, - "maxzoom": 7, - "metadata": { - "mapbox:group": "1444856151690.9143" - }, - "minzoom": 3, - "paint": { - "text-color": "hsl(0, 0%, 0%)", - "text-halo-color": "hsl(0, 0%, 100%)", - "text-halo-width": 1, - "text-opacity": 1 - }, - "source": "composite", - "source-layer": "state_label", - "type": "symbol" - }, - { - "filter": [ - ">=", - "scalerank", - 5 - ], - "id": "country-label-sm", - "layout": { - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Medium", - "Arial Unicode MS Regular" - ], - "text-max-width": 6, - "text-size": { - "base": 0.9, - "stops": [ - [ - 5, - 14 - ], - [ - 9, - 22 - ] - ] - } - }, - "maxzoom": 10, - "metadata": { - "mapbox:group": "1444856144497.7825" - }, - "minzoom": 1, - "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 - }, - "source": "composite", - "source-layer": "country_label", - "type": "symbol" - }, - { - "filter": [ - "in", - "scalerank", - 3, - 4 - ], - "id": "country-label-md", - "layout": { - "text-field": { - "base": 1, - "stops": [ - [ - 0, - "{code}" - ], - [ - 2, - "{name_en}" - ] - ] - }, - "text-font": [ - "DIN Offc Pro Medium", - "Arial Unicode MS Regular" - ], - "text-max-width": 6, - "text-size": { - "base": 1, - "stops": [ - [ - 3, - 10 - ], - [ - 8, - 24 - ] - ] - } - }, - "maxzoom": 8, - "metadata": { - "mapbox:group": "1444856144497.7825" - }, - "minzoom": 1, - "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 - }, - "source": "composite", - "source-layer": "country_label", - "type": "symbol" - }, - { - "filter": [ - "in", - "scalerank", - 1, - 2 - ], - "id": "country-label-lg", - "layout": { - "text-field": "{name_en}", - "text-font": [ - "DIN Offc Pro Medium", - "Arial Unicode MS Regular" - ], - "text-max-width": { - "base": 1, - "stops": [ - [ - 0, - 5 - ], - [ - 3, - 6 - ] - ] - }, - "text-size": { - "base": 1, - "stops": [ - [ - 1, - 10 - ], - [ - 6, - 24 - ] - ] - } - }, - "maxzoom": 7, - "metadata": { - "mapbox:group": "1444856144497.7825" - }, - "minzoom": 1, - "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 - }, - "source": "composite", - "source-layer": "country_label", - "type": "symbol" - }, - { - "id": "testlayer", - "type": "symbol", - "source": "testsource", - "layout": { - "icon-image": "test-icon" - } + "version": 8, + "name": "Mapbox Streets", + "metadata": { + "mapbox:autocomposite": true, + "mapbox:type": "default", + "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 } + } + }, + "sources": { + "composite": { "url": "mapbox://mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v7", "type": "vector" } + }, + "sprite": "mapbox://sprites/mapbox/streets-v10", + "glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf", + "visibility": "public", + "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", "ref": "water-shadow", "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", "Polygon" ], [ "!=", "type", "apron" ] ], + "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", + [ "in", "class", "link", "service", "track" ], + [ "==", "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(230, 19%, 75%)", + "line-gap-width": { "base": 1.5, "stops": [ [ 14, 0.5 ], [ 18, 12 ] ] }, + "line-dasharray": [ 3, 3 ] + } + }, + { + "id": "tunnel-street_limited-case", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-street_limited-low", + "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", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-street-low", + "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", [ "in", "class", "secondary", "tertiary" ], [ "==", "structure", "tunnel" ] ] + ], + "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 ] ] + ] } - ], - "metadata": { - "mapbox:autocomposite": true, - "mapbox:groups": { - "1444855769305.6016": { - "collapsed": true, - "name": "Tunnels" - }, - "1444855786460.0557": { - "collapsed": true, - "name": "Roads" - }, - "1444855799204.86": { - "collapsed": true, - "name": "Bridges" - }, - "1444856087950.3635": { - "collapsed": true, - "name": "Marine labels" - }, - "1444856144497.7825": { - "collapsed": true, - "name": "Country labels" - }, - "1444856151690.9143": { - "collapsed": true, - "name": "State labels" - }, - "1444862510685.128": { - "collapsed": true, - "name": "City labels" - }, - "1444933322393.2852": { - "collapsed": true, - "name": "POI labels (scalerank 1)" - }, - "1444933358918.2366": { - "collapsed": true, - "name": "POI labels (scalerank 2)" - }, - "1444933372896.5967": { - "collapsed": true, - "name": "POI labels (scalerank 3)" - }, - "1444933456003.5437": { - "collapsed": true, - "name": "POI labels (scalerank 4)" - }, - "1444933575858.6992": { - "collapsed": true, - "name": "Highway shields" - }, - "1444933721429.3076": { - "collapsed": true, - "name": "Road labels" - }, - "1444933808272.805": { - "collapsed": true, - "name": "Water labels" - }, - "1444934295202.7542": { - "collapsed": true, - "name": "Admin boundaries" - }, - "1444934828655.3389": { - "collapsed": true, - "name": "Aeroways" - }, - "1456969573402.7817": { - "collapsed": true, - "name": "Hillshading" - }, - "1456970288113.8113": { - "collapsed": true, - "name": "Landcover" - } - }, - "mapbox:type": "default" - }, - "modified": 0, - "name": "Mapbox Streets", - "owner": "mapbox", - "sources": { - "composite": { - "type": "vector", - "url": "mapbox://mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v7" - }, - "testsource": { - "type": "geojson", - "data": { - "type": "Point", - "coordinates": [ - -73.992857, - 40.726989 - ] - } + } + }, + { + "id": "tunnel-path", + "type": "line", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ "==", "$type", "LineString" ], + [ + "all", + [ "==", "class", "path" ], + [ "==", "structure", "tunnel" ], + [ "!=", "type", "steps" ] + ] + ], + "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", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-trunk_link-case", + "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", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-motorway_link-case", + "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", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-service-link-track-case", + "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", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-street_limited-low", + "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", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-street-low", + "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", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-secondary-tertiary-case", + "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", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-primary-case", + "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", + [ "in", "class", "link", "path", "pedestrian", "service", "track" ], + [ "==", "oneway", "true" ], + [ "==", "structure", "tunnel" ], + [ "!=", "type", "trunk_link" ] + ] + ], + "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", + [ "in", "class", "primary", "secondary", "street", "street_limited", "tertiary" ], + [ "==", "oneway", "true" ], + [ "==", "structure", "tunnel" ], + [ "!=", "type", "trunk_link" ] + ] + ], + "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", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-motorway-case", + "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", "class", "link", "motorway", "motorway_link", "trunk" ], + [ "==", "oneway", "true" ], + [ "==", "structure", "tunnel" ], + [ "!in", "type", "primary_link", "secondary_link", "tertiary_link" ] + ] + ], + "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", + [ "==", "class", "path" ], + [ "!in", "structure", "bridge", "tunnel" ], + [ "!in", "type", "crossing", "sidewalk", "steps" ] + ] + ], + "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", + [ "in", "class", "link", "service", "track" ], + [ "!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(230, 24%, 87%)", + "line-gap-width": { "base": 1.5, "stops": [ [ 14, 0.5 ], [ 18, 12 ] ] } + } + }, + { + "id": "road-street_limited-case", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-street_limited-low", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-street-low", + "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", "class", "secondary", "tertiary" ], + [ "!in", "structure", "bridge", "tunnel" ] + ] + ], + "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", [ "==", "class", "primary" ], [ "!in", "structure", "bridge", "tunnel" ] ] + ], + "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", [ "==", "class", "motorway_link" ], [ "!in", "structure", "bridge", "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-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", [ "==", "class", "trunk" ], [ "!in", "structure", "bridge", "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": { "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", [ "==", "class", "motorway" ], [ "!in", "structure", "bridge", "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 ] ] } + } + }, + { + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-sidewalk-bg", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-path-bg", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-steps-bg", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-trunk_link-case", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-motorway_link-case", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-pedestrian-case", + "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", [ "in", "class", "path", "pedestrian" ], [ "==", "structure", "none" ] ] + ], + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-pedestrian-polygon-fill", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-service-link-track-case", + "paint": { + "line-width": { "base": 1.5, "stops": [ [ 14, 0.5 ], [ 18, 12 ] ] }, + "line-color": "hsl(0, 0%, 100%)" + } + }, + { + "id": "road-street_limited", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-street_limited-low", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-street-low", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-secondary-tertiary-case", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-primary-case", + "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", + [ "in", "class", "link", "path", "pedestrian", "service", "track" ], + [ "==", "oneway", "true" ], + [ "!in", "structure", "bridge", "tunnel" ], + [ "!=", "type", "trunk_link" ] + ] + ], + "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", + [ "in", "class", "primary", "secondary", "street", "street_limited", "tertiary" ], + [ "==", "oneway", "true" ], + [ "!in", "structure", "bridge", "tunnel" ], + [ "!=", "type", "trunk_link" ] + ] + ], + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-trunk-case", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-motorway-case", + "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", "class", "major_rail", "minor_rail" ], + [ "!in", "structure", "bridge", "tunnel" ] + ] + ], + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-rail", + "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", "class", "link", "motorway", "motorway_link", "trunk" ], + [ "==", "oneway", "true" ], + [ "!in", "structure", "bridge", "tunnel" ], + [ "!in", "type", "primary_link", "secondary_link", "tertiary_link" ] + ] + ], + "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", + [ "==", "class", "path" ], + [ "==", "structure", "bridge" ], + [ "!=", "type", "steps" ] + ] + ], + "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", + [ "in", "class", "link", "service", "track" ], + [ "==", "structure", "bridge" ], + [ "!=", "type", "trunk_link" ] + ] + ], + "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", [ "in", "class", "secondary", "tertiary" ], [ "==", "structure", "bridge" ] ] + ], + "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", + [ "==", "class", "motorway_link" ], + [ "!in", "layer", 2, 3, 4, 5 ], + [ "==", "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", + [ "==", "class", "trunk" ], + [ "!in", "layer", 2, 3, 4, 5 ], + [ "==", "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", + [ "==", "class", "motorway" ], + [ "!in", "layer", 2, 3, 4, 5 ], + [ "==", "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", + [ "==", "class", "path" ], + [ "==", "structure", "bridge" ], + [ "!=", "type", "steps" ] + ] + ], + "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", + "metadata": { "mapbox:group": "1444855799204.86" }, + "ref": "bridge-steps-bg", + "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", + [ "==", "class", "motorway_link" ], + [ "!in", "layer", 2, 3, 4, 5 ], + [ "==", "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", + "metadata": { "mapbox:group": "1444855799204.86" }, + "ref": "bridge-pedestrian-case", + "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", + [ "in", "class", "link", "service", "track" ], + [ "==", "structure", "bridge" ], + [ "!=", "type", "trunk_link" ] + ] + ], + "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", + "metadata": { "mapbox:group": "1444855799204.86" }, + "ref": "bridge-street_limited-low", + "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", + "metadata": { "mapbox:group": "1444855799204.86" }, + "ref": "bridge-street-low", + "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", + [ "in", "class", "link", "path", "pedestrian", "service", "track" ], + [ "==", "oneway", "true" ], + [ "==", "structure", "bridge" ] + ] + ], + "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", + [ "in", "class", "primary", "secondary", "street", "street_limited", "tertiary" ], + [ "==", "oneway", "true" ], + [ "==", "structure", "bridge" ] + ] + ], + "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", + [ "==", "class", "trunk" ], + [ "!in", "layer", 2, 3, 4, 5 ], + [ "==", "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", + [ "==", "class", "motorway" ], + [ "!in", "layer", 2, 3, 4, 5 ], + [ "==", "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", [ "in", "class", "major_rail", "minor_rail" ], [ "==", "structure", "bridge" ] ] + ], + "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", + "metadata": { "mapbox:group": "1444855799204.86" }, + "ref": "bridge-rail", + "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", + [ ">=", "layer", 2 ], + [ "==", "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-2-case", + "type": "line", + "metadata": { "mapbox:group": "1444855799204.86" }, + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ "==", "$type", "LineString" ], + [ + "all", + [ "==", "class", "motorway_link" ], + [ ">=", "layer", 2 ], + [ "==", "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-2-case", + "type": "line", + "metadata": { "mapbox:group": "1444855799204.86" }, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ "==", "$type", "LineString" ], + [ + "all", + [ "==", "class", "trunk" ], + [ ">=", "layer", 2 ], + [ "==", "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-2-case", + "type": "line", + "metadata": { "mapbox:group": "1444855799204.86" }, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ "==", "$type", "LineString" ], + [ + "all", + [ "==", "class", "motorway" ], + [ ">=", "layer", 2 ], + [ "==", "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-trunk_link-2", + "type": "line", + "metadata": { "mapbox:group": "1444855799204.86" }, + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ "==", "$type", "LineString" ], + [ + "all", + [ ">=", "layer", 2 ], + [ "==", "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-2", + "type": "line", + "metadata": { "mapbox:group": "1444855799204.86" }, + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ "==", "$type", "LineString" ], + [ + "all", + [ "==", "class", "motorway_link" ], + [ ">=", "layer", 2 ], + [ "==", "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-trunk-2", + "type": "line", + "metadata": { "mapbox:group": "1444855799204.86" }, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ "==", "$type", "LineString" ], + [ + "all", + [ "==", "class", "trunk" ], + [ ">=", "layer", 2 ], + [ "==", "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-2", + "type": "line", + "metadata": { "mapbox:group": "1444855799204.86" }, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ "==", "$type", "LineString" ], + [ + "all", + [ "==", "class", "motorway" ], + [ ">=", "layer", 2 ], + [ "==", "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-oneway-arrows-white", + "type": "symbol", + "metadata": { "mapbox:group": "1444855799204.86" }, + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "all", + [ "==", "$type", "LineString" ], + [ + "all", + [ "in", "class", "link", "motorway", "motorway_link", "trunk" ], + [ "==", "oneway", "true" ], + [ "==", "structure", "bridge" ], + [ "!in", "type", "primary_link", "secondary_link", "tertiary_link" ] + ] + ], + "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", [ ">=", "admin_level", 3 ], [ "==", "maritime", 0 ] ], + "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", [ ">=", "admin_level", 3 ], [ "==", "maritime", 0 ] ], + "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-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", + [ ">=", "localrank", 15 ], + [ + "!in", + "maki", + "campsite", + "cemetery", + "dog-park", + "garden", + "golf", + "park", + "picnic-site", + "playground", + "zoo" + ], + [ "==", "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": 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", + [ "<=", "localrank", 14 ], + [ + "!in", + "maki", + "campsite", + "cemetery", + "dog-park", + "garden", + "golf", + "park", + "picnic-site", + "playground", + "zoo" + ], + [ "==", "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", + [ + "in", + "maki", + "campsite", + "cemetery", + "dog-park", + "garden", + "golf", + "park", + "picnic-site", + "playground", + "zoo" + ], + [ "==", "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(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", + [ + "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": 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", + [ "==", "$type", "LineString" ], + [ + "!in", + "class", + "link", + "motorway", + "pedestrian", + "primary", + "secondary", + "street", + "street_limited", + "tertiary", + "trunk" + ] + ], + "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-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-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-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", + [ "<=", "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%, 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", 0 ], [ "<=", "reflen", 9 ] ], + "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", + [ + "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(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", + [ "in", "$type", "LineString", "Point", "Polygon" ], + [ "all", [ "<=", "localrank", 10 ], [ "==", "type", "residential" ] ] + ], + "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", + [ + "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(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", + [ "in", "ldir", "E", "S", "SE", "SW" ], + [ "in", "scalerank", 3, 4, 5 ], + [ "==", "type", "city" ] + ], + "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", + [ "in", "ldir", "N", "NE", "NW", "W" ], + [ "in", "scalerank", 3, 4, 5 ], + [ "==", "type", "city" ] + ], + "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", + [ "in", "ldir", "E", "S", "SE", "SW" ], + [ "<=", "scalerank", 2 ], + [ "==", "type", "city" ] + ], + "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", + [ "in", "ldir", "N", "NE", "NW", "W" ], + [ "<=", "scalerank", 2 ], + [ "==", "type", "city" ] + ], + "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-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-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-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 + } }, - "sprite": "mapbox://sprites/mapbox/streets-v9", - "version": 8 -} + { + "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 + } + } + ] +} \ No newline at end of file -- cgit v1.2.1 From 7c117281bc8d53d9d6a1e3a9ff9760a5a5b44cf8 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Wed, 3 Aug 2016 19:24:04 +0300 Subject: [core] Isolate pthread-based tls implementation --- platform/android/config.cmake | 1 + platform/default/thread_local.cpp | 62 +++++++++++++++++++++++++++++++++++++++ platform/ios/config.cmake | 1 + platform/linux/config.cmake | 1 + platform/macos/config.cmake | 1 + platform/qt/qt.cmake | 3 ++ src/mbgl/util/thread_local.hpp | 44 +++++++-------------------- test/util/thread_local.test.cpp | 26 ++++++---------- 8 files changed, 88 insertions(+), 51 deletions(-) create mode 100644 platform/default/thread_local.cpp diff --git a/platform/android/config.cmake b/platform/android/config.cmake index a7370da5fd..5a6950a23f 100644 --- a/platform/android/config.cmake +++ b/platform/android/config.cmake @@ -55,6 +55,7 @@ macro(mbgl_platform_core) PRIVATE platform/android/src/thread.cpp PRIVATE platform/default/string_stdlib.cpp PRIVATE platform/default/bidi.cpp + PRIVATE platform/default/thread_local.cpp PRIVATE platform/default/utf.cpp # Image handling diff --git a/platform/default/thread_local.cpp b/platform/default/thread_local.cpp new file mode 100644 index 0000000000..b754a04b7d --- /dev/null +++ b/platform/default/thread_local.cpp @@ -0,0 +1,62 @@ +#include + +#include +#include +#include + +#include +#include + +#include + +namespace mbgl { +namespace util { + +template +class ThreadLocal::Impl { +public: + pthread_key_t key; +}; + +template +ThreadLocal::ThreadLocal() : impl(std::make_unique()) { + int ret = pthread_key_create(&impl->key, [](void *) {}); + + if (ret) { + throw std::runtime_error("Failed to init local storage key."); + } +} + +template +ThreadLocal::~ThreadLocal() { + delete get(); + + if (pthread_key_delete(impl->key)) { + Log::Error(Event::General, "Failed to delete local storage key."); + assert(false); + } +} + +template +T* ThreadLocal::get() { + auto* ret = reinterpret_cast(pthread_getspecific(impl->key)); + if (!ret) { + return nullptr; + } + + return ret; +} + +template +void ThreadLocal::set(T* ptr) { + if (pthread_setspecific(impl->key, ptr)) { + throw std::runtime_error("Failed to set local storage."); + } +} + +template class ThreadLocal; +template class ThreadLocal; +template class ThreadLocal; // For unit tests + +} // namespace util +} // namespace mbgl diff --git a/platform/ios/config.cmake b/platform/ios/config.cmake index fdb286a6d1..401a0e202a 100644 --- a/platform/ios/config.cmake +++ b/platform/ios/config.cmake @@ -41,6 +41,7 @@ macro(mbgl_platform_core) PRIVATE platform/darwin/src/nsthread.mm PRIVATE platform/darwin/src/string_nsstring.mm PRIVATE platform/default/bidi.cpp + PRIVATE platform/default/thread_local.cpp PRIVATE platform/default/utf.cpp # Image handling diff --git a/platform/linux/config.cmake b/platform/linux/config.cmake index 41e7f71b99..d16842c201 100644 --- a/platform/linux/config.cmake +++ b/platform/linux/config.cmake @@ -69,6 +69,7 @@ macro(mbgl_platform_core) PRIVATE platform/default/string_stdlib.cpp PRIVATE platform/default/thread.cpp PRIVATE platform/default/bidi.cpp + PRIVATE platform/default/thread_local.cpp PRIVATE platform/default/utf.cpp # Image handling diff --git a/platform/macos/config.cmake b/platform/macos/config.cmake index 8dc3c38245..e0edc90a6a 100644 --- a/platform/macos/config.cmake +++ b/platform/macos/config.cmake @@ -37,6 +37,7 @@ macro(mbgl_platform_core) PRIVATE platform/darwin/src/nsthread.mm PRIVATE platform/darwin/src/string_nsstring.mm PRIVATE platform/default/bidi.cpp + PRIVATE platform/default/thread_local.cpp PRIVATE platform/default/utf.cpp # Image handling diff --git a/platform/qt/qt.cmake b/platform/qt/qt.cmake index e5b96bfe93..9febee88b5 100644 --- a/platform/qt/qt.cmake +++ b/platform/qt/qt.cmake @@ -36,6 +36,9 @@ set(MBGL_QT_FILES PRIVATE platform/default/mbgl/util/default_thread_pool.cpp PRIVATE platform/default/mbgl/util/default_thread_pool.hpp + # Thread + PRIVATE platform/default/thread_local.cpp + # Platform integration PRIVATE platform/qt/src/async_task.cpp PRIVATE platform/qt/src/async_task_impl.hpp diff --git a/src/mbgl/util/thread_local.hpp b/src/mbgl/util/thread_local.hpp index 15d4d56524..b0e26356b4 100644 --- a/src/mbgl/util/thread_local.hpp +++ b/src/mbgl/util/thread_local.hpp @@ -1,12 +1,8 @@ #pragma once -#include #include -#include -#include - -#include +#include namespace mbgl { namespace util { @@ -14,40 +10,20 @@ namespace util { template class ThreadLocal : public noncopyable { public: - ThreadLocal() { - int ret = pthread_key_create(&key, [](void *ptr) { - delete reinterpret_cast(ptr); - }); - - if (ret) { - throw std::runtime_error("Failed to init local storage key."); - } - } - - ~ThreadLocal() { - if (pthread_key_delete(key)) { - Log::Error(Event::General, "Failed to delete local storage key."); - assert(false); - } + ThreadLocal(T* val) { + ThreadLocal(); + set(val); } - T* get() { - auto* ret = reinterpret_cast(pthread_getspecific(key)); - if (!ret) { - return nullptr; - } + ThreadLocal(); + ~ThreadLocal(); - return ret; - } - - void set(T* ptr) { - if (pthread_setspecific(key, ptr)) { - throw std::runtime_error("Failed to set local storage."); - } - } + T* get(); + void set(T* ptr); private: - pthread_key_t key; + class Impl; + std::unique_ptr impl; }; } // namespace util diff --git a/test/util/thread_local.test.cpp b/test/util/thread_local.test.cpp index 0590e8b4dc..12a19ab59b 100644 --- a/test/util/thread_local.test.cpp +++ b/test/util/thread_local.test.cpp @@ -71,38 +71,30 @@ TEST(ThreadLocalStorage, NotSetReturnsNull) { namespace { -struct DtorCounter { - ~DtorCounter() { ++(*value); } - unsigned *value; -}; - class TestThreadReclaim { public: - TestThreadReclaim(mbgl::ActorRef, DtorCounter* counter_) { - counter.set(counter_); + TestThreadReclaim(mbgl::ActorRef, int* data_) { + data.set(data_); } private: - static ThreadLocal counter; + ThreadLocal data; }; -ThreadLocal TestThreadReclaim::counter; - } // namespace TEST(ThreadLocalStorage, AutoReclaim) { RunLoop loop; - unsigned counter = 0; - - auto dtorCounter1 = new DtorCounter{ &counter }; - auto dtorCounter2 = new DtorCounter{ &counter }; + auto data1 = new int; + auto data2 = new int; - auto thread1 = std::make_unique>("Test", dtorCounter1); - auto thread2 = std::make_unique>("Test", dtorCounter2); + auto thread1 = std::make_unique>("Test", data1); + auto thread2 = std::make_unique>("Test", data2); thread1.reset(); thread2.reset(); - EXPECT_EQ(counter, 2u); + // Should not leak, valgrind will + // let us know. } -- cgit v1.2.1 From a24d89d9f8499123a03376e58da0c4d6ebe43261 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Wed, 3 Aug 2016 19:56:10 +0300 Subject: [Qt] Use QThreadStorage for thread local Portable. --- platform/qt/qt.cmake | 2 +- platform/qt/src/thread_local.cpp | 44 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 platform/qt/src/thread_local.cpp diff --git a/platform/qt/qt.cmake b/platform/qt/qt.cmake index 9febee88b5..5b09dbf9ab 100644 --- a/platform/qt/qt.cmake +++ b/platform/qt/qt.cmake @@ -37,7 +37,7 @@ set(MBGL_QT_FILES PRIVATE platform/default/mbgl/util/default_thread_pool.hpp # Thread - PRIVATE platform/default/thread_local.cpp + PRIVATE platform/qt/src/thread_local.cpp # Platform integration PRIVATE platform/qt/src/async_task.cpp diff --git a/platform/qt/src/thread_local.cpp b/platform/qt/src/thread_local.cpp new file mode 100644 index 0000000000..e48a9d6e74 --- /dev/null +++ b/platform/qt/src/thread_local.cpp @@ -0,0 +1,44 @@ +#include + +#include +#include + +#include + +#include + +namespace mbgl { +namespace util { + +template +class ThreadLocal::Impl { +public: + QThreadStorage> local; +}; + +template +ThreadLocal::ThreadLocal() : impl(std::make_unique()) { + set(nullptr); +} + +template +ThreadLocal::~ThreadLocal() { + delete get(); +} + +template +T* ThreadLocal::get() { + return impl->local.localData()[0]; +} + +template +void ThreadLocal::set(T* ptr) { + impl->local.localData()[0] = ptr; +} + +template class ThreadLocal; +template class ThreadLocal; +template class ThreadLocal; // For unit tests + +} // namespace util +} // namespace mbgl -- cgit v1.2.1 From 65118296eb4b17f3abdf5613d2f5d07fb83df74c Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Fri, 5 Aug 2016 23:39:35 +0300 Subject: [Qt] Add a no-op thread helper for other platforms --- platform/qt/src/thread.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 platform/qt/src/thread.cpp diff --git a/platform/qt/src/thread.cpp b/platform/qt/src/thread.cpp new file mode 100644 index 0000000000..ade3629b63 --- /dev/null +++ b/platform/qt/src/thread.cpp @@ -0,0 +1,19 @@ +#include + +#include + +namespace mbgl { +namespace platform { + +std::string getCurrentThreadName() { + return "unknown"; +} + +void setCurrentThreadName(const std::string&) { +} + +void makeThreadLowPriority() { +} + +} // namespace platform +} // namespace mbgl -- cgit v1.2.1 From 35b90618b77391eb9cddcfa6286e679c63b14a09 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Fri, 5 Aug 2016 23:45:57 +0300 Subject: [Qt] Make qt.cmake Windows-friendly - Do not build headless view. - Add no-op thread implementation. --- platform/qt/qt.cmake | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/qt/qt.cmake b/platform/qt/qt.cmake index 5b09dbf9ab..5133d517d4 100644 --- a/platform/qt/qt.cmake +++ b/platform/qt/qt.cmake @@ -96,13 +96,17 @@ if (MASON_PLATFORM STREQUAL "osx" OR MASON_PLATFORM STREQUAL "ios") PRIVATE "-framework Foundation" PRIVATE "-framework OpenGL" ) -else() +elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") list(APPEND MBGL_QT_FILES PRIVATE platform/default/thread.cpp ) list(APPEND MBGL_QT_LIBRARIES PRIVATE -lGL ) +elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + list(APPEND MBGL_QT_FILES + PRIVATE platform/qt/src/thread.cpp + ) endif() add_custom_command( -- cgit v1.2.1 From ba328312609d62c3d32f9d01e89dc4a8463b6dc4 Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Fri, 7 Jul 2017 16:45:33 +0300 Subject: [benchmark] add render benchmarks --- benchmark/api/query.benchmark.cpp | 2 +- benchmark/api/render.benchmark.cpp | 79 + benchmark/fixtures/api/query_style.json | 3993 ------------------------------- benchmark/fixtures/api/style.json | 3993 +++++++++++++++++++++++++++++++ cmake/benchmark-files.cmake | 1 + 5 files changed, 4074 insertions(+), 3994 deletions(-) create mode 100644 benchmark/api/render.benchmark.cpp delete mode 100644 benchmark/fixtures/api/query_style.json create mode 100644 benchmark/fixtures/api/style.json diff --git a/benchmark/api/query.benchmark.cpp b/benchmark/api/query.benchmark.cpp index 05732e0e9a..763349c07a 100644 --- a/benchmark/api/query.benchmark.cpp +++ b/benchmark/api/query.benchmark.cpp @@ -24,7 +24,7 @@ public: NetworkStatus::Set(NetworkStatus::Status::Offline); fileSource.setAccessToken("foobar"); - map.getStyle().loadJSON(util::read_file("benchmark/fixtures/api/query_style.json")); + map.getStyle().loadJSON(util::read_file("benchmark/fixtures/api/style.json")); map.setLatLngZoom({ 40.726989, -73.992857 }, 15); // Manhattan map.getStyle().addImage(std::make_unique("test-icon", decodeImage(util::read_file("benchmark/fixtures/api/default_marker.png")), 1.0)); diff --git a/benchmark/api/render.benchmark.cpp b/benchmark/api/render.benchmark.cpp new file mode 100644 index 0000000000..8c71c1a9bf --- /dev/null +++ b/benchmark/api/render.benchmark.cpp @@ -0,0 +1,79 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace mbgl; + +namespace { + +class RenderBenchmark { +public: + RenderBenchmark() { + NetworkStatus::Set(NetworkStatus::Status::Offline); + fileSource.setAccessToken("foobar"); + } + + util::RunLoop loop; + HeadlessBackend backend; + BackendScope scope { backend }; + OffscreenView view { backend.getContext(), { 1000, 1000 } }; + DefaultFileSource fileSource { "benchmark/fixtures/api/cache.db", "." }; + ThreadPool threadPool { 4 }; +}; + +static void prepare(Map& map, optional json = {}) { + map.getStyle().loadJSON(json ? *json : util::read_file("benchmark/fixtures/api/style.json")); + map.setLatLngZoom({ 40.726989, -73.992857 }, 15); // Manhattan + map.getStyle().addImage(std::make_unique("test-icon", + decodeImage(util::read_file("benchmark/fixtures/api/default_marker.png")), 1.0)); +} + +} // end namespace + +static void API_renderStill_reuse_map(::benchmark::State& state) { + RenderBenchmark bench; + Map map { bench.backend, bench.view.getSize(), 1, bench.fileSource, bench.threadPool, MapMode::Still }; + prepare(map); + + while (state.KeepRunning()) { + mbgl::benchmark::render(map, bench.view); + } +} + +static void API_renderStill_reuse_map_switch_styles(::benchmark::State& state) { + RenderBenchmark bench; + Map map { bench.backend, bench.view.getSize(), 1, bench.fileSource, bench.threadPool, MapMode::Still }; + + while (state.KeepRunning()) { + prepare(map, { "{}" }); + mbgl::benchmark::render(map, bench.view); + prepare(map); + mbgl::benchmark::render(map, bench.view); + } +} + +static void API_renderStill_recreate_map(::benchmark::State& state) { + RenderBenchmark bench; + + while (state.KeepRunning()) { + Map map { bench.backend, bench.view.getSize(), 1, bench.fileSource, bench.threadPool, MapMode::Still }; + prepare(map); + mbgl::benchmark::render(map, bench.view); + } +} + +BENCHMARK(API_renderStill_reuse_map); +BENCHMARK(API_renderStill_reuse_map_switch_styles); +BENCHMARK(API_renderStill_recreate_map); diff --git a/benchmark/fixtures/api/query_style.json b/benchmark/fixtures/api/query_style.json deleted file mode 100644 index cf88aeb6ed..0000000000 --- a/benchmark/fixtures/api/query_style.json +++ /dev/null @@ -1,3993 +0,0 @@ -{ - "version": 8, - "name": "Mapbox Streets", - "metadata": { - "mapbox:autocomposite": true, - "mapbox:type": "default", - "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 } - } - }, - "sources": { - "composite": { "url": "mapbox://mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v7", "type": "vector" } - }, - "sprite": "mapbox://sprites/mapbox/streets-v10", - "glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf", - "visibility": "public", - "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", "ref": "water-shadow", "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", "Polygon" ], [ "!=", "type", "apron" ] ], - "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", - [ "in", "class", "link", "service", "track" ], - [ "==", "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(230, 19%, 75%)", - "line-gap-width": { "base": 1.5, "stops": [ [ 14, 0.5 ], [ 18, 12 ] ] }, - "line-dasharray": [ 3, 3 ] - } - }, - { - "id": "tunnel-street_limited-case", - "metadata": { "mapbox:group": "1444855769305.6016" }, - "ref": "tunnel-street_limited-low", - "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", - "metadata": { "mapbox:group": "1444855769305.6016" }, - "ref": "tunnel-street-low", - "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", [ "in", "class", "secondary", "tertiary" ], [ "==", "structure", "tunnel" ] ] - ], - "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", - [ "==", "class", "path" ], - [ "==", "structure", "tunnel" ], - [ "!=", "type", "steps" ] - ] - ], - "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", - "metadata": { "mapbox:group": "1444855769305.6016" }, - "ref": "tunnel-trunk_link-case", - "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", - "metadata": { "mapbox:group": "1444855769305.6016" }, - "ref": "tunnel-motorway_link-case", - "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", - "metadata": { "mapbox:group": "1444855769305.6016" }, - "ref": "tunnel-service-link-track-case", - "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", - "metadata": { "mapbox:group": "1444855769305.6016" }, - "ref": "tunnel-street_limited-low", - "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", - "metadata": { "mapbox:group": "1444855769305.6016" }, - "ref": "tunnel-street-low", - "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", - "metadata": { "mapbox:group": "1444855769305.6016" }, - "ref": "tunnel-secondary-tertiary-case", - "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", - "metadata": { "mapbox:group": "1444855769305.6016" }, - "ref": "tunnel-primary-case", - "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", - [ "in", "class", "link", "path", "pedestrian", "service", "track" ], - [ "==", "oneway", "true" ], - [ "==", "structure", "tunnel" ], - [ "!=", "type", "trunk_link" ] - ] - ], - "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", - [ "in", "class", "primary", "secondary", "street", "street_limited", "tertiary" ], - [ "==", "oneway", "true" ], - [ "==", "structure", "tunnel" ], - [ "!=", "type", "trunk_link" ] - ] - ], - "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", - "metadata": { "mapbox:group": "1444855769305.6016" }, - "ref": "tunnel-motorway-case", - "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", "class", "link", "motorway", "motorway_link", "trunk" ], - [ "==", "oneway", "true" ], - [ "==", "structure", "tunnel" ], - [ "!in", "type", "primary_link", "secondary_link", "tertiary_link" ] - ] - ], - "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", - [ "==", "class", "path" ], - [ "!in", "structure", "bridge", "tunnel" ], - [ "!in", "type", "crossing", "sidewalk", "steps" ] - ] - ], - "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", - [ "in", "class", "link", "service", "track" ], - [ "!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(230, 24%, 87%)", - "line-gap-width": { "base": 1.5, "stops": [ [ 14, 0.5 ], [ 18, 12 ] ] } - } - }, - { - "id": "road-street_limited-case", - "metadata": { "mapbox:group": "1444855786460.0557" }, - "ref": "road-street_limited-low", - "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", - "metadata": { "mapbox:group": "1444855786460.0557" }, - "ref": "road-street-low", - "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", "class", "secondary", "tertiary" ], - [ "!in", "structure", "bridge", "tunnel" ] - ] - ], - "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", [ "==", "class", "primary" ], [ "!in", "structure", "bridge", "tunnel" ] ] - ], - "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", [ "==", "class", "motorway_link" ], [ "!in", "structure", "bridge", "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-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", [ "==", "class", "trunk" ], [ "!in", "structure", "bridge", "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": { "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", [ "==", "class", "motorway" ], [ "!in", "structure", "bridge", "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 ] ] } - } - }, - { - "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", - "metadata": { "mapbox:group": "1444855786460.0557" }, - "ref": "road-sidewalk-bg", - "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", - "metadata": { "mapbox:group": "1444855786460.0557" }, - "ref": "road-path-bg", - "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", - "metadata": { "mapbox:group": "1444855786460.0557" }, - "ref": "road-steps-bg", - "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", - "metadata": { "mapbox:group": "1444855786460.0557" }, - "ref": "road-trunk_link-case", - "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", - "metadata": { "mapbox:group": "1444855786460.0557" }, - "ref": "road-motorway_link-case", - "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", - "metadata": { "mapbox:group": "1444855786460.0557" }, - "ref": "road-pedestrian-case", - "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", [ "in", "class", "path", "pedestrian" ], [ "==", "structure", "none" ] ] - ], - "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", - "metadata": { "mapbox:group": "1444855786460.0557" }, - "ref": "road-pedestrian-polygon-fill", - "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", - "metadata": { "mapbox:group": "1444855786460.0557" }, - "ref": "road-service-link-track-case", - "paint": { - "line-width": { "base": 1.5, "stops": [ [ 14, 0.5 ], [ 18, 12 ] ] }, - "line-color": "hsl(0, 0%, 100%)" - } - }, - { - "id": "road-street_limited", - "metadata": { "mapbox:group": "1444855786460.0557" }, - "ref": "road-street_limited-low", - "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", - "metadata": { "mapbox:group": "1444855786460.0557" }, - "ref": "road-street-low", - "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", - "metadata": { "mapbox:group": "1444855786460.0557" }, - "ref": "road-secondary-tertiary-case", - "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", - "metadata": { "mapbox:group": "1444855786460.0557" }, - "ref": "road-primary-case", - "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", - [ "in", "class", "link", "path", "pedestrian", "service", "track" ], - [ "==", "oneway", "true" ], - [ "!in", "structure", "bridge", "tunnel" ], - [ "!=", "type", "trunk_link" ] - ] - ], - "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", - [ "in", "class", "primary", "secondary", "street", "street_limited", "tertiary" ], - [ "==", "oneway", "true" ], - [ "!in", "structure", "bridge", "tunnel" ], - [ "!=", "type", "trunk_link" ] - ] - ], - "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", - "metadata": { "mapbox:group": "1444855786460.0557" }, - "ref": "road-trunk-case", - "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", - "metadata": { "mapbox:group": "1444855786460.0557" }, - "ref": "road-motorway-case", - "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", "class", "major_rail", "minor_rail" ], - [ "!in", "structure", "bridge", "tunnel" ] - ] - ], - "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", - "metadata": { "mapbox:group": "1444855786460.0557" }, - "ref": "road-rail", - "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", "class", "link", "motorway", "motorway_link", "trunk" ], - [ "==", "oneway", "true" ], - [ "!in", "structure", "bridge", "tunnel" ], - [ "!in", "type", "primary_link", "secondary_link", "tertiary_link" ] - ] - ], - "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", - [ "==", "class", "path" ], - [ "==", "structure", "bridge" ], - [ "!=", "type", "steps" ] - ] - ], - "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", - [ "in", "class", "link", "service", "track" ], - [ "==", "structure", "bridge" ], - [ "!=", "type", "trunk_link" ] - ] - ], - "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", [ "in", "class", "secondary", "tertiary" ], [ "==", "structure", "bridge" ] ] - ], - "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", - [ "==", "class", "motorway_link" ], - [ "!in", "layer", 2, 3, 4, 5 ], - [ "==", "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", - [ "==", "class", "trunk" ], - [ "!in", "layer", 2, 3, 4, 5 ], - [ "==", "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", - [ "==", "class", "motorway" ], - [ "!in", "layer", 2, 3, 4, 5 ], - [ "==", "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", - [ "==", "class", "path" ], - [ "==", "structure", "bridge" ], - [ "!=", "type", "steps" ] - ] - ], - "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", - "metadata": { "mapbox:group": "1444855799204.86" }, - "ref": "bridge-steps-bg", - "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", - [ "==", "class", "motorway_link" ], - [ "!in", "layer", 2, 3, 4, 5 ], - [ "==", "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", - "metadata": { "mapbox:group": "1444855799204.86" }, - "ref": "bridge-pedestrian-case", - "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", - [ "in", "class", "link", "service", "track" ], - [ "==", "structure", "bridge" ], - [ "!=", "type", "trunk_link" ] - ] - ], - "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", - "metadata": { "mapbox:group": "1444855799204.86" }, - "ref": "bridge-street_limited-low", - "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", - "metadata": { "mapbox:group": "1444855799204.86" }, - "ref": "bridge-street-low", - "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", - [ "in", "class", "link", "path", "pedestrian", "service", "track" ], - [ "==", "oneway", "true" ], - [ "==", "structure", "bridge" ] - ] - ], - "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", - [ "in", "class", "primary", "secondary", "street", "street_limited", "tertiary" ], - [ "==", "oneway", "true" ], - [ "==", "structure", "bridge" ] - ] - ], - "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", - [ "==", "class", "trunk" ], - [ "!in", "layer", 2, 3, 4, 5 ], - [ "==", "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", - [ "==", "class", "motorway" ], - [ "!in", "layer", 2, 3, 4, 5 ], - [ "==", "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", [ "in", "class", "major_rail", "minor_rail" ], [ "==", "structure", "bridge" ] ] - ], - "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", - "metadata": { "mapbox:group": "1444855799204.86" }, - "ref": "bridge-rail", - "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", - [ ">=", "layer", 2 ], - [ "==", "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-2-case", - "type": "line", - "metadata": { "mapbox:group": "1444855799204.86" }, - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ "==", "$type", "LineString" ], - [ - "all", - [ "==", "class", "motorway_link" ], - [ ">=", "layer", 2 ], - [ "==", "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-2-case", - "type": "line", - "metadata": { "mapbox:group": "1444855799204.86" }, - "source": "composite", - "source-layer": "road", - "filter": [ - "all", - [ "==", "$type", "LineString" ], - [ - "all", - [ "==", "class", "trunk" ], - [ ">=", "layer", 2 ], - [ "==", "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-2-case", - "type": "line", - "metadata": { "mapbox:group": "1444855799204.86" }, - "source": "composite", - "source-layer": "road", - "filter": [ - "all", - [ "==", "$type", "LineString" ], - [ - "all", - [ "==", "class", "motorway" ], - [ ">=", "layer", 2 ], - [ "==", "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-trunk_link-2", - "type": "line", - "metadata": { "mapbox:group": "1444855799204.86" }, - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ "==", "$type", "LineString" ], - [ - "all", - [ ">=", "layer", 2 ], - [ "==", "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-2", - "type": "line", - "metadata": { "mapbox:group": "1444855799204.86" }, - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ "==", "$type", "LineString" ], - [ - "all", - [ "==", "class", "motorway_link" ], - [ ">=", "layer", 2 ], - [ "==", "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-trunk-2", - "type": "line", - "metadata": { "mapbox:group": "1444855799204.86" }, - "source": "composite", - "source-layer": "road", - "filter": [ - "all", - [ "==", "$type", "LineString" ], - [ - "all", - [ "==", "class", "trunk" ], - [ ">=", "layer", 2 ], - [ "==", "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-2", - "type": "line", - "metadata": { "mapbox:group": "1444855799204.86" }, - "source": "composite", - "source-layer": "road", - "filter": [ - "all", - [ "==", "$type", "LineString" ], - [ - "all", - [ "==", "class", "motorway" ], - [ ">=", "layer", 2 ], - [ "==", "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-oneway-arrows-white", - "type": "symbol", - "metadata": { "mapbox:group": "1444855799204.86" }, - "source": "composite", - "source-layer": "road", - "minzoom": 16, - "filter": [ - "all", - [ "==", "$type", "LineString" ], - [ - "all", - [ "in", "class", "link", "motorway", "motorway_link", "trunk" ], - [ "==", "oneway", "true" ], - [ "==", "structure", "bridge" ], - [ "!in", "type", "primary_link", "secondary_link", "tertiary_link" ] - ] - ], - "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", [ ">=", "admin_level", 3 ], [ "==", "maritime", 0 ] ], - "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", [ ">=", "admin_level", 3 ], [ "==", "maritime", 0 ] ], - "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-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", - [ ">=", "localrank", 15 ], - [ - "!in", - "maki", - "campsite", - "cemetery", - "dog-park", - "garden", - "golf", - "park", - "picnic-site", - "playground", - "zoo" - ], - [ "==", "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": 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", - [ "<=", "localrank", 14 ], - [ - "!in", - "maki", - "campsite", - "cemetery", - "dog-park", - "garden", - "golf", - "park", - "picnic-site", - "playground", - "zoo" - ], - [ "==", "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", - [ - "in", - "maki", - "campsite", - "cemetery", - "dog-park", - "garden", - "golf", - "park", - "picnic-site", - "playground", - "zoo" - ], - [ "==", "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(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", - [ - "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": 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", - [ "==", "$type", "LineString" ], - [ - "!in", - "class", - "link", - "motorway", - "pedestrian", - "primary", - "secondary", - "street", - "street_limited", - "tertiary", - "trunk" - ] - ], - "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-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-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-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", - [ "<=", "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%, 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", 0 ], [ "<=", "reflen", 9 ] ], - "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", - [ - "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(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", - [ "in", "$type", "LineString", "Point", "Polygon" ], - [ "all", [ "<=", "localrank", 10 ], [ "==", "type", "residential" ] ] - ], - "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", - [ - "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(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", - [ "in", "ldir", "E", "S", "SE", "SW" ], - [ "in", "scalerank", 3, 4, 5 ], - [ "==", "type", "city" ] - ], - "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", - [ "in", "ldir", "N", "NE", "NW", "W" ], - [ "in", "scalerank", 3, 4, 5 ], - [ "==", "type", "city" ] - ], - "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", - [ "in", "ldir", "E", "S", "SE", "SW" ], - [ "<=", "scalerank", 2 ], - [ "==", "type", "city" ] - ], - "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", - [ "in", "ldir", "N", "NE", "NW", "W" ], - [ "<=", "scalerank", 2 ], - [ "==", "type", "city" ] - ], - "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-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-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-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 - } - } - ] -} \ No newline at end of file diff --git a/benchmark/fixtures/api/style.json b/benchmark/fixtures/api/style.json new file mode 100644 index 0000000000..cf88aeb6ed --- /dev/null +++ b/benchmark/fixtures/api/style.json @@ -0,0 +1,3993 @@ +{ + "version": 8, + "name": "Mapbox Streets", + "metadata": { + "mapbox:autocomposite": true, + "mapbox:type": "default", + "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 } + } + }, + "sources": { + "composite": { "url": "mapbox://mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v7", "type": "vector" } + }, + "sprite": "mapbox://sprites/mapbox/streets-v10", + "glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf", + "visibility": "public", + "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", "ref": "water-shadow", "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", "Polygon" ], [ "!=", "type", "apron" ] ], + "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", + [ "in", "class", "link", "service", "track" ], + [ "==", "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(230, 19%, 75%)", + "line-gap-width": { "base": 1.5, "stops": [ [ 14, 0.5 ], [ 18, 12 ] ] }, + "line-dasharray": [ 3, 3 ] + } + }, + { + "id": "tunnel-street_limited-case", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-street_limited-low", + "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", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-street-low", + "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", [ "in", "class", "secondary", "tertiary" ], [ "==", "structure", "tunnel" ] ] + ], + "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", + [ "==", "class", "path" ], + [ "==", "structure", "tunnel" ], + [ "!=", "type", "steps" ] + ] + ], + "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", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-trunk_link-case", + "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", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-motorway_link-case", + "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", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-service-link-track-case", + "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", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-street_limited-low", + "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", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-street-low", + "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", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-secondary-tertiary-case", + "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", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-primary-case", + "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", + [ "in", "class", "link", "path", "pedestrian", "service", "track" ], + [ "==", "oneway", "true" ], + [ "==", "structure", "tunnel" ], + [ "!=", "type", "trunk_link" ] + ] + ], + "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", + [ "in", "class", "primary", "secondary", "street", "street_limited", "tertiary" ], + [ "==", "oneway", "true" ], + [ "==", "structure", "tunnel" ], + [ "!=", "type", "trunk_link" ] + ] + ], + "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", + "metadata": { "mapbox:group": "1444855769305.6016" }, + "ref": "tunnel-motorway-case", + "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", "class", "link", "motorway", "motorway_link", "trunk" ], + [ "==", "oneway", "true" ], + [ "==", "structure", "tunnel" ], + [ "!in", "type", "primary_link", "secondary_link", "tertiary_link" ] + ] + ], + "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", + [ "==", "class", "path" ], + [ "!in", "structure", "bridge", "tunnel" ], + [ "!in", "type", "crossing", "sidewalk", "steps" ] + ] + ], + "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", + [ "in", "class", "link", "service", "track" ], + [ "!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(230, 24%, 87%)", + "line-gap-width": { "base": 1.5, "stops": [ [ 14, 0.5 ], [ 18, 12 ] ] } + } + }, + { + "id": "road-street_limited-case", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-street_limited-low", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-street-low", + "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", "class", "secondary", "tertiary" ], + [ "!in", "structure", "bridge", "tunnel" ] + ] + ], + "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", [ "==", "class", "primary" ], [ "!in", "structure", "bridge", "tunnel" ] ] + ], + "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", [ "==", "class", "motorway_link" ], [ "!in", "structure", "bridge", "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-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", [ "==", "class", "trunk" ], [ "!in", "structure", "bridge", "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": { "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", [ "==", "class", "motorway" ], [ "!in", "structure", "bridge", "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 ] ] } + } + }, + { + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-sidewalk-bg", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-path-bg", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-steps-bg", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-trunk_link-case", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-motorway_link-case", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-pedestrian-case", + "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", [ "in", "class", "path", "pedestrian" ], [ "==", "structure", "none" ] ] + ], + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-pedestrian-polygon-fill", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-service-link-track-case", + "paint": { + "line-width": { "base": 1.5, "stops": [ [ 14, 0.5 ], [ 18, 12 ] ] }, + "line-color": "hsl(0, 0%, 100%)" + } + }, + { + "id": "road-street_limited", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-street_limited-low", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-street-low", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-secondary-tertiary-case", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-primary-case", + "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", + [ "in", "class", "link", "path", "pedestrian", "service", "track" ], + [ "==", "oneway", "true" ], + [ "!in", "structure", "bridge", "tunnel" ], + [ "!=", "type", "trunk_link" ] + ] + ], + "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", + [ "in", "class", "primary", "secondary", "street", "street_limited", "tertiary" ], + [ "==", "oneway", "true" ], + [ "!in", "structure", "bridge", "tunnel" ], + [ "!=", "type", "trunk_link" ] + ] + ], + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-trunk-case", + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-motorway-case", + "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", "class", "major_rail", "minor_rail" ], + [ "!in", "structure", "bridge", "tunnel" ] + ] + ], + "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", + "metadata": { "mapbox:group": "1444855786460.0557" }, + "ref": "road-rail", + "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", "class", "link", "motorway", "motorway_link", "trunk" ], + [ "==", "oneway", "true" ], + [ "!in", "structure", "bridge", "tunnel" ], + [ "!in", "type", "primary_link", "secondary_link", "tertiary_link" ] + ] + ], + "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", + [ "==", "class", "path" ], + [ "==", "structure", "bridge" ], + [ "!=", "type", "steps" ] + ] + ], + "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", + [ "in", "class", "link", "service", "track" ], + [ "==", "structure", "bridge" ], + [ "!=", "type", "trunk_link" ] + ] + ], + "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", [ "in", "class", "secondary", "tertiary" ], [ "==", "structure", "bridge" ] ] + ], + "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", + [ "==", "class", "motorway_link" ], + [ "!in", "layer", 2, 3, 4, 5 ], + [ "==", "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", + [ "==", "class", "trunk" ], + [ "!in", "layer", 2, 3, 4, 5 ], + [ "==", "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", + [ "==", "class", "motorway" ], + [ "!in", "layer", 2, 3, 4, 5 ], + [ "==", "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", + [ "==", "class", "path" ], + [ "==", "structure", "bridge" ], + [ "!=", "type", "steps" ] + ] + ], + "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", + "metadata": { "mapbox:group": "1444855799204.86" }, + "ref": "bridge-steps-bg", + "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", + [ "==", "class", "motorway_link" ], + [ "!in", "layer", 2, 3, 4, 5 ], + [ "==", "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", + "metadata": { "mapbox:group": "1444855799204.86" }, + "ref": "bridge-pedestrian-case", + "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", + [ "in", "class", "link", "service", "track" ], + [ "==", "structure", "bridge" ], + [ "!=", "type", "trunk_link" ] + ] + ], + "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", + "metadata": { "mapbox:group": "1444855799204.86" }, + "ref": "bridge-street_limited-low", + "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", + "metadata": { "mapbox:group": "1444855799204.86" }, + "ref": "bridge-street-low", + "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", + [ "in", "class", "link", "path", "pedestrian", "service", "track" ], + [ "==", "oneway", "true" ], + [ "==", "structure", "bridge" ] + ] + ], + "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", + [ "in", "class", "primary", "secondary", "street", "street_limited", "tertiary" ], + [ "==", "oneway", "true" ], + [ "==", "structure", "bridge" ] + ] + ], + "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", + [ "==", "class", "trunk" ], + [ "!in", "layer", 2, 3, 4, 5 ], + [ "==", "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", + [ "==", "class", "motorway" ], + [ "!in", "layer", 2, 3, 4, 5 ], + [ "==", "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", [ "in", "class", "major_rail", "minor_rail" ], [ "==", "structure", "bridge" ] ] + ], + "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", + "metadata": { "mapbox:group": "1444855799204.86" }, + "ref": "bridge-rail", + "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", + [ ">=", "layer", 2 ], + [ "==", "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-2-case", + "type": "line", + "metadata": { "mapbox:group": "1444855799204.86" }, + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ "==", "$type", "LineString" ], + [ + "all", + [ "==", "class", "motorway_link" ], + [ ">=", "layer", 2 ], + [ "==", "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-2-case", + "type": "line", + "metadata": { "mapbox:group": "1444855799204.86" }, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ "==", "$type", "LineString" ], + [ + "all", + [ "==", "class", "trunk" ], + [ ">=", "layer", 2 ], + [ "==", "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-2-case", + "type": "line", + "metadata": { "mapbox:group": "1444855799204.86" }, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ "==", "$type", "LineString" ], + [ + "all", + [ "==", "class", "motorway" ], + [ ">=", "layer", 2 ], + [ "==", "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-trunk_link-2", + "type": "line", + "metadata": { "mapbox:group": "1444855799204.86" }, + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ "==", "$type", "LineString" ], + [ + "all", + [ ">=", "layer", 2 ], + [ "==", "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-2", + "type": "line", + "metadata": { "mapbox:group": "1444855799204.86" }, + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ "==", "$type", "LineString" ], + [ + "all", + [ "==", "class", "motorway_link" ], + [ ">=", "layer", 2 ], + [ "==", "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-trunk-2", + "type": "line", + "metadata": { "mapbox:group": "1444855799204.86" }, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ "==", "$type", "LineString" ], + [ + "all", + [ "==", "class", "trunk" ], + [ ">=", "layer", 2 ], + [ "==", "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-2", + "type": "line", + "metadata": { "mapbox:group": "1444855799204.86" }, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ "==", "$type", "LineString" ], + [ + "all", + [ "==", "class", "motorway" ], + [ ">=", "layer", 2 ], + [ "==", "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-oneway-arrows-white", + "type": "symbol", + "metadata": { "mapbox:group": "1444855799204.86" }, + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "all", + [ "==", "$type", "LineString" ], + [ + "all", + [ "in", "class", "link", "motorway", "motorway_link", "trunk" ], + [ "==", "oneway", "true" ], + [ "==", "structure", "bridge" ], + [ "!in", "type", "primary_link", "secondary_link", "tertiary_link" ] + ] + ], + "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", [ ">=", "admin_level", 3 ], [ "==", "maritime", 0 ] ], + "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", [ ">=", "admin_level", 3 ], [ "==", "maritime", 0 ] ], + "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-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", + [ ">=", "localrank", 15 ], + [ + "!in", + "maki", + "campsite", + "cemetery", + "dog-park", + "garden", + "golf", + "park", + "picnic-site", + "playground", + "zoo" + ], + [ "==", "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": 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", + [ "<=", "localrank", 14 ], + [ + "!in", + "maki", + "campsite", + "cemetery", + "dog-park", + "garden", + "golf", + "park", + "picnic-site", + "playground", + "zoo" + ], + [ "==", "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", + [ + "in", + "maki", + "campsite", + "cemetery", + "dog-park", + "garden", + "golf", + "park", + "picnic-site", + "playground", + "zoo" + ], + [ "==", "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(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", + [ + "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": 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", + [ "==", "$type", "LineString" ], + [ + "!in", + "class", + "link", + "motorway", + "pedestrian", + "primary", + "secondary", + "street", + "street_limited", + "tertiary", + "trunk" + ] + ], + "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-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-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-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", + [ "<=", "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%, 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", 0 ], [ "<=", "reflen", 9 ] ], + "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", + [ + "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(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", + [ "in", "$type", "LineString", "Point", "Polygon" ], + [ "all", [ "<=", "localrank", 10 ], [ "==", "type", "residential" ] ] + ], + "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", + [ + "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(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", + [ "in", "ldir", "E", "S", "SE", "SW" ], + [ "in", "scalerank", 3, 4, 5 ], + [ "==", "type", "city" ] + ], + "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", + [ "in", "ldir", "N", "NE", "NW", "W" ], + [ "in", "scalerank", 3, 4, 5 ], + [ "==", "type", "city" ] + ], + "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", + [ "in", "ldir", "E", "S", "SE", "SW" ], + [ "<=", "scalerank", 2 ], + [ "==", "type", "city" ] + ], + "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", + [ "in", "ldir", "N", "NE", "NW", "W" ], + [ "<=", "scalerank", 2 ], + [ "==", "type", "city" ] + ], + "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-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-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-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 + } + } + ] +} \ No newline at end of file diff --git a/cmake/benchmark-files.cmake b/cmake/benchmark-files.cmake index 3736df11f6..35931a6b52 100644 --- a/cmake/benchmark-files.cmake +++ b/cmake/benchmark-files.cmake @@ -3,6 +3,7 @@ set(MBGL_BENCHMARK_FILES # api benchmark/api/query.benchmark.cpp + benchmark/api/render.benchmark.cpp # include/mbgl benchmark/include/mbgl/benchmark.hpp -- cgit v1.2.1 From b87816a7ab3a1b154a6b76a8c97e2f1c7a43e0e4 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 7 Jul 2017 19:22:58 +0200 Subject: [android] - build SNAPSHOT from master (#9452) --- circle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index 9354a6d854..b866556d77 100644 --- a/circle.yml +++ b/circle.yml @@ -166,7 +166,7 @@ jobs: - deploy: name: Publish to Maven command: | - if [ "${CIRCLE_BRANCH}" == "release-ios-v3.6.0-android-v5.1.0" ]; then make run-android-upload-archives ; fi + if [ "${CIRCLE_BRANCH}" == "master" ]; then make run-android-upload-archives ; fi - save_cache: key: v1-android-release-all paths: -- cgit v1.2.1 From 7d59e3f8b3a0b83833cd87eb8bfefa7d0856f0a9 Mon Sep 17 00:00:00 2001 From: Antonio Zugaldia Date: Sun, 9 Jul 2017 11:16:18 -0400 Subject: [android] fix javadoc comment for public setOfflineMapboxTileCountLimit method (#9454) --- .../main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) 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 1cf3711255..1e6f44f094 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 @@ -236,10 +236,11 @@ public class OfflineManager { return LatLngBounds.world().contains(definition.getBounds()); } - /* - * Changing or bypassing this limit without permission from Mapbox is prohibited - * by the Mapbox Terms of Service. - */ + /** + * Changing or bypassing this limit without permission from Mapbox is prohibited + * by the Mapbox Terms of Service. + * @param limit the new tile count limit. + */ public native void setOfflineMapboxTileCountLimit(long limit); private native void initialize(FileSource fileSource); -- cgit v1.2.1 From 90c61c195622c8b3106ed4a3d5c6080dfa8a65e0 Mon Sep 17 00:00:00 2001 From: Jason Wray Date: Mon, 10 Jul 2017 17:32:43 -0400 Subject: [darwin] Include polylabel via cmake --- platform/ios/config.cmake | 1 + platform/ios/ios.xcodeproj/project.pbxproj | 30 ++++++-------------------- platform/macos/config.cmake | 1 + platform/macos/macos.xcodeproj/project.pbxproj | 20 ++++------------- scripts/config.xcconfig.in | 1 - 5 files changed, 12 insertions(+), 41 deletions(-) diff --git a/platform/ios/config.cmake b/platform/ios/config.cmake index 401a0e202a..30cfad5d4b 100644 --- a/platform/ios/config.cmake +++ b/platform/ios/config.cmake @@ -66,6 +66,7 @@ macro(mbgl_platform_core) ) target_add_mason_package(mbgl-core PUBLIC geojson) + target_add_mason_package(mbgl-core PUBLIC polylabel) target_add_mason_package(mbgl-core PRIVATE icu) target_compile_options(mbgl-core diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index 9af8387233..37d87fa797 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -2697,10 +2697,7 @@ baseConfigurationReference = 55D8C9941D0F133500F42F10 /* config.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; INFOPLIST_FILE = test/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -2724,10 +2721,7 @@ baseConfigurationReference = 55D8C9941D0F133500F42F10 /* config.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; INFOPLIST_FILE = test/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -2755,10 +2749,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; INFOPLIST_FILE = framework/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; @@ -2792,10 +2783,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; INFOPLIST_FILE = framework/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; @@ -2846,10 +2834,7 @@ baseConfigurationReference = 55D8C9941D0F133500F42F10 /* config.xcconfig */; buildSettings = { BITCODE_GENERATION_MODE = bitcode; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "$(sqlite_cflags)", @@ -2875,10 +2860,7 @@ baseConfigurationReference = 55D8C9941D0F133500F42F10 /* config.xcconfig */; buildSettings = { BITCODE_GENERATION_MODE = bitcode; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "$(sqlite_cflags)", diff --git a/platform/macos/config.cmake b/platform/macos/config.cmake index e0edc90a6a..33ab1d7c9e 100644 --- a/platform/macos/config.cmake +++ b/platform/macos/config.cmake @@ -62,6 +62,7 @@ macro(mbgl_platform_core) ) target_add_mason_package(mbgl-core PUBLIC geojson) + target_add_mason_package(mbgl-core PUBLIC polylabel) target_add_mason_package(mbgl-core PRIVATE icu) target_compile_options(mbgl-core diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj index 723bbc6f4b..3283c5b5bb 100644 --- a/platform/macos/macos.xcodeproj/project.pbxproj +++ b/platform/macos/macos.xcodeproj/project.pbxproj @@ -1791,10 +1791,7 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_VERSION = A; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; INFOPLIST_FILE = "$(SRCROOT)/sdk/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; @@ -1828,10 +1825,7 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_VERSION = A; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; INFOPLIST_FILE = "$(SRCROOT)/sdk/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; @@ -1855,10 +1849,7 @@ buildSettings = { CLANG_ENABLE_MODULES = YES; COMBINE_HIDPI_IMAGES = YES; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; INFOPLIST_FILE = test/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; LIBRARY_SEARCH_PATHS = ( @@ -1887,10 +1878,7 @@ buildSettings = { CLANG_ENABLE_MODULES = YES; COMBINE_HIDPI_IMAGES = YES; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; INFOPLIST_FILE = test/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; OTHER_CFLAGS = "-fvisibility=hidden"; diff --git a/scripts/config.xcconfig.in b/scripts/config.xcconfig.in index b70ff9d677..eb6bc71b89 100644 --- a/scripts/config.xcconfig.in +++ b/scripts/config.xcconfig.in @@ -3,4 +3,3 @@ // mbgl-core mbgl_core_INCLUDE_DIRECTORIES = "@mbgl_core_INCLUDE_DIRECTORIES@" mbgl_core_LINK_LIBRARIES = "@mbgl_core_LINK_LIBRARIES@" -polylabel_INCLUDE_DIRECTORIES = "@MASON_PACKAGE_polylabel_INCLUDE_DIRS@" -- cgit v1.2.1 From 5e2305fa5b361f13c26bcc6254e18889aaf3da67 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Mon, 10 Jul 2017 15:58:18 +0300 Subject: [benchmark] Fix build on GCC 5 For some mysterious reason GCC 5 was complaining about the implicit default value. Passing it explicitly fixes it. --- benchmark/api/query.benchmark.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmark/api/query.benchmark.cpp b/benchmark/api/query.benchmark.cpp index 763349c07a..4c11a56da5 100644 --- a/benchmark/api/query.benchmark.cpp +++ b/benchmark/api/query.benchmark.cpp @@ -48,7 +48,7 @@ static void API_queryRenderedFeaturesAll(::benchmark::State& state) { QueryBenchmark bench; while (state.KeepRunning()) { - bench.map.queryRenderedFeatures(bench.box); + bench.map.queryRenderedFeatures(bench.box, {}); } } -- cgit v1.2.1 From 3f1c6dabf105f2463cb4955da4754228b02fac92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Tue, 11 Jul 2017 11:38:07 +0200 Subject: [build] add -fvisibility=hidden for all macOS targets to avoid linker warnings --- platform/macos/config.cmake | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/platform/macos/config.cmake b/platform/macos/config.cmake index 33ab1d7c9e..de17dfb067 100644 --- a/platform/macos/config.cmake +++ b/platform/macos/config.cmake @@ -92,6 +92,9 @@ macro(mbgl_platform_glfw) target_link_libraries(mbgl-glfw PRIVATE mbgl-loop-darwin ) + target_compile_options(mbgl-glfw + PRIVATE -fvisibility=hidden + ) endmacro() @@ -99,6 +102,9 @@ macro(mbgl_platform_render) target_link_libraries(mbgl-render PRIVATE mbgl-loop-darwin ) + target_compile_options(mbgl-render + PRIVATE -fvisibility=hidden + ) endmacro() @@ -106,6 +112,9 @@ macro(mbgl_platform_offline) target_link_libraries(mbgl-offline PRIVATE mbgl-loop-darwin ) + target_compile_options(mbgl-offline + PRIVATE -fvisibility=hidden + ) endmacro() -- cgit v1.2.1 From d03fd0dce2efc101021b4cf351945680afaa4349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Mon, 10 Jul 2017 13:48:43 +0200 Subject: [build] Don't use maybe-uninitialized and misleading-indentation in Clang, since they're not implemented there --- src/mbgl/annotation/symbol_annotation_impl.hpp | 2 ++ src/mbgl/text/collision_tile.hpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/mbgl/annotation/symbol_annotation_impl.hpp b/src/mbgl/annotation/symbol_annotation_impl.hpp index 9270acb857..e41ff85f33 100644 --- a/src/mbgl/annotation/symbol_annotation_impl.hpp +++ b/src/mbgl/annotation/symbol_annotation_impl.hpp @@ -17,8 +17,10 @@ #pragma GCC diagnostic ignored "-Wdeprecated-register" #pragma GCC diagnostic ignored "-Wshorten-64-to-32" #pragma GCC diagnostic ignored "-Wunused-local-typedefs" +#ifndef __clang__ #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #pragma GCC diagnostic ignored "-Wmisleading-indentation" +#endif #include #include #include diff --git a/src/mbgl/text/collision_tile.hpp b/src/mbgl/text/collision_tile.hpp index bdacbb7437..59fd1a3927 100644 --- a/src/mbgl/text/collision_tile.hpp +++ b/src/mbgl/text/collision_tile.hpp @@ -16,8 +16,10 @@ #pragma GCC diagnostic ignored "-Wdeprecated-register" #pragma GCC diagnostic ignored "-Wshorten-64-to-32" #pragma GCC diagnostic ignored "-Wunused-local-typedefs" +#ifndef __clang__ #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #pragma GCC diagnostic ignored "-Wmisleading-indentation" +#endif #include #include #include -- cgit v1.2.1 From e364f24570f863044b9c464c2eb8c0fd75c5a80b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Tue, 11 Jul 2017 11:33:51 +0200 Subject: [build] Don't fail hard for unknown warning groups --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 189f033b79..694147fc8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,7 +77,10 @@ if(APPLE) endif() set(CMAKE_CXX_FLAGS_RELEASE "-Os -DNDEBUG") -if(CMAKE_COMPILER_IS_GNUCXX) + +if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=unknown-warning-option") +elseif(CMAKE_COMPILER_IS_GNUCXX) # https://svn.boost.org/trac/boost/ticket/9240 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fext-numeric-literals") endif() -- cgit v1.2.1 From 59df3a90f41461562a80688337ec53687e341124 Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Mon, 15 May 2017 14:17:06 -0700 Subject: [core] Improved label pitch-scaling: approximate collision box shapes based on tile distance from camera. --- src/mbgl/map/transform_state.cpp | 12 +++++++++ src/mbgl/map/transform_state.hpp | 2 ++ src/mbgl/programs/symbol_program.cpp | 2 ++ src/mbgl/programs/symbol_program.hpp | 6 ++++- src/mbgl/renderer/tile_pyramid.cpp | 13 +++++++--- src/mbgl/text/collision_tile.cpp | 50 +++++++++++++++++++++++++----------- src/mbgl/text/collision_tile.hpp | 6 +++-- src/mbgl/text/placement_config.hpp | 8 +++--- src/mbgl/tile/geometry_tile.cpp | 4 +++ src/mbgl/tile/geometry_tile.hpp | 2 ++ src/mbgl/tile/tile.hpp | 2 ++ 11 files changed, 82 insertions(+), 25 deletions(-) diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp index f052e30a6b..4606e3eece 100644 --- a/src/mbgl/map/transform_state.cpp +++ b/src/mbgl/map/transform_state.cpp @@ -385,4 +385,16 @@ void TransformState::setScalePoint(const double newScale, const ScreenCoordinate Cc = Projection::worldSize(scale) / util::M2PI; } +float TransformState::getCameraToTileDistance(const UnwrappedTileID& tileID) const { + mat4 projectionMatrix; + getProjMatrix(projectionMatrix); + mat4 tileProjectionMatrix; + matrixFor(tileProjectionMatrix, tileID); + matrix::multiply(tileProjectionMatrix, projectionMatrix, tileProjectionMatrix); + vec4 tileCenter = {{util::tileSize / 2, util::tileSize / 2, 0, 1}}; + vec4 projectedCenter; + matrix::transformMat4(projectedCenter, tileCenter, tileProjectionMatrix); + return projectedCenter[3]; +} + } // namespace mbgl diff --git a/src/mbgl/map/transform_state.hpp b/src/mbgl/map/transform_state.hpp index e6464aeacc..f35f570549 100644 --- a/src/mbgl/map/transform_state.hpp +++ b/src/mbgl/map/transform_state.hpp @@ -86,6 +86,8 @@ public: return !size.isEmpty() && (scale >= min_scale && scale <= max_scale); } + float getCameraToTileDistance(const UnwrappedTileID&) const; + private: bool rotatedNorth() const; void constrain(double& scale, double& x, double& y) const; diff --git a/src/mbgl/programs/symbol_program.cpp b/src/mbgl/programs/symbol_program.cpp index cdbd6b9713..789eed0dd8 100644 --- a/src/mbgl/programs/symbol_program.cpp +++ b/src/mbgl/programs/symbol_program.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -57,6 +58,7 @@ Values makeValues(const bool isText, uniforms::u_texture::Value{ 0 }, uniforms::u_fadetexture::Value{ 1 }, uniforms::u_is_text::Value{ isText }, + uniforms::u_collision_y_stretch::Value{ tile.tile.yStretch() }, std::forward(args)... }; } diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index c11e0b5ca1..d1a6b4b994 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -42,6 +42,7 @@ MBGL_DEFINE_UNIFORM_SCALAR(bool, u_is_size_feature_constant); MBGL_DEFINE_UNIFORM_SCALAR(float, u_size_t); MBGL_DEFINE_UNIFORM_SCALAR(float, u_size); MBGL_DEFINE_UNIFORM_SCALAR(float, u_layout_size); +MBGL_DEFINE_UNIFORM_SCALAR(float, u_collision_y_stretch); } // namespace uniforms struct SymbolLayoutAttributes : gl::Attributes< @@ -389,7 +390,8 @@ class SymbolIconProgram : public SymbolProgram< uniforms::u_rotate_with_map, uniforms::u_texture, uniforms::u_fadetexture, - uniforms::u_is_text>, + uniforms::u_is_text, + uniforms::u_collision_y_stretch>, style::IconPaintProperties> { public: @@ -422,6 +424,7 @@ class SymbolSDFProgram : public SymbolProgram< uniforms::u_texture, uniforms::u_fadetexture, uniforms::u_is_text, + uniforms::u_collision_y_stretch, uniforms::u_gamma_scale, uniforms::u_pitch, uniforms::u_bearing, @@ -443,6 +446,7 @@ public: uniforms::u_texture, uniforms::u_fadetexture, uniforms::u_is_text, + uniforms::u_collision_y_stretch, uniforms::u_gamma_scale, uniforms::u_pitch, uniforms::u_bearing, diff --git a/src/mbgl/renderer/tile_pyramid.cpp b/src/mbgl/renderer/tile_pyramid.cpp index a8e6c128ba..57e7f6d375 100644 --- a/src/mbgl/renderer/tile_pyramid.cpp +++ b/src/mbgl/renderer/tile_pyramid.cpp @@ -175,11 +175,16 @@ void TilePyramid::update(const std::vector>& layer removeStaleTiles(retain); - const PlacementConfig config { parameters.transformState.getAngle(), - parameters.transformState.getPitch(), - parameters.debugOptions & MapDebugOptions::Collision }; - for (auto& pair : tiles) { + // TODO: Calculating yStretch based on tile distance means we can no longer use the same collision tile for two wrapped + // copies of the same data tile. For now the assumption that we're always at "wrap = 0" means collision detection is broken + // for wrapped tiles. + const PlacementConfig config { parameters.transformState.getAngle(), + parameters.transformState.getPitch(), + parameters.transformState.getCameraToCenterDistance(), + parameters.transformState.getCameraToTileDistance(pair.first.unwrapTo(0)), + parameters.debugOptions & MapDebugOptions::Collision }; + pair.second->setPlacementConfig(config); } } diff --git a/src/mbgl/text/collision_tile.cpp b/src/mbgl/text/collision_tile.cpp index 368750c89f..520f66ead8 100644 --- a/src/mbgl/text/collision_tile.cpp +++ b/src/mbgl/text/collision_tile.cpp @@ -20,12 +20,17 @@ CollisionTile::CollisionTile(PlacementConfig config_) : config(std::move(config_ rotationMatrix = { { angle_cos, -angle_sin, angle_sin, angle_cos } }; reverseRotationMatrix = { { angle_cos, angle_sin, -angle_sin, angle_cos } }; - // Stretch boxes in y direction to account for the map tilt. - const float _yStretch = 1.0f / std::cos(config.pitch); - - // The amount the map is squished depends on the y position. - // Sort of account for this by making all boxes a bit bigger. - yStretch = std::pow(_yStretch, 1.3f); + perspectiveRatio = 1.0f + 0.5f * ((config.cameraToTileDistance / config.cameraToCenterDistance) - 1.0f); + minScale /= perspectiveRatio; + maxScale /= perspectiveRatio; + + // We can only approximate here based on the y position of the tile + // The shaders calculate a more accurate "incidence_stretch" + // at render time to calculate an effective scale for collision + // purposes, but we still want to use the yStretch approximation + // here because we can't adjust the aspect ratio of the collision + // boxes at render time. + yStretch = util::max(1.0f, config.cameraToTileDistance / (config.cameraToCenterDistance * std::cos(config.pitch))); } @@ -157,13 +162,21 @@ void CollisionTile::insertFeature(CollisionFeature& feature, float minPlacementS Box CollisionTile::getTreeBox(const Point& anchor, const CollisionBox& box, const float scale) { assert(box.x1 <= box.x2 && box.y1 <= box.y2); return Box{ + // When the 'perspectiveRatio' is high, we're effectively underzooming + // the tile because it's in the distance. + // In order to detect collisions that only happen while underzoomed, + // we have to query a larger portion of the grid. + // This extra work is offset by having a lower 'maxScale' bound + // Note that this adjustment ONLY affects the bounding boxes + // in the grid. It doesn't affect the boxes used for the + // minPlacementScale calculations. CollisionPoint{ - anchor.x + box.x1 / scale, - anchor.y + box.y1 / scale * yStretch + anchor.x + box.x1 / scale * perspectiveRatio, + anchor.y + box.y1 / scale * yStretch * perspectiveRatio, }, CollisionPoint{ - anchor.x + box.x2 / scale, - anchor.y + box.y2 / scale * yStretch + anchor.x + box.x2 / scale * perspectiveRatio, + anchor.y + box.y2 / scale * yStretch * perspectiveRatio } }; } @@ -190,8 +203,14 @@ std::vector CollisionTile::queryRenderedSymbols(const Geometr return seenFeatures.find(feature.index) == seenFeatures.end(); }; + // "perspectiveRatio" is a tile-based approximation of how much larger symbols will + // be in the distance. It won't line up exactly with the actually rendered symbols + // Being exact would require running the collision detection logic in symbol_sdf.vertex + // in the CPU + const float perspectiveScale = scale / perspectiveRatio; + // Account for the rounding done when updating symbol shader variables. - const float roundedScale = std::pow(2.0f, std::ceil(util::log2(scale) * 10.0f) / 10.0f); + const float roundedScale = std::pow(2.0f, std::ceil(util::log2(perspectiveScale) * 10.0f) / 10.0f); // Check if feature is rendered (collision free) at current scale. auto visibleAtScale = [&] (const CollisionTreeBox& treeBox) -> bool { @@ -203,10 +222,11 @@ std::vector CollisionTile::queryRenderedSymbols(const Geometr auto intersectsAtScale = [&] (const CollisionTreeBox& treeBox) -> bool { const CollisionBox& collisionBox = std::get<1>(treeBox); const auto anchor = util::matrixMultiply(rotationMatrix, collisionBox.anchor); - const int16_t x1 = anchor.x + collisionBox.x1 / scale; - const int16_t y1 = anchor.y + collisionBox.y1 / scale * yStretch; - const int16_t x2 = anchor.x + collisionBox.x2 / scale; - const int16_t y2 = anchor.y + collisionBox.y2 / scale * yStretch; + + const int16_t x1 = anchor.x + (collisionBox.x1 / perspectiveScale); + const int16_t y1 = anchor.y + (collisionBox.y1 / perspectiveScale) * yStretch; + const int16_t x2 = anchor.x + (collisionBox.x2 / perspectiveScale); + const int16_t y2 = anchor.y + (collisionBox.y2 / perspectiveScale) * yStretch; auto bbox = GeometryCoordinates { { x1, y1 }, { x2, y1 }, { x2, y2 }, { x1, y2 } }; diff --git a/src/mbgl/text/collision_tile.hpp b/src/mbgl/text/collision_tile.hpp index 59fd1a3927..dbff6a007b 100644 --- a/src/mbgl/text/collision_tile.hpp +++ b/src/mbgl/text/collision_tile.hpp @@ -49,8 +49,8 @@ public: const PlacementConfig config; - const float minScale = 0.5f; - const float maxScale = 2.0f; + float minScale = 0.5f; + float maxScale = 2.0f; float yStretch; std::array rotationMatrix; @@ -64,6 +64,8 @@ private: Tree tree; Tree ignoredTree; + + float perspectiveRatio; }; } // namespace mbgl diff --git a/src/mbgl/text/placement_config.hpp b/src/mbgl/text/placement_config.hpp index 7e61cabc24..c5c013055a 100644 --- a/src/mbgl/text/placement_config.hpp +++ b/src/mbgl/text/placement_config.hpp @@ -4,12 +4,12 @@ namespace mbgl { class PlacementConfig { public: - PlacementConfig(float angle_ = 0, float pitch_ = 0, bool debug_ = false) - : angle(angle_), pitch(pitch_), debug(debug_) { + PlacementConfig(float angle_ = 0, float pitch_ = 0, float cameraToCenterDistance_ = 0, float cameraToTileDistance_ = 0, bool debug_ = false) + : angle(angle_), pitch(pitch_), cameraToCenterDistance(cameraToCenterDistance_), cameraToTileDistance(cameraToTileDistance_), debug(debug_) { } bool operator==(const PlacementConfig& rhs) const { - return angle == rhs.angle && pitch == rhs.pitch && debug == rhs.debug; + return angle == rhs.angle && pitch == rhs.pitch && cameraToCenterDistance == rhs.cameraToCenterDistance && cameraToTileDistance == rhs.cameraToTileDistance && debug == rhs.debug; } bool operator!=(const PlacementConfig& rhs) const { @@ -19,6 +19,8 @@ public: public: float angle; float pitch; + float cameraToCenterDistance; + float cameraToTileDistance; bool debug; }; diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp index 4ab11d79fe..ad5c2edd4c 100644 --- a/src/mbgl/tile/geometry_tile.cpp +++ b/src/mbgl/tile/geometry_tile.cpp @@ -264,4 +264,8 @@ void GeometryTile::querySourceFeatures( } } +float GeometryTile::yStretch() const { + return collisionTile->yStretch; +} + } // namespace mbgl diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp index 77202d20b6..3e2efe1093 100644 --- a/src/mbgl/tile/geometry_tile.hpp +++ b/src/mbgl/tile/geometry_tile.hpp @@ -86,6 +86,8 @@ public: void onError(std::exception_ptr); + float yStretch() const override; + protected: const GeometryTileData* getData() { return data.get(); diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp index a925d88af3..1898f76849 100644 --- a/src/mbgl/tile/tile.hpp +++ b/src/mbgl/tile/tile.hpp @@ -105,6 +105,8 @@ public: // Contains the tile ID string for painting debug information. std::unique_ptr debugBucket; + + virtual float yStretch() const { return 1.0f; } protected: bool triedOptional = false; -- cgit v1.2.1 From 8f5e0b66ab13cff7d35ed46afaddbdca9ab1993f Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Wed, 17 May 2017 21:40:57 -0700 Subject: [core] Pass pitch-scaling vertex attributes and uniforms to shaders. --- src/mbgl/layout/symbol_layout.cpp | 23 ++++++++++++----------- src/mbgl/layout/symbol_layout.hpp | 3 ++- src/mbgl/programs/attributes.hpp | 2 ++ src/mbgl/programs/collision_box_program.cpp | 2 +- src/mbgl/programs/collision_box_program.hpp | 12 ++++++++++-- src/mbgl/programs/symbol_program.cpp | 6 ++++-- src/mbgl/programs/symbol_program.hpp | 21 +++++++++++++++++---- src/mbgl/programs/uniforms.hpp | 2 ++ src/mbgl/renderer/painters/painter_symbol.cpp | 3 +++ 9 files changed, 53 insertions(+), 21 deletions(-) diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index adc7eaaed8..a664957489 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -504,7 +504,7 @@ std::unique_ptr SymbolLayout::place(CollisionTile& collisionTile) for (const auto& symbol : symbolInstance.glyphQuads) { addSymbol( bucket->text, *bucket->textSizeBinder, symbol, feature, placementZoom, - keepUpright, textPlacement, collisionTile.config.angle, symbolInstance.writingModes); + keepUpright, textPlacement, collisionTile.config.angle, symbolInstance.writingModes, symbolInstance.point); } } } @@ -515,7 +515,7 @@ std::unique_ptr SymbolLayout::place(CollisionTile& collisionTile) if (iconScale < collisionTile.maxScale && symbolInstance.iconQuad) { addSymbol( bucket->icon, *bucket->iconSizeBinder, *symbolInstance.iconQuad, feature, placementZoom, - keepUpright, iconPlacement, collisionTile.config.angle, symbolInstance.writingModes); + keepUpright, iconPlacement, collisionTile.config.angle, symbolInstance.writingModes, symbolInstance.point); } } @@ -541,7 +541,8 @@ void SymbolLayout::addSymbol(Buffer& buffer, const bool keepUpright, const style::SymbolPlacementType placement, const float placementAngle, - const WritingModeType writingModes) { + const WritingModeType writingModes, + const Point labelAnchor) { constexpr const uint16_t vertexLength = 4; const auto &tl = symbol.tl; @@ -590,13 +591,13 @@ void SymbolLayout::addSymbol(Buffer& buffer, uint8_t glyphAngle = std::round((symbol.glyphAngle / (M_PI * 2)) * 256); // coordinates (2 triangles) - buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(anchorPoint, tl, tex.x, tex.y, + buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(anchorPoint, tl, labelAnchor, tex.x, tex.y, minZoom, maxZoom, placementZoom, glyphAngle)); - buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(anchorPoint, tr, tex.x + tex.w, tex.y, + buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(anchorPoint, tr, labelAnchor, tex.x + tex.w, tex.y, minZoom, maxZoom, placementZoom, glyphAngle)); - buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(anchorPoint, bl, tex.x, tex.y + tex.h, + buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(anchorPoint, bl, labelAnchor, tex.x, tex.y + tex.h, minZoom, maxZoom, placementZoom, glyphAngle)); - buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(anchorPoint, br, tex.x + tex.w, tex.y + tex.h, + buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(anchorPoint, br, labelAnchor, tex.x + tex.w, tex.y + tex.h, minZoom, maxZoom, placementZoom, glyphAngle)); sizeBinder.populateVertexVector(feature); @@ -646,10 +647,10 @@ void SymbolLayout::addToDebugBuffers(CollisionTile& collisionTile, SymbolBucket& auto& segment = collisionBox.segments.back(); uint16_t index = segment.vertexLength; - collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, tl, maxZoom, placementZoom)); - collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, tr, maxZoom, placementZoom)); - collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, br, maxZoom, placementZoom)); - collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, bl, maxZoom, placementZoom)); + collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.point, tl, maxZoom, placementZoom)); + collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.point, tr, maxZoom, placementZoom)); + collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.point, br, maxZoom, placementZoom)); + collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.point, bl, maxZoom, placementZoom)); collisionBox.lines.emplace_back(index + 0, index + 1); collisionBox.lines.emplace_back(index + 1, index + 2); diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp index 4ee52e843f..5dc0f3eb76 100644 --- a/src/mbgl/layout/symbol_layout.hpp +++ b/src/mbgl/layout/symbol_layout.hpp @@ -65,7 +65,8 @@ private: const bool keepUpright, const style::SymbolPlacementType, const float placementAngle, - WritingModeType writingModes); + WritingModeType writingModes, + const Point labelAnchor); // Stores the layer so that we can hold on to GeometryTileFeature instances in SymbolFeature, // which may reference data from this object. diff --git a/src/mbgl/programs/attributes.hpp b/src/mbgl/programs/attributes.hpp index 8f2751080f..f39af2deec 100644 --- a/src/mbgl/programs/attributes.hpp +++ b/src/mbgl/programs/attributes.hpp @@ -23,6 +23,8 @@ inline uint16_t packUint8Pair(T a, T b) { MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_pos); MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_extrude); MBGL_DEFINE_ATTRIBUTE(int16_t, 4, a_pos_offset); +MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_label_pos); +MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_anchor_pos); MBGL_DEFINE_ATTRIBUTE(uint16_t, 2, a_texture_pos); MBGL_DEFINE_ATTRIBUTE(int16_t, 3, a_normal); MBGL_DEFINE_ATTRIBUTE(uint16_t, 1, a_edgedistance); diff --git a/src/mbgl/programs/collision_box_program.cpp b/src/mbgl/programs/collision_box_program.cpp index a3dc01ebe4..57107db75d 100644 --- a/src/mbgl/programs/collision_box_program.cpp +++ b/src/mbgl/programs/collision_box_program.cpp @@ -2,6 +2,6 @@ namespace mbgl { -static_assert(sizeof(CollisionBoxProgram::LayoutVertex) == 10, "expected CollisionBoxVertex size"); +static_assert(sizeof(CollisionBoxProgram::LayoutVertex) == 14, "expected CollisionBoxVertex size"); } // namespace mbgl diff --git a/src/mbgl/programs/collision_box_program.hpp b/src/mbgl/programs/collision_box_program.hpp index 160fd42814..3b4260bb78 100644 --- a/src/mbgl/programs/collision_box_program.hpp +++ b/src/mbgl/programs/collision_box_program.hpp @@ -18,6 +18,7 @@ MBGL_DEFINE_UNIFORM_SCALAR(float, u_maxzoom); using CollisionBoxAttributes = gl::Attributes< attributes::a_pos, + attributes::a_anchor_pos, attributes::a_extrude, attributes::a_data>; @@ -29,18 +30,25 @@ class CollisionBoxProgram : public Program< uniforms::u_matrix, uniforms::u_scale, uniforms::u_zoom, - uniforms::u_maxzoom>, + uniforms::u_maxzoom, + uniforms::u_collision_y_stretch, + uniforms::u_camera_to_center_distance, + uniforms::u_pitch>, style::Properties<>> { public: using Program::Program; - static LayoutVertex vertex(Point a, Point o, float maxzoom, float placementZoom) { + static LayoutVertex vertex(Point a, Point anchor, Point o, float maxzoom, float placementZoom) { return LayoutVertex { {{ static_cast(a.x), static_cast(a.y) }}, + {{ + static_cast(anchor.x), + static_cast(anchor.y) + }}, {{ static_cast(::round(o.x)), static_cast(::round(o.y)) diff --git a/src/mbgl/programs/symbol_program.cpp b/src/mbgl/programs/symbol_program.cpp index 789eed0dd8..1b5a7d9bff 100644 --- a/src/mbgl/programs/symbol_program.cpp +++ b/src/mbgl/programs/symbol_program.cpp @@ -10,7 +10,7 @@ namespace mbgl { using namespace style; -static_assert(sizeof(SymbolLayoutVertex) == 16, "expected SymbolLayoutVertex size"); +static_assert(sizeof(SymbolLayoutVertex) == 20, "expected SymbolLayoutVertex size"); std::unique_ptr SymbolSizeBinder::create(const float tileZoom, const style::DataDrivenPropertyValue& sizeProperty, @@ -59,6 +59,9 @@ Values makeValues(const bool isText, uniforms::u_fadetexture::Value{ 1 }, uniforms::u_is_text::Value{ isText }, uniforms::u_collision_y_stretch::Value{ tile.tile.yStretch() }, + uniforms::u_camera_to_center_distance::Value{ state.getCameraToCenterDistance() }, + uniforms::u_pitch::Value{ state.getPitch() }, + uniforms::u_max_camera_distance::Value{ 10.0f }, std::forward(args)... }; } @@ -103,7 +106,6 @@ typename SymbolSDFProgram::UniformValues SymbolSDFProgram> { static Vertex vertex(Point a, Point o, + Point labelAnchor, uint16_t tx, uint16_t ty, float minzoom, @@ -65,6 +67,10 @@ struct SymbolLayoutAttributes : gl::Attributes< static_cast(::round(o.x * 64)), // use 1/64 pixels for placement static_cast(::round(o.y * 64)) }}, + {{ + static_cast(labelAnchor.x), + static_cast(labelAnchor.y) + }}, {{ tx, ty, @@ -391,7 +397,10 @@ class SymbolIconProgram : public SymbolProgram< uniforms::u_texture, uniforms::u_fadetexture, uniforms::u_is_text, - uniforms::u_collision_y_stretch>, + uniforms::u_collision_y_stretch, + uniforms::u_camera_to_center_distance, + uniforms::u_pitch, + uniforms::u_max_camera_distance>, style::IconPaintProperties> { public: @@ -425,8 +434,10 @@ class SymbolSDFProgram : public SymbolProgram< uniforms::u_fadetexture, uniforms::u_is_text, uniforms::u_collision_y_stretch, - uniforms::u_gamma_scale, + uniforms::u_camera_to_center_distance, uniforms::u_pitch, + uniforms::u_max_camera_distance, + uniforms::u_gamma_scale, uniforms::u_bearing, uniforms::u_aspect_ratio, uniforms::u_pitch_with_map, @@ -447,8 +458,10 @@ public: uniforms::u_fadetexture, uniforms::u_is_text, uniforms::u_collision_y_stretch, - uniforms::u_gamma_scale, + uniforms::u_camera_to_center_distance, uniforms::u_pitch, + uniforms::u_max_camera_distance, + uniforms::u_gamma_scale, uniforms::u_bearing, uniforms::u_aspect_ratio, uniforms::u_pitch_with_map, diff --git a/src/mbgl/programs/uniforms.hpp b/src/mbgl/programs/uniforms.hpp index c8f8684ba1..8d606dcf08 100644 --- a/src/mbgl/programs/uniforms.hpp +++ b/src/mbgl/programs/uniforms.hpp @@ -14,6 +14,8 @@ MBGL_DEFINE_UNIFORM_SCALAR(Color, u_color); MBGL_DEFINE_UNIFORM_SCALAR(float, u_blur); MBGL_DEFINE_UNIFORM_SCALAR(float, u_zoom); +MBGL_DEFINE_UNIFORM_SCALAR(float, u_collision_y_stretch); +MBGL_DEFINE_UNIFORM_SCALAR(float, u_camera_to_center_distance); MBGL_DEFINE_UNIFORM_SCALAR(float, u_pitch); MBGL_DEFINE_UNIFORM_SCALAR(float, u_bearing); MBGL_DEFINE_UNIFORM_SCALAR(float, u_radius); diff --git a/src/mbgl/renderer/painters/painter_symbol.cpp b/src/mbgl/renderer/painters/painter_symbol.cpp index d3a505aa3f..2d91ff41ad 100644 --- a/src/mbgl/renderer/painters/painter_symbol.cpp +++ b/src/mbgl/renderer/painters/painter_symbol.cpp @@ -152,6 +152,9 @@ void Painter::renderSymbol(PaintParameters& parameters, uniforms::u_scale::Value{ std::pow(2.0f, float(state.getZoom() - tile.tile.id.overscaledZ)) }, uniforms::u_zoom::Value{ float(state.getZoom() * 10) }, uniforms::u_maxzoom::Value{ float((tile.id.canonical.z + 1) * 10) }, + uniforms::u_collision_y_stretch::Value{ tile.tile.yStretch() }, + uniforms::u_camera_to_center_distance::Value{ state.getCameraToCenterDistance() }, + uniforms::u_pitch::Value{ state.getPitch() } }, *bucket.collisionBox.vertexBuffer, *bucket.collisionBox.indexBuffer, -- cgit v1.2.1 From 7b29b90e7fb379ca4f592e98fd3144d424937632 Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Thu, 18 May 2017 12:54:11 -0700 Subject: [core] Extend collision feature boxes to accommodate potential pitch-scaling. --- src/mbgl/text/collision_feature.cpp | 57 +++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/src/mbgl/text/collision_feature.cpp b/src/mbgl/text/collision_feature.cpp index 71d7cc74e0..58a7949a8e 100644 --- a/src/mbgl/text/collision_feature.cpp +++ b/src/mbgl/text/collision_feature.cpp @@ -49,7 +49,11 @@ CollisionFeature::CollisionFeature(const GeometryCoordinates& line, void CollisionFeature::bboxifyLabel(const GeometryCoordinates& line, GeometryCoordinate& anchorPoint, const int segment, const float labelLength, const float boxSize) { const float step = boxSize / 2; - const unsigned int nBoxes = std::floor(labelLength / step); + const int nBoxes = std::floor(labelLength / step); + // We calculate line collision boxes out to 150% of what would normally be our + // max size, to allow collision detection to work on labels that expand as + // they move into the distance + const int nPitchPaddingBoxes = std::floor(nBoxes / 4); // offset the center of the first box by half a box so that the edge of the // box is at the edge of the label. @@ -58,24 +62,40 @@ void CollisionFeature::bboxifyLabel(const GeometryCoordinates& line, GeometryCoo GeometryCoordinate &p = anchorPoint; int index = segment + 1; float anchorDistance = firstBoxOffset; + const float labelStartDistance = -labelLength / 2; + const float paddingStartDistance = labelStartDistance - labelLength / 8; // move backwards along the line to the first segment the label appears on do { index--; - // there isn't enough room for the label after the beginning of the line - // checkMaxAngle should have already caught this - if (index < 0) return; + if (index < 0) { + if (anchorDistance > labelStartDistance) { + // there isn't enough room for the label after the beginning of the line + // checkMaxAngle should have already caught this + return; + } else { + // The line doesn't extend far enough back for all of our padding, + // but we got far enough to show the label under most conditions. + index = 0; + break; + } + } anchorDistance -= util::dist(line[index], p); p = line[index]; - } while (anchorDistance > -labelLength / 2); + } while (anchorDistance > paddingStartDistance); auto segmentLength = util::dist(line[index], line[index + 1]); - for (unsigned int i = 0; i < nBoxes; i++) { + for (int i = -nPitchPaddingBoxes; i < nBoxes + nPitchPaddingBoxes; i++) { // the distance the box will be from the anchor - const float boxDistanceToAnchor = -labelLength / 2 + i * step; + const float boxDistanceToAnchor = labelStartDistance + i * step; + if (boxDistanceToAnchor < anchorDistance) { + // The line doesn't extend far enough back for this box, skip it + // (This could allow for line collisions on distant tiles) + continue; + } // the box is not on the current segment. Move to the next segment. while (anchorDistance + segmentLength < boxDistanceToAnchor) { @@ -99,8 +119,29 @@ void CollisionFeature::bboxifyLabel(const GeometryCoordinates& line, GeometryCoo p0.y + segmentBoxDistance / segmentLength * (p1.y - p0.y) }; + // Distance from label anchor point to inner (towards center) edge of this box + // The tricky thing here is that box positioning doesn't change with scale, + // but box size does change with scale. + // Technically, distanceToInnerEdge should be: + // Math.max(Math.abs(boxDistanceToAnchor - firstBoxOffset) - (step / scale), 0); + // But using that formula would make solving for maxScale more difficult, so we + // approximate with scale=2. + // This makes our calculation spot-on at scale=2, and on the conservative side for + // lower scales const float distanceToInnerEdge = std::max(std::fabs(boxDistanceToAnchor - firstBoxOffset) - step / 2, 0.0f); - const float maxScale = labelLength / 2 / distanceToInnerEdge; + float maxScale = labelLength / 2 / distanceToInnerEdge; + + // The box maxScale calculations are designed to be conservative on collisions in the scale range + // [1,2]. At scale=1, each box has 50% overlap, and at scale=2, the boxes are lined up edge + // to edge (beyond scale 2, gaps start to appear, which could potentially allow missed collisions). + // We add "pitch padding" boxes to the left and right to handle effective underzooming + // (scale < 1) when labels are in the distance. The overlap approximation could cause us to use + // these boxes when the scale is greater than 1, but we prevent that because we know + // they're only necessary for scales less than one. + // This preserves the pre-pitch-padding behavior for unpitched maps. + if (i < 0 || i >= nBoxes) { + maxScale = std::min(maxScale, 0.99f); + } boxes.emplace_back(boxAnchor, -boxSize / 2, -boxSize / 2, boxSize / 2, boxSize / 2, maxScale); } -- cgit v1.2.1 From 2ee59796fb47c3152b2bdcfa5cde4be5a92316b4 Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Thu, 18 May 2017 14:08:10 -0700 Subject: [core] Enable tile clipping for collision boxes. Necessary because collision boxes now change shape based on while tile they're part of. --- src/mbgl/renderer/painters/painter_symbol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mbgl/renderer/painters/painter_symbol.cpp b/src/mbgl/renderer/painters/painter_symbol.cpp index 2d91ff41ad..c358d78b80 100644 --- a/src/mbgl/renderer/painters/painter_symbol.cpp +++ b/src/mbgl/renderer/painters/painter_symbol.cpp @@ -145,7 +145,7 @@ void Painter::renderSymbol(PaintParameters& parameters, context, gl::Lines { 1.0f }, gl::DepthMode::disabled(), - gl::StencilMode::disabled(), + stencilModeForClipping(tile.clip), colorModeForRenderPass(), CollisionBoxProgram::UniformValues { uniforms::u_matrix::Value{ tile.matrix }, -- cgit v1.2.1 From f8402e20425cee6cbad2a28809bce17ac46c1379 Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Fri, 19 May 2017 13:30:17 -0700 Subject: [core] Set "max_camera_distance" to 1.5 for viewport-aligned road labels. Viewport-aligned curved labels start to look very strange in the distance. Until we have a better system for projecting them, just prevent them from showing. --- src/mbgl/programs/symbol_program.cpp | 2 +- src/mbgl/renderer/layers/render_symbol_layer.cpp | 18 ++++++++++++++++-- src/mbgl/renderer/layers/render_symbol_layer.hpp | 2 ++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/mbgl/programs/symbol_program.cpp b/src/mbgl/programs/symbol_program.cpp index 1b5a7d9bff..bd43237b8f 100644 --- a/src/mbgl/programs/symbol_program.cpp +++ b/src/mbgl/programs/symbol_program.cpp @@ -61,7 +61,7 @@ Values makeValues(const bool isText, uniforms::u_collision_y_stretch::Value{ tile.tile.yStretch() }, uniforms::u_camera_to_center_distance::Value{ state.getCameraToCenterDistance() }, uniforms::u_pitch::Value{ state.getPitch() }, - uniforms::u_max_camera_distance::Value{ 10.0f }, + uniforms::u_max_camera_distance::Value{ values.maxCameraDistance }, std::forward(args)... }; } diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index 6540fc9612..573e9db72e 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -88,11 +88,24 @@ style::SymbolPropertyValues RenderSymbolLayer::iconPropertyValues(const style::S evaluated.get(), evaluated.get().constantOr(Color::black()).a > 0 && evaluated.get().constantOr(1), - evaluated.get().constantOr(Color::black()).a > 0 + evaluated.get().constantOr(Color::black()).a > 0, + 10.0f }; } style::SymbolPropertyValues RenderSymbolLayer::textPropertyValues(const style::SymbolLayoutProperties::PossiblyEvaluated& layout_) const { + // We hide line labels with viewport alignment as they move into the distance + // because the approximations we use for drawing their glyphs get progressively worse + // The "1.5" here means we start hiding them when the distance from the label + // to the camera is 50% greater than the distance from the center of the map + // to the camera. Depending on viewport properties, you might expect this to filter + // the top third of the screen at pitch 60, and do almost nothing at pitch 45 + // "10" is effectively infinite at any pitch we support + const bool limitMaxDistance = + layout_.get() == style::SymbolPlacementType::Line + && layout_.get() == style::AlignmentType::Map + && layout_.get() == style::AlignmentType::Viewport; + return style::SymbolPropertyValues { layout_.get(), layout_.get(), @@ -100,7 +113,8 @@ style::SymbolPropertyValues RenderSymbolLayer::textPropertyValues(const style::S evaluated.get(), evaluated.get().constantOr(Color::black()).a > 0 && evaluated.get().constantOr(1), - evaluated.get().constantOr(Color::black()).a > 0 + evaluated.get().constantOr(Color::black()).a > 0, + limitMaxDistance ? 1.5f : 10.0f }; } diff --git a/src/mbgl/renderer/layers/render_symbol_layer.hpp b/src/mbgl/renderer/layers/render_symbol_layer.hpp index 2199103de2..e788336cbd 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.hpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.hpp @@ -47,6 +47,8 @@ public: bool hasHalo; bool hasFill; + + float maxCameraDistance; // 1.5 for road labels, or 10 (essentially infinite) for everything else }; } // namespace style -- cgit v1.2.1 From 8c23f14a9f47bc3e2d687ed25561b586643348f5 Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Thu, 25 May 2017 09:15:27 -0700 Subject: [core] Use fade texture in collision debug boxes so that they agree more closely with symbol shaders. --- src/mbgl/programs/collision_box_program.hpp | 3 ++- src/mbgl/programs/symbol_program.hpp | 1 - src/mbgl/programs/uniforms.hpp | 1 + src/mbgl/renderer/painters/painter_symbol.cpp | 3 ++- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/mbgl/programs/collision_box_program.hpp b/src/mbgl/programs/collision_box_program.hpp index 3b4260bb78..ba99e0c087 100644 --- a/src/mbgl/programs/collision_box_program.hpp +++ b/src/mbgl/programs/collision_box_program.hpp @@ -33,7 +33,8 @@ class CollisionBoxProgram : public Program< uniforms::u_maxzoom, uniforms::u_collision_y_stretch, uniforms::u_camera_to_center_distance, - uniforms::u_pitch>, + uniforms::u_pitch, + uniforms::u_fadetexture>, style::Properties<>> { public: diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index c38ed04a1e..130e556b46 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -31,7 +31,6 @@ class TransformState; namespace uniforms { MBGL_DEFINE_UNIFORM_SCALAR(bool, u_rotate_with_map); MBGL_DEFINE_UNIFORM_SCALAR(gl::TextureUnit, u_texture); -MBGL_DEFINE_UNIFORM_SCALAR(gl::TextureUnit, u_fadetexture); MBGL_DEFINE_UNIFORM_SCALAR(float, u_aspect_ratio); MBGL_DEFINE_UNIFORM_SCALAR(bool, u_is_halo); MBGL_DEFINE_UNIFORM_SCALAR(float, u_gamma_scale); diff --git a/src/mbgl/programs/uniforms.hpp b/src/mbgl/programs/uniforms.hpp index 8d606dcf08..861f3271c9 100644 --- a/src/mbgl/programs/uniforms.hpp +++ b/src/mbgl/programs/uniforms.hpp @@ -51,6 +51,7 @@ MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_pixel_coord_lower); MBGL_DEFINE_UNIFORM_SCALAR(float, u_mix); MBGL_DEFINE_UNIFORM_SCALAR(gl::TextureUnit, u_image); +MBGL_DEFINE_UNIFORM_SCALAR(gl::TextureUnit, u_fadetexture); MBGL_DEFINE_UNIFORM_SCALAR(float, u_scale_a); MBGL_DEFINE_UNIFORM_SCALAR(float, u_scale_b); MBGL_DEFINE_UNIFORM_SCALAR(float, u_tile_units_to_pixels); diff --git a/src/mbgl/renderer/painters/painter_symbol.cpp b/src/mbgl/renderer/painters/painter_symbol.cpp index c358d78b80..dc80f096f4 100644 --- a/src/mbgl/renderer/painters/painter_symbol.cpp +++ b/src/mbgl/renderer/painters/painter_symbol.cpp @@ -154,7 +154,8 @@ void Painter::renderSymbol(PaintParameters& parameters, uniforms::u_maxzoom::Value{ float((tile.id.canonical.z + 1) * 10) }, uniforms::u_collision_y_stretch::Value{ tile.tile.yStretch() }, uniforms::u_camera_to_center_distance::Value{ state.getCameraToCenterDistance() }, - uniforms::u_pitch::Value{ state.getPitch() } + uniforms::u_pitch::Value{ state.getPitch() }, + uniforms::u_fadetexture::Value{ 1 } }, *bucket.collisionBox.vertexBuffer, *bucket.collisionBox.indexBuffer, -- cgit v1.2.1 From 7c7564d72ed060bfd9ff1d5ebc6086a52f837c4b Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Tue, 16 May 2017 11:50:24 -0700 Subject: [core] Re-generate shaders. --- src/mbgl/shaders/collision_box.cpp | 36 ++++++- src/mbgl/shaders/symbol_icon.cpp | 44 ++++++--- src/mbgl/shaders/symbol_sdf.cpp | 193 +++++++++++++++++++++++-------------- 3 files changed, 184 insertions(+), 89 deletions(-) diff --git a/src/mbgl/shaders/collision_box.cpp b/src/mbgl/shaders/collision_box.cpp index 5f733c6a1e..05f306ef65 100644 --- a/src/mbgl/shaders/collision_box.cpp +++ b/src/mbgl/shaders/collision_box.cpp @@ -8,44 +8,74 @@ namespace shaders { const char* collision_box::name = "collision_box"; const char* collision_box::vertexSource = R"MBGL_SHADER( attribute vec2 a_pos; +attribute vec2 a_anchor_pos; attribute vec2 a_extrude; attribute vec2 a_data; uniform mat4 u_matrix; uniform float u_scale; +uniform float u_pitch; +uniform float u_collision_y_stretch; +uniform float u_camera_to_center_distance; varying float v_max_zoom; varying float v_placement_zoom; +varying float v_perspective_zoom_adjust; +varying vec2 v_fade_tex; void main() { - gl_Position = u_matrix * vec4(a_pos + a_extrude / u_scale, 0.0, 1.0); + vec4 projectedPoint = u_matrix * vec4(a_anchor_pos, 0, 1); + highp float camera_to_anchor_distance = projectedPoint.w; + highp float collision_perspective_ratio = 1.0 + 0.5 * ((camera_to_anchor_distance / u_camera_to_center_distance) - 1.0); + + highp float incidence_stretch = camera_to_anchor_distance / (u_camera_to_center_distance * cos(u_pitch)); + highp float collision_adjustment = max(1.0, incidence_stretch / u_collision_y_stretch); + + gl_Position = u_matrix * vec4(a_pos + a_extrude * collision_perspective_ratio * collision_adjustment / u_scale, 0.0, 1.0); v_max_zoom = a_data.x; v_placement_zoom = a_data.y; + + v_perspective_zoom_adjust = log2(collision_perspective_ratio * collision_adjustment) * 10.0; + v_fade_tex = vec2((v_placement_zoom + v_perspective_zoom_adjust) / 255.0, 0.0); } )MBGL_SHADER"; const char* collision_box::fragmentSource = R"MBGL_SHADER( uniform float u_zoom; +// u_maxzoom is derived from the maximum scale considered by the CollisionTile +// Labels with placement zoom greater than this value will not be placed, +// regardless of perspective effects. uniform float u_maxzoom; +uniform sampler2D u_fadetexture; +// v_max_zoom is a collision-box-specific value that controls when line-following +// collision boxes are used. varying float v_max_zoom; varying float v_placement_zoom; +varying float v_perspective_zoom_adjust; +varying vec2 v_fade_tex; void main() { float alpha = 0.5; + // Green = no collisions, label is showing gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0) * alpha; - if (v_placement_zoom > u_zoom) { + // Red = collision, label hidden + if (texture2D(u_fadetexture, v_fade_tex).a < 1.0) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0) * alpha; } - if (u_zoom >= v_max_zoom) { + // Faded black = this collision box is not used at this zoom (for curved labels) + if (u_zoom >= v_max_zoom + v_perspective_zoom_adjust) { gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0) * alpha * 0.25; } + // Faded blue = the placement scale for this label is beyond the CollisionTile + // max scale, so it's impossible for this label to show without collision detection + // being run again (the label's glyphs haven't even been added to the symbol bucket) if (v_placement_zoom >= u_maxzoom) { gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0) * alpha * 0.2; } diff --git a/src/mbgl/shaders/symbol_icon.cpp b/src/mbgl/shaders/symbol_icon.cpp index bc570cf361..8960e02c28 100644 --- a/src/mbgl/shaders/symbol_icon.cpp +++ b/src/mbgl/shaders/symbol_icon.cpp @@ -7,17 +7,20 @@ namespace shaders { const char* symbol_icon::name = "symbol_icon"; const char* symbol_icon::vertexSource = R"MBGL_SHADER( - attribute vec4 a_pos_offset; +attribute vec2 a_label_pos; attribute vec4 a_data; // icon-size data (see symbol_sdf.vertex.glsl for more) attribute vec3 a_size; uniform bool u_is_size_zoom_constant; uniform bool u_is_size_feature_constant; -uniform mediump float u_size_t; // used to interpolate between zoom stops when size is a composite function -uniform mediump float u_size; // used when size is both zoom and feature constant -uniform mediump float u_layout_size; // used when size is feature constant +uniform highp float u_size_t; // used to interpolate between zoom stops when size is a composite function +uniform highp float u_size; // used when size is both zoom and feature constant +uniform highp float u_layout_size; // used when size is feature constant +uniform highp float u_camera_to_center_distance; +uniform highp float u_pitch; +uniform highp float u_collision_y_stretch; #ifndef HAS_UNIFORM_u_opacity @@ -32,7 +35,7 @@ uniform lowp float u_opacity; uniform mat4 u_matrix; uniform bool u_is_text; -uniform mediump float u_zoom; +uniform highp float u_zoom; uniform bool u_rotate_with_map; uniform vec2 u_extrude_scale; @@ -53,11 +56,11 @@ void main() { vec2 a_offset = a_pos_offset.zw; vec2 a_tex = a_data.xy; - mediump vec2 label_data = unpack_float(a_data[2]); - mediump float a_labelminzoom = label_data[0]; - mediump vec2 a_zoom = unpack_float(a_data[3]); - mediump float a_minzoom = a_zoom[0]; - mediump float a_maxzoom = a_zoom[1]; + highp vec2 label_data = unpack_float(a_data[2]); + highp float a_labelminzoom = label_data[0]; + highp vec2 a_zoom = unpack_float(a_data[3]); + highp float a_minzoom = a_zoom[0]; + highp float a_maxzoom = a_zoom[1]; float size; // In order to accommodate placing labels around corners in @@ -68,7 +71,7 @@ void main() { // currently rendered zoom level if text-size is zoom-dependent. // Thus, we compensate for this difference by calculating an adjustment // based on the scale of rendered text size relative to layout text size. - mediump float layoutSize; + highp float layoutSize; if (!u_is_size_zoom_constant && !u_is_size_feature_constant) { size = mix(a_size[0], a_size[1], u_size_t) / 10.0; layoutSize = a_size[2] / 10.0; @@ -85,12 +88,16 @@ void main() { float fontScale = u_is_text ? size / 24.0 : size; - mediump float zoomAdjust = log2(size / layoutSize); - mediump float adjustedZoom = (u_zoom - zoomAdjust) * 10.0; + highp float zoomAdjust = log2(size / layoutSize); + highp float adjustedZoom = (u_zoom - zoomAdjust) * 10.0; // result: z = 0 if a_minzoom <= adjustedZoom < a_maxzoom, and 1 otherwise - mediump float z = 2.0 - step(a_minzoom, adjustedZoom) - (1.0 - step(a_maxzoom, adjustedZoom)); + highp float z = 2.0 - step(a_minzoom, adjustedZoom) - (1.0 - step(a_maxzoom, adjustedZoom)); + + vec4 projectedPoint = u_matrix * vec4(a_label_pos, 0, 1); + highp float camera_to_anchor_distance = projectedPoint.w; + highp float perspective_ratio = 1.0 + 0.5*((camera_to_anchor_distance / u_camera_to_center_distance) - 1.0); - vec2 extrude = fontScale * u_extrude_scale * (a_offset / 64.0); + vec2 extrude = fontScale * u_extrude_scale * perspective_ratio * (a_offset / 64.0); if (u_rotate_with_map) { gl_Position = u_matrix * vec4(a_pos + extrude, 0, 1); gl_Position.z += z * gl_Position.w; @@ -99,7 +106,12 @@ void main() { } v_tex = a_tex / u_texsize; - v_fade_tex = vec2(a_labelminzoom / 255.0, 0.0); + // See comments in symbol_sdf.vertex + highp float incidence_stretch = camera_to_anchor_distance / (u_camera_to_center_distance * cos(u_pitch)); + highp float collision_adjustment = max(1.0, incidence_stretch / u_collision_y_stretch); + + highp float perspective_zoom_adjust = log2(perspective_ratio * collision_adjustment) * 10.0; + v_fade_tex = vec2((a_labelminzoom + perspective_zoom_adjust) / 255.0, 0.0); } )MBGL_SHADER"; diff --git a/src/mbgl/shaders/symbol_sdf.cpp b/src/mbgl/shaders/symbol_sdf.cpp index cce6b769a6..bae01a5b59 100644 --- a/src/mbgl/shaders/symbol_sdf.cpp +++ b/src/mbgl/shaders/symbol_sdf.cpp @@ -9,7 +9,10 @@ const char* symbol_sdf::name = "symbol_sdf"; const char* symbol_sdf::vertexSource = R"MBGL_SHADER( const float PI = 3.141592653589793; +// NOTE: the a_data attribute in this shader is manually bound (see https://github.com/mapbox/mapbox-gl-js/issues/4607). +// If removing or renaming a_data, revisit the manual binding in painter.js accordingly. attribute vec4 a_pos_offset; +attribute vec2 a_label_pos; attribute vec4 a_data; // contents of a_size vary based on the type of property value @@ -23,12 +26,12 @@ attribute vec4 a_data; attribute vec3 a_size; uniform bool u_is_size_zoom_constant; uniform bool u_is_size_feature_constant; -uniform mediump float u_size_t; // used to interpolate between zoom stops when size is a composite function -uniform mediump float u_size; // used when size is both zoom and feature constant -uniform mediump float u_layout_size; // used when size is feature constant +uniform highp float u_size_t; // used to interpolate between zoom stops when size is a composite function +uniform highp float u_size; // used when size is both zoom and feature constant +uniform highp float u_layout_size; // used when size is feature constant -#ifndef HAS_UNIFORM_u_fill_color +#ifdef HAS_UNIFORM_u_fill_color uniform lowp float a_fill_color_t; attribute highp vec4 a_fill_color; varying highp vec4 fill_color; @@ -36,7 +39,8 @@ varying highp vec4 fill_color; uniform highp vec4 u_fill_color; #endif -#ifndef HAS_UNIFORM_u_halo_color + +#ifdef HAS_UNIFORM_u_halo_color uniform lowp float a_halo_color_t; attribute highp vec4 a_halo_color; varying highp vec4 halo_color; @@ -44,7 +48,8 @@ varying highp vec4 halo_color; uniform highp vec4 u_halo_color; #endif -#ifndef HAS_UNIFORM_u_opacity + +#ifdef HAS_UNIFORM_u_opacity uniform lowp float a_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; @@ -52,7 +57,8 @@ varying lowp float opacity; uniform lowp float u_opacity; #endif -#ifndef HAS_UNIFORM_u_halo_width + +#ifdef HAS_UNIFORM_u_halo_width uniform lowp float a_halo_width_t; attribute lowp vec2 a_halo_width; varying lowp float halo_width; @@ -60,7 +66,8 @@ varying lowp float halo_width; uniform lowp float u_halo_width; #endif -#ifndef HAS_UNIFORM_u_halo_blur + +#ifdef HAS_UNIFORM_u_halo_blur uniform lowp float a_halo_blur_t; attribute lowp vec2 a_halo_blur; varying lowp float halo_blur; @@ -68,68 +75,89 @@ varying lowp float halo_blur; uniform lowp float u_halo_blur; #endif + // matrix is for the vertex position. uniform mat4 u_matrix; uniform bool u_is_text; -uniform mediump float u_zoom; +uniform highp float u_zoom; uniform bool u_rotate_with_map; uniform bool u_pitch_with_map; -uniform mediump float u_pitch; -uniform mediump float u_bearing; -uniform mediump float u_aspect_ratio; +uniform highp float u_pitch; +uniform highp float u_bearing; +uniform highp float u_aspect_ratio; +uniform highp float u_camera_to_center_distance; +uniform highp float u_max_camera_distance; +uniform highp float u_collision_y_stretch; uniform vec2 u_extrude_scale; uniform vec2 u_texsize; -varying vec4 v_data0; -varying vec2 v_data1; +varying vec2 v_tex; +varying vec2 v_fade_tex; +varying float v_gamma_scale; +varying float v_size; + +// Used below to move the vertex out of the clip space for when the current +// zoom is out of the glyph's zoom range. +highp float clipUnusedGlyphAngles(const highp float render_size, + const highp float layout_size, + const highp float min_zoom, + const highp float max_zoom) { + highp float zoom_adjust = log2(render_size / layout_size); + highp float adjusted_zoom = (u_zoom - zoom_adjust) * 10.0; + // result: 0 if min_zoom <= adjusted_zoom < max_zoom, and 1 otherwise + return 2.0 - step(min_zoom, adjusted_zoom) - (1.0 - step(max_zoom, adjusted_zoom)); +} void main() { - + #ifndef HAS_UNIFORM_u_fill_color fill_color = unpack_mix_vec4(a_fill_color, a_fill_color_t); #else highp vec4 fill_color = u_fill_color; #endif + #ifndef HAS_UNIFORM_u_halo_color halo_color = unpack_mix_vec4(a_halo_color, a_halo_color_t); #else highp vec4 halo_color = u_halo_color; #endif + #ifndef HAS_UNIFORM_u_opacity opacity = unpack_mix_vec2(a_opacity, a_opacity_t); #else lowp float opacity = u_opacity; #endif + #ifndef HAS_UNIFORM_u_halo_width halo_width = unpack_mix_vec2(a_halo_width, a_halo_width_t); #else lowp float halo_width = u_halo_width; #endif + #ifndef HAS_UNIFORM_u_halo_blur halo_blur = unpack_mix_vec2(a_halo_blur, a_halo_blur_t); #else lowp float halo_blur = u_halo_blur; #endif + vec2 a_pos = a_pos_offset.xy; vec2 a_offset = a_pos_offset.zw; vec2 a_tex = a_data.xy; - mediump vec2 label_data = unpack_float(a_data[2]); - mediump float a_labelminzoom = label_data[0]; - mediump float a_labelangle = label_data[1]; - - mediump vec2 a_zoom = unpack_float(a_data[3]); - mediump float a_minzoom = a_zoom[0]; - mediump float a_maxzoom = a_zoom[1]; - float size; + highp vec2 label_data = unpack_float(a_data[2]); + highp float a_labelminzoom = label_data[0]; + highp float a_lineangle = (label_data[1] / 256.0 * 2.0 * PI); + highp vec2 a_zoom = unpack_float(a_data[3]); + highp float a_minzoom = a_zoom[0]; + highp float a_maxzoom = a_zoom[1]; // In order to accommodate placing labels around corners in // symbol-placement: line, each glyph in a label could have multiple @@ -139,79 +167,97 @@ void main() { // currently rendered zoom level if text-size is zoom-dependent. // Thus, we compensate for this difference by calculating an adjustment // based on the scale of rendered text size relative to layout text size. - mediump float layoutSize; + highp float layoutSize; if (!u_is_size_zoom_constant && !u_is_size_feature_constant) { - size = mix(a_size[0], a_size[1], u_size_t) / 10.0; + v_size = mix(a_size[0], a_size[1], u_size_t) / 10.0; layoutSize = a_size[2] / 10.0; } else if (u_is_size_zoom_constant && !u_is_size_feature_constant) { - size = a_size[0] / 10.0; - layoutSize = size; + v_size = a_size[0] / 10.0; + layoutSize = v_size; } else if (!u_is_size_zoom_constant && u_is_size_feature_constant) { - size = u_size; + v_size = u_size; layoutSize = u_layout_size; } else { - size = u_size; + v_size = u_size; layoutSize = u_size; } - float fontScale = u_is_text ? size / 24.0 : size; + float fontScale = u_is_text ? v_size / 24.0 : v_size; - mediump float zoomAdjust = log2(size / layoutSize); - mediump float adjustedZoom = (u_zoom - zoomAdjust) * 10.0; - // result: z = 0 if a_minzoom <= adjustedZoom < a_maxzoom, and 1 otherwise - // Used below to move the vertex out of the clip space for when the current - // zoom is out of the glyph's zoom range. - mediump float z = 2.0 - step(a_minzoom, adjustedZoom) - (1.0 - step(a_maxzoom, adjustedZoom)); + vec4 projectedPoint = u_matrix * vec4(a_label_pos, 0, 1); + highp float camera_to_anchor_distance = projectedPoint.w; + highp float perspective_ratio = 1.0 + 0.5*((camera_to_anchor_distance / u_camera_to_center_distance) - 1.0); // pitch-alignment: map // rotation-alignment: map | viewport if (u_pitch_with_map) { - lowp float angle = u_rotate_with_map ? (a_labelangle / 256.0 * 2.0 * PI) : u_bearing; - lowp float asin = sin(angle); - lowp float acos = cos(angle); + highp float angle = u_rotate_with_map ? a_lineangle : u_bearing; + highp float asin = sin(angle); + highp float acos = cos(angle); mat2 RotationMatrix = mat2(acos, asin, -1.0 * asin, acos); vec2 offset = RotationMatrix * a_offset; - vec2 extrude = fontScale * u_extrude_scale * (offset / 64.0); + vec2 extrude = fontScale * u_extrude_scale * perspective_ratio * (offset / 64.0); + gl_Position = u_matrix * vec4(a_pos + extrude, 0, 1); - gl_Position.z += z * gl_Position.w; + gl_Position.z += clipUnusedGlyphAngles(v_size*perspective_ratio, layoutSize, a_minzoom, a_maxzoom) * gl_Position.w; // pitch-alignment: viewport // rotation-alignment: map } else if (u_rotate_with_map) { // foreshortening factor to apply on pitched maps // as a label goes from horizontal <=> vertical in angle // it goes from 0% foreshortening to up to around 70% foreshortening - lowp float pitchfactor = 1.0 - cos(u_pitch * sin(u_pitch * 0.75)); - - lowp float lineangle = a_labelangle / 256.0 * 2.0 * PI; + highp float pitchfactor = 1.0 - cos(u_pitch * sin(u_pitch * 0.75)); // use the lineangle to position points a,b along the line // project the points and calculate the label angle in projected space // this calculation allows labels to be rendered unskewed on pitched maps vec4 a = u_matrix * vec4(a_pos, 0, 1); - vec4 b = u_matrix * vec4(a_pos + vec2(cos(lineangle),sin(lineangle)), 0, 1); - lowp float angle = atan((b[1]/b[3] - a[1]/a[3])/u_aspect_ratio, b[0]/b[3] - a[0]/a[3]); - lowp float asin = sin(angle); - lowp float acos = cos(angle); + vec4 b = u_matrix * vec4(a_pos + vec2(cos(a_lineangle), sin(a_lineangle)), 0, 1); + highp float angle = atan((b[1] / b[3] - a[1] / a[3]) / u_aspect_ratio, b[0] / b[3] - a[0] / a[3]); + highp float asin = sin(angle); + highp float acos = cos(angle); mat2 RotationMatrix = mat2(acos, -1.0 * asin, asin, acos); + highp float foreshortening = (1.0 - pitchfactor) + (pitchfactor * cos(angle * 2.0)); + + vec2 offset = RotationMatrix * (vec2(foreshortening, 1.0) * a_offset); + vec2 extrude = fontScale * u_extrude_scale * perspective_ratio * (offset / 64.0); - vec2 offset = RotationMatrix * (vec2((1.0-pitchfactor)+(pitchfactor*cos(angle*2.0)), 1.0) * a_offset); - vec2 extrude = fontScale * u_extrude_scale * (offset / 64.0); gl_Position = u_matrix * vec4(a_pos, 0, 1) + vec4(extrude, 0, 0); - gl_Position.z += z * gl_Position.w; + gl_Position.z += clipUnusedGlyphAngles(v_size * perspective_ratio, layoutSize, a_minzoom, a_maxzoom) * gl_Position.w; // pitch-alignment: viewport // rotation-alignment: viewport } else { - vec2 extrude = fontScale * u_extrude_scale * (a_offset / 64.0); + vec2 extrude = fontScale * u_extrude_scale * perspective_ratio * (a_offset / 64.0); gl_Position = u_matrix * vec4(a_pos, 0, 1) + vec4(extrude, 0, 0); } - float gamma_scale = gl_Position.w; - - vec2 tex = a_tex / u_texsize; - vec2 fade_tex = vec2(a_labelminzoom / 255.0, 0.0); - - v_data0 = vec4(tex.x, tex.y, fade_tex.x, fade_tex.y); - v_data1 = vec2(gamma_scale, size); + gl_Position.z += + step(u_max_camera_distance * u_camera_to_center_distance, camera_to_anchor_distance) * gl_Position.w; + + v_gamma_scale = gl_Position.w / perspective_ratio; + + v_tex = a_tex / u_texsize; + // incidence_stretch is the ratio of how much y space a label takes up on a tile while drawn perpendicular to the viewport vs + // how much space it would take up if it were drawn flat on the tile + // Using law of sines, camera_to_anchor/sin(ground_angle) = camera_to_center/sin(incidence_angle) + // sin(incidence_angle) = 1/incidence_stretch + // Incidence angle 90 -> head on, sin(incidence_angle) = 1, no incidence stretch + // Incidence angle 1 -> very oblique, sin(incidence_angle) =~ 0, lots of incidence stretch + // ground_angle = u_pitch + PI/2 -> sin(ground_angle) = cos(u_pitch) + // This 2D calculation is only exactly correct when gl_Position.x is in the center of the viewport, + // but it's a close enough approximation for our purposes + highp float incidence_stretch = camera_to_anchor_distance / (u_camera_to_center_distance * cos(u_pitch)); + // incidence_stretch only applies to the y-axis, but without re-calculating the collision tile, we can't + // adjust the size of only one axis. So, we do a crude approximation at placement time to get the aspect ratio + // about right, and then do the rest of the adjustment here: there will be some extra padding on the x-axis, + // but hopefully not too much. + // Never make the adjustment less than 1.0: instead of allowing collisions on the x-axis, be conservative on + // the y-axis. + highp float collision_adjustment = max(1.0, incidence_stretch / u_collision_y_stretch); + + // Floor to 1/10th zoom to dodge precision issues that can cause partially hidden labels + highp float perspective_zoom_adjust = floor(log2(perspective_ratio * collision_adjustment) * 10.0); + v_fade_tex = vec2((a_labelminzoom + perspective_zoom_adjust) / 255.0, 0.0); } )MBGL_SHADER"; @@ -227,66 +273,73 @@ varying highp vec4 fill_color; uniform highp vec4 u_fill_color; #endif + #ifndef HAS_UNIFORM_u_halo_color varying highp vec4 halo_color; #else uniform highp vec4 u_halo_color; #endif + #ifndef HAS_UNIFORM_u_opacity varying lowp float opacity; #else uniform lowp float u_opacity; #endif + #ifndef HAS_UNIFORM_u_halo_width varying lowp float halo_width; #else uniform lowp float u_halo_width; #endif + #ifndef HAS_UNIFORM_u_halo_blur varying lowp float halo_blur; #else uniform lowp float u_halo_blur; #endif + uniform sampler2D u_texture; uniform sampler2D u_fadetexture; uniform highp float u_gamma_scale; uniform bool u_is_text; -varying vec4 v_data0; -varying vec2 v_data1; +varying vec2 v_tex; +varying vec2 v_fade_tex; +varying float v_gamma_scale; +varying float v_size; void main() { - + #ifdef HAS_UNIFORM_u_fill_color highp vec4 fill_color = u_fill_color; #endif + #ifdef HAS_UNIFORM_u_halo_color highp vec4 halo_color = u_halo_color; #endif + #ifdef HAS_UNIFORM_u_opacity lowp float opacity = u_opacity; #endif + #ifdef HAS_UNIFORM_u_halo_width lowp float halo_width = u_halo_width; #endif + #ifdef HAS_UNIFORM_u_halo_blur lowp float halo_blur = u_halo_blur; #endif - vec2 tex = v_data0.xy; - vec2 fade_tex = v_data0.zw; - float gamma_scale = v_data1.x; - float size = v_data1.y; - float fontScale = u_is_text ? size / 24.0 : size; + float fontScale = u_is_text ? v_size / 24.0 : v_size; lowp vec4 color = fill_color; highp float gamma = EDGE_GAMMA / (fontScale * u_gamma_scale); @@ -297,9 +350,9 @@ void main() { buff = (6.0 - halo_width / fontScale) / SDF_PX; } - lowp float dist = texture2D(u_texture, tex).a; - lowp float fade_alpha = texture2D(u_fadetexture, fade_tex).a; - highp float gamma_scaled = gamma * gamma_scale; + lowp float dist = texture2D(u_texture, v_tex).a; + lowp float fade_alpha = texture2D(u_fadetexture, v_fade_tex).a; + highp float gamma_scaled = gamma * v_gamma_scale; highp float alpha = smoothstep(buff - gamma_scaled, buff + gamma_scaled, dist) * fade_alpha; gl_FragColor = color * (alpha * opacity); -- cgit v1.2.1 From 72f6b73590722d5451623cd21c4b1abde74e8f69 Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Thu, 25 May 2017 14:12:20 -0700 Subject: [core] Limit symbol re-placement on changed tile distance to pitch > 25. --- src/mbgl/text/placement_config.hpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/mbgl/text/placement_config.hpp b/src/mbgl/text/placement_config.hpp index c5c013055a..1e1279341d 100644 --- a/src/mbgl/text/placement_config.hpp +++ b/src/mbgl/text/placement_config.hpp @@ -1,5 +1,7 @@ #pragma once +#include + namespace mbgl { class PlacementConfig { @@ -9,7 +11,11 @@ public: } bool operator==(const PlacementConfig& rhs) const { - return angle == rhs.angle && pitch == rhs.pitch && cameraToCenterDistance == rhs.cameraToCenterDistance && cameraToTileDistance == rhs.cameraToTileDistance && debug == rhs.debug; + return angle == rhs.angle && + pitch == rhs.pitch && + cameraToCenterDistance == rhs.cameraToCenterDistance && + (pitch * util::RAD2DEG < 25 || cameraToTileDistance == rhs.cameraToTileDistance) && + debug == rhs.debug; } bool operator!=(const PlacementConfig& rhs) const { -- cgit v1.2.1 From a432a289a35815beeadc8719a963f50f8dc07bbb Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Mon, 29 May 2017 12:47:32 -0700 Subject: [core] Change OverscaledTileID to also include a "wrap" value. This prevents TilePyramid from sharing wrapped copies of tiles. This is necessary because two wrapped tiles no longer share the same CollisionTile. --- src/mbgl/algorithm/update_renderables.hpp | 9 +- src/mbgl/renderer/tile_pyramid.cpp | 7 +- src/mbgl/tile/tile_id.hpp | 33 +- test/algorithm/update_renderables.test.cpp | 986 ++++++++++++++--------------- test/tile/tile_id.test.cpp | 146 ++--- 5 files changed, 588 insertions(+), 593 deletions(-) diff --git a/src/mbgl/algorithm/update_renderables.hpp b/src/mbgl/algorithm/update_renderables.hpp index a9c348b538..0c2266ff47 100644 --- a/src/mbgl/algorithm/update_renderables.hpp +++ b/src/mbgl/algorithm/update_renderables.hpp @@ -31,7 +31,7 @@ void updateRenderables(GetTileFn getTile, assert(idealRenderTileID.canonical.z <= zoomRange.max); assert(dataTileZoom >= idealRenderTileID.canonical.z); - const OverscaledTileID idealDataTileID(dataTileZoom, idealRenderTileID.canonical); + const OverscaledTileID idealDataTileID(dataTileZoom, idealRenderTileID.wrap, idealRenderTileID.canonical); auto tile = getTile(idealDataTileID); if (!tile) { tile = createTile(idealDataTileID); @@ -64,11 +64,11 @@ void updateRenderables(GetTileFn getTile, } else { // Check all four actual child tiles. for (const auto& childTileID : idealDataTileID.canonical.children()) { - const OverscaledTileID childDataTileID(overscaledZ, childTileID); + const OverscaledTileID childDataTileID(overscaledZ, idealRenderTileID.wrap, childTileID); tile = getTile(childDataTileID); if (tile && tile->isRenderable()) { retainTile(*tile, Resource::Necessity::Optional); - renderTile(childDataTileID.unwrapTo(idealRenderTileID.wrap), *tile); + renderTile(childDataTileID.toUnwrapped(), *tile); } else { // At least one child tile doesn't exist, so we are going to look for // parents as well. @@ -81,8 +81,7 @@ void updateRenderables(GetTileFn getTile, // We couldn't find child tiles that entirely cover the ideal tile. for (overscaledZ = dataTileZoom - 1; overscaledZ >= zoomRange.min; --overscaledZ) { const auto parentDataTileID = idealDataTileID.scaledTo(overscaledZ); - const auto parentRenderTileID = - parentDataTileID.unwrapTo(idealRenderTileID.wrap); + const auto parentRenderTileID = parentDataTileID.toUnwrapped(); if (checked.find(parentRenderTileID) != checked.end()) { // Break parent tile ascent, this route has been checked by another child diff --git a/src/mbgl/renderer/tile_pyramid.cpp b/src/mbgl/renderer/tile_pyramid.cpp index 57e7f6d375..5b1e621743 100644 --- a/src/mbgl/renderer/tile_pyramid.cpp +++ b/src/mbgl/renderer/tile_pyramid.cpp @@ -176,15 +176,12 @@ void TilePyramid::update(const std::vector>& layer removeStaleTiles(retain); for (auto& pair : tiles) { - // TODO: Calculating yStretch based on tile distance means we can no longer use the same collision tile for two wrapped - // copies of the same data tile. For now the assumption that we're always at "wrap = 0" means collision detection is broken - // for wrapped tiles. const PlacementConfig config { parameters.transformState.getAngle(), parameters.transformState.getPitch(), parameters.transformState.getCameraToCenterDistance(), - parameters.transformState.getCameraToTileDistance(pair.first.unwrapTo(0)), + parameters.transformState.getCameraToTileDistance(pair.first.toUnwrapped()), parameters.debugOptions & MapDebugOptions::Collision }; - + pair.second->setPlacementConfig(config); } } diff --git a/src/mbgl/tile/tile_id.hpp b/src/mbgl/tile/tile_id.hpp index 1ce3eea98e..811158e9b9 100644 --- a/src/mbgl/tile/tile_id.hpp +++ b/src/mbgl/tile/tile_id.hpp @@ -46,8 +46,8 @@ std::string toString(const CanonicalTileID&); // z/x/y describe the class OverscaledTileID { public: - OverscaledTileID(uint8_t overscaledZ, CanonicalTileID); - OverscaledTileID(uint8_t overscaledZ, uint8_t z, uint32_t x, uint32_t y); + OverscaledTileID(uint8_t overscaledZ, int16_t wrap, CanonicalTileID); + OverscaledTileID(uint8_t overscaledZ, int16_t wrap, uint8_t z, uint32_t x, uint32_t y); OverscaledTileID(uint8_t z, uint32_t x, uint32_t y); explicit OverscaledTileID(const CanonicalTileID&); explicit OverscaledTileID(CanonicalTileID&&); @@ -57,9 +57,10 @@ public: bool isChildOf(const OverscaledTileID&) const; uint32_t overscaleFactor() const; OverscaledTileID scaledTo(uint8_t z) const; - UnwrappedTileID unwrapTo(int16_t wrap) const; + UnwrappedTileID toUnwrapped() const; const uint8_t overscaledZ; + const int16_t wrap; const CanonicalTileID canonical; }; @@ -137,40 +138,40 @@ inline std::array CanonicalTileID::children() const { } }; } -inline OverscaledTileID::OverscaledTileID(uint8_t overscaledZ_, CanonicalTileID canonical_) - : overscaledZ(overscaledZ_), canonical(std::move(canonical_)) { +inline OverscaledTileID::OverscaledTileID(uint8_t overscaledZ_, int16_t wrap_, CanonicalTileID canonical_) + : overscaledZ(overscaledZ_), wrap(wrap_), canonical(std::move(canonical_)) { assert(overscaledZ >= canonical.z); } -inline OverscaledTileID::OverscaledTileID(uint8_t overscaledZ_, uint8_t z, uint32_t x, uint32_t y) - : overscaledZ(overscaledZ_), canonical(z, x, y) { +inline OverscaledTileID::OverscaledTileID(uint8_t overscaledZ_, int16_t wrap_, uint8_t z, uint32_t x, uint32_t y) + : overscaledZ(overscaledZ_), wrap(wrap_), canonical(z, x, y) { assert(overscaledZ >= canonical.z); } inline OverscaledTileID::OverscaledTileID(uint8_t z, uint32_t x, uint32_t y) - : overscaledZ(z), canonical(z, x, y) { + : overscaledZ(z), wrap(0), canonical(z, x, y) { } inline OverscaledTileID::OverscaledTileID(const CanonicalTileID& canonical_) - : overscaledZ(canonical_.z), canonical(canonical_) { + : overscaledZ(canonical_.z), wrap(0), canonical(canonical_) { assert(overscaledZ >= canonical.z); } inline OverscaledTileID::OverscaledTileID(CanonicalTileID&& canonical_) - : overscaledZ(canonical_.z), canonical(std::forward(canonical_)) { + : overscaledZ(canonical_.z), wrap(0), canonical(std::forward(canonical_)) { assert(overscaledZ >= canonical.z); } inline bool OverscaledTileID::operator==(const OverscaledTileID& rhs) const { - return overscaledZ == rhs.overscaledZ && canonical == rhs.canonical; + return overscaledZ == rhs.overscaledZ && wrap == rhs.wrap &&canonical == rhs.canonical; } inline bool OverscaledTileID::operator!=(const OverscaledTileID& rhs) const { - return overscaledZ != rhs.overscaledZ || canonical != rhs.canonical; + return overscaledZ != rhs.overscaledZ || wrap != rhs.wrap || canonical != rhs.canonical; } inline bool OverscaledTileID::operator<(const OverscaledTileID& rhs) const { - return std::tie(overscaledZ, canonical) < std::tie(rhs.overscaledZ, rhs.canonical); + return std::tie(overscaledZ, wrap, canonical) < std::tie(rhs.overscaledZ, rhs.wrap, rhs.canonical); } inline uint32_t OverscaledTileID::overscaleFactor() const { @@ -183,10 +184,10 @@ inline bool OverscaledTileID::isChildOf(const OverscaledTileID& rhs) const { } inline OverscaledTileID OverscaledTileID::scaledTo(uint8_t z) const { - return { z, z >= canonical.z ? canonical : canonical.scaledTo(z) }; + return { z, wrap, z >= canonical.z ? canonical : canonical.scaledTo(z) }; } -inline UnwrappedTileID OverscaledTileID::unwrapTo(int16_t wrap) const { +inline UnwrappedTileID OverscaledTileID::toUnwrapped() const { return { wrap, canonical }; } @@ -232,7 +233,7 @@ inline std::array UnwrappedTileID::children() const { inline OverscaledTileID UnwrappedTileID::overscaleTo(const uint8_t overscaledZ) const { assert(overscaledZ >= canonical.z); - return { overscaledZ, canonical }; + return { overscaledZ, wrap, canonical }; } inline float UnwrappedTileID::pixelsToTileUnits(const float pixelValue, const float zoom) const { diff --git a/test/algorithm/update_renderables.test.cpp b/test/algorithm/update_renderables.test.cpp index af90d262de..26b7cf7f72 100644 --- a/test/algorithm/update_renderables.test.cpp +++ b/test/algorithm/update_renderables.test.cpp @@ -23,10 +23,10 @@ struct GetTileDataAction { }; std::ostream& operator<<(std::ostream& os, const GetTileDataAction& action) { - return os << "GetTileDataAction{ { " << int(action.tileID.overscaledZ) << ", { " + return os << "GetTileDataAction{ { " << int(action.tileID.overscaledZ) << ", " << int(action.tileID.wrap) << ", { " << int(action.tileID.canonical.z) << ", " << action.tileID.canonical.x << ", " << action.tileID.canonical.y << " } }, " - << (action.found == Found ? "Found" : "NotFound") << " }"; + << (action.found == Found ? "Found" : "NotFound") << " }\n"; } struct CreateTileDataAction { @@ -38,9 +38,9 @@ struct CreateTileDataAction { }; std::ostream& operator<<(std::ostream& os, const CreateTileDataAction& action) { - return os << "CreateTileDataAction{ { " << int(action.tileID.overscaledZ) << ", { " + return os << "CreateTileDataAction{ { " << int(action.tileID.overscaledZ) << ", " << int(action.tileID.wrap) << ", { " << int(action.tileID.canonical.z) << ", " << action.tileID.canonical.x << ", " - << action.tileID.canonical.y << " } } }"; + << action.tileID.canonical.y << " } } }\n"; } struct RetainTileDataAction { @@ -53,10 +53,10 @@ struct RetainTileDataAction { }; std::ostream& operator<<(std::ostream& os, const RetainTileDataAction& action) { - return os << "RetainTileDataAction{ { " << int(action.tileID.overscaledZ) << ", { " + return os << "RetainTileDataAction{ { " << int(action.tileID.overscaledZ) << ", " << int(action.tileID.wrap) << ", { " << int(action.tileID.canonical.z) << ", " << action.tileID.canonical.x << ", " << action.tileID.canonical.y << " } }, " - << (action.necessity == Resource::Necessity::Required ? "Required" : "Optional") << " }"; + << (action.necessity == Resource::Necessity::Required ? "Required" : "Optional") << " }\n"; } struct RenderTileAction { @@ -76,7 +76,7 @@ std::ostream& operator<<(std::ostream& os, const RenderTileAction& action) { << int(action.tileData.tileID.overscaledZ) << "_" << int(action.tileData.tileID.canonical.z) << "_" << action.tileData.tileID.canonical.x << "_" << action.tileData.tileID.canonical.y - << " }"; + << " }\n"; } using ActionLogEntry = @@ -129,8 +129,8 @@ TEST(UpdateRenderables, SingleTile) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 1); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 1, { 1, 1, 1 } }, Found }, // found ideal tile - RetainTileDataAction{ { 1, { 1, 1, 1 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 1, 0, { 1, 1, 1 } }, Found }, // found ideal tile + RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, Resource::Necessity::Required }, // RenderTileAction{ { 1, 1, 1 }, *tile_1_1_1_1 }, // render ideal tile }), log); @@ -140,8 +140,8 @@ TEST(UpdateRenderables, SingleTile) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 1); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 1, { 1, 1, 1 } }, Found }, // found ideal tile - RetainTileDataAction{ { 1, { 1, 1, 1 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 1, 0, { 1, 1, 1 } }, Found }, // found ideal tile + RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, Resource::Necessity::Required }, // RenderTileAction{ { 1, 1, 1 }, *tile_1_1_1_1 }, // render ideal tile }), log); @@ -152,39 +152,39 @@ TEST(UpdateRenderables, SingleTile) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 1); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 1, { 1, 0, 1 } }, NotFound }, // missing ideal tile - CreateTileDataAction{ { 1, { 1, 0, 1 } } }, // create ideal tile - RetainTileDataAction{ { 1, { 1, 0, 1 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 2, { 2, 0, 2 } }, NotFound }, // four child tiles - GetTileDataAction{ { 2, { 2, 0, 3 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 1, 2 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 1, 3 } }, NotFound }, // ... - GetTileDataAction{ { 0, { 0, 0, 0 } }, NotFound }, // parent tile - - GetTileDataAction{ { 1, { 1, 1, 1 } }, Found }, // found ideal tile - RetainTileDataAction{ { 1, { 1, 1, 1 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, NotFound }, // missing ideal tile + CreateTileDataAction{ { 1, 0, { 1, 0, 1 } } }, // create ideal tile + RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, 0, { 2, 0, 2 } }, NotFound }, // four child tiles + GetTileDataAction{ { 2, 0, { 2, 0, 3 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 1, 2 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 1, 3 } }, NotFound }, // ... + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // parent tile + + GetTileDataAction{ { 1, 0, { 1, 1, 1 } }, Found }, // found ideal tile + RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, Resource::Necessity::Required }, // RenderTileAction{ { 1, 1, 1 }, *tile_1_1_1_1 }, // render found tile }), log); // Mark the created tile as having the optional request tried. log.clear(); - source.dataTiles[{ 1, { 1, 0, 1 } }]->triedOptional = true; + source.dataTiles[{ 1, 0, { 1, 0, 1 } }]->triedOptional = true; algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 1); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 1, { 1, 0, 1 } }, Found }, // missing ideal tile - RetainTileDataAction{ { 1, { 1, 0, 1 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 2, { 2, 0, 2 } }, NotFound }, // four child tiles - GetTileDataAction{ { 2, { 2, 0, 3 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 1, 2 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 1, 3 } }, NotFound }, // ... - GetTileDataAction{ { 0, { 0, 0, 0 } }, NotFound }, // parent tile - CreateTileDataAction{ { 0, { 0, 0, 0 } } }, // load parent tile - RetainTileDataAction{ { 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // - - GetTileDataAction{ { 1, { 1, 1, 1 } }, Found }, // found ideal tile - RetainTileDataAction{ { 1, { 1, 1, 1 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, Found }, // missing ideal tile + RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, 0, { 2, 0, 2 } }, NotFound }, // four child tiles + GetTileDataAction{ { 2, 0, { 2, 0, 3 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 1, 2 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 1, 3 } }, NotFound }, // ... + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // parent tile + CreateTileDataAction{ { 0, 0, { 0, 0, 0 } } }, // load parent tile + RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // + + GetTileDataAction{ { 1, 0, { 1, 1, 1 } }, Found }, // found ideal tile + RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, Resource::Necessity::Required }, // RenderTileAction{ { 1, 1, 1 }, *tile_1_1_1_1 }, // render found tile }), log); @@ -196,12 +196,12 @@ TEST(UpdateRenderables, SingleTile) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 1); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 1, { 1, 0, 1 } }, Found }, // newly added tile - RetainTileDataAction{ { 1, { 1, 0, 1 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, Found }, // newly added tile + RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, Resource::Necessity::Required }, // RenderTileAction{ { 1, 0, 1 }, *tile_1_1_0_1 }, // render ideal tile - GetTileDataAction{ { 1, { 1, 1, 1 } }, Found }, // ideal tile - RetainTileDataAction{ { 1, { 1, 1, 1 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 1, 0, { 1, 1, 1 } }, Found }, // ideal tile + RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, Resource::Necessity::Required }, // RenderTileAction{ { 1, 1, 1 }, *tile_1_1_1_1 }, // render found tile }), log); @@ -215,22 +215,22 @@ TEST(UpdateRenderables, SingleTile) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 1); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 1, { 1, 0, 0 } }, Found }, // found tile, not ready - RetainTileDataAction{ { 1, { 1, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // four child tiles - GetTileDataAction{ { 2, { 2, 0, 1 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 1, 0 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 1, 1 } }, NotFound }, // ... - GetTileDataAction{ { 0, { 0, 0, 0 } }, Found }, // parent tile - RetainTileDataAction{ { 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // found tile, not ready + RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // four child tiles + GetTileDataAction{ { 2, 0, { 2, 0, 1 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 1, 0 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 1, 1 } }, NotFound }, // ... + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, // parent tile + RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // // optional parent tile was already created before, but is not renderable - GetTileDataAction{ { 1, { 1, 0, 1 } }, Found }, // ideal tile - RetainTileDataAction{ { 1, { 1, 0, 1 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, Found }, // ideal tile + RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, Resource::Necessity::Required }, // RenderTileAction{ { 1, 0, 1 }, *tile_1_1_0_1 }, // render ideal tile - GetTileDataAction{ { 1, { 1, 1, 1 } }, Found }, // ideal tile - RetainTileDataAction{ { 1, { 1, 1, 1 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 1, 0, { 1, 1, 1 } }, Found }, // ideal tile + RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, Resource::Necessity::Required }, // RenderTileAction{ { 1, 1, 1 }, *tile_1_1_1_1 }, // render ideal tile }), log); @@ -241,16 +241,16 @@ TEST(UpdateRenderables, SingleTile) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 1); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 1, { 1, 0, 0 } }, Found }, // found tile, now ready - RetainTileDataAction{ { 1, { 1, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // found tile, now ready + RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, // RenderTileAction{ { 1, 0, 0 }, *tile_1_1_0_0 }, // - GetTileDataAction{ { 1, { 1, 0, 1 } }, Found }, // ideal tile - RetainTileDataAction{ { 1, { 1, 0, 1 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, Found }, // ideal tile + RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, Resource::Necessity::Required }, // RenderTileAction{ { 1, 0, 1 }, *tile_1_1_0_1 }, // - GetTileDataAction{ { 1, { 1, 1, 1 } }, Found }, // ideal tile - RetainTileDataAction{ { 1, { 1, 1, 1 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 1, 0, { 1, 1, 1 } }, Found }, // ideal tile + RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, Resource::Necessity::Required }, // RenderTileAction{ { 1, 1, 1 }, *tile_1_1_1_1 }, // }), log); @@ -274,30 +274,30 @@ TEST(UpdateRenderables, UseParentTile) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 1); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 1, { 1, 0, 1 } }, NotFound }, // missing ideal tile - CreateTileDataAction{ { 1, { 1, 0, 1 } } }, // - RetainTileDataAction{ { 1, { 1, 0, 1 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 2, { 2, 0, 2 } }, NotFound }, // child tile - GetTileDataAction{ { 2, { 2, 0, 3 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 1, 2 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 1, 3 } }, NotFound }, // ... - GetTileDataAction{ { 0, { 0, 0, 0 } }, Found }, // parent found! - RetainTileDataAction{ { 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, NotFound }, // missing ideal tile + CreateTileDataAction{ { 1, 0, { 1, 0, 1 } } }, // + RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, 0, { 2, 0, 2 } }, NotFound }, // child tile + GetTileDataAction{ { 2, 0, { 2, 0, 3 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 1, 2 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 1, 3 } }, NotFound }, // ... + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, // parent found! + RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 0, 0, 0 }, *tile_0_0_0_0 }, // render parent - GetTileDataAction{ { 1, { 1, 1, 0 } }, NotFound }, // missing ideal tile - CreateTileDataAction{ { 1, { 1, 1, 0 } } }, // - RetainTileDataAction{ { 1, { 1, 1, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 2, { 2, 2, 0 } }, NotFound }, // child tile - GetTileDataAction{ { 2, { 2, 2, 1 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 3, 0 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 3, 1 } }, NotFound }, // ... - GetTileDataAction{ { 1, { 1, 1, 1 } }, NotFound }, // missing tile - CreateTileDataAction{ { 1, { 1, 1, 1 } } }, // - RetainTileDataAction{ { 1, { 1, 1, 1 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 2, { 2, 2, 2 } }, NotFound }, // child tile - GetTileDataAction{ { 2, { 2, 2, 3 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 3, 2 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 3, 3 } }, NotFound }, // ... + GetTileDataAction{ { 1, 0, { 1, 1, 0 } }, NotFound }, // missing ideal tile + CreateTileDataAction{ { 1, 0, { 1, 1, 0 } } }, // + RetainTileDataAction{ { 1, 0, { 1, 1, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, 0, { 2, 2, 0 } }, NotFound }, // child tile + GetTileDataAction{ { 2, 0, { 2, 2, 1 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 3, 0 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 3, 1 } }, NotFound }, // ... + GetTileDataAction{ { 1, 0, { 1, 1, 1 } }, NotFound }, // missing tile + CreateTileDataAction{ { 1, 0, { 1, 1, 1 } } }, // + RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, 0, { 2, 2, 2 } }, NotFound }, // child tile + GetTileDataAction{ { 2, 0, { 2, 2, 3 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 3, 2 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 3, 3 } }, NotFound }, // ... }), log); } @@ -317,34 +317,34 @@ TEST(UpdateRenderables, DontUseWrongParentTile) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 2); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // missing ideal tile - CreateTileDataAction{ { 2, { 2, 0, 0 } } }, // - RetainTileDataAction{ { 2, { 2, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 3, { 3, 0, 0 } }, NotFound }, // child tile - GetTileDataAction{ { 3, { 3, 0, 1 } }, NotFound }, // ... - GetTileDataAction{ { 3, { 3, 1, 0 } }, NotFound }, // ... - GetTileDataAction{ { 3, { 3, 1, 1 } }, NotFound }, // ... - GetTileDataAction{ { 1, { 1, 0, 0 } }, NotFound }, // parent tile, missing - GetTileDataAction{ { 0, { 0, 0, 0 } }, NotFound }, // parent tile, missing + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // missing ideal tile + CreateTileDataAction{ { 2, 0, { 2, 0, 0 } } }, // + RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // child tile + GetTileDataAction{ { 3, 0, { 3, 0, 1 } }, NotFound }, // ... + GetTileDataAction{ { 3, 0, { 3, 1, 0 } }, NotFound }, // ... + GetTileDataAction{ { 3, 0, { 3, 1, 1 } }, NotFound }, // ... + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // parent tile, missing + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // parent tile, missing }), log); // Now mark the created tile as having the optional request tried. log.clear(); - source.dataTiles[{ 2, { 2, 0, 0 } }]->triedOptional = true; + source.dataTiles[{ 2, 0, { 2, 0, 0 } }]->triedOptional = true; algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 2); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 2, { 2, 0, 0 } }, Found }, // non-ready ideal tile - RetainTileDataAction{ { 2, { 2, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 3, { 3, 0, 0 } }, NotFound }, // child tile - GetTileDataAction{ { 3, { 3, 0, 1 } }, NotFound }, // ... - GetTileDataAction{ { 3, { 3, 1, 0 } }, NotFound }, // ... - GetTileDataAction{ { 3, { 3, 1, 1 } }, NotFound }, // ... - GetTileDataAction{ { 1, { 1, 0, 0 } }, NotFound }, // parent tile, missing - CreateTileDataAction{ { 1, { 1, 0, 0 } } }, // find optional parent - RetainTileDataAction{ { 1, { 1, 0, 0 } }, Resource::Necessity::Optional }, // - GetTileDataAction{ { 0, { 0, 0, 0 } }, NotFound }, // parent tile, missing + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // non-ready ideal tile + RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // child tile + GetTileDataAction{ { 3, 0, { 3, 0, 1 } }, NotFound }, // ... + GetTileDataAction{ { 3, 0, { 3, 1, 0 } }, NotFound }, // ... + GetTileDataAction{ { 3, 0, { 3, 1, 1 } }, NotFound }, // ... + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // parent tile, missing + CreateTileDataAction{ { 1, 0, { 1, 0, 0 } } }, // find optional parent + RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // parent tile, missing }), log); @@ -354,26 +354,26 @@ TEST(UpdateRenderables, DontUseWrongParentTile) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 2); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 2, { 2, 0, 0 } }, Found }, // non-ready ideal tile - RetainTileDataAction{ { 2, { 2, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // non-ready ideal tile + RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, // // this tile was added by the previous invocation of updateRenderables - GetTileDataAction{ { 3, { 3, 0, 0 } }, NotFound }, // child tile - GetTileDataAction{ { 3, { 3, 0, 1 } }, NotFound }, // ... - GetTileDataAction{ { 3, { 3, 1, 0 } }, NotFound }, // ... - GetTileDataAction{ { 3, { 3, 1, 1 } }, NotFound }, // ... - GetTileDataAction{ { 1, { 1, 0, 0 } }, Found }, // parent tile not ready - RetainTileDataAction{ { 1, { 1, 0, 0 } }, Resource::Necessity::Optional }, // - GetTileDataAction{ { 0, { 0, 0, 0 } }, NotFound }, // missing parent tile - - GetTileDataAction{ { 2, { 2, 2, 0 } }, NotFound }, // missing ideal tile - CreateTileDataAction{ { 2, { 2, 2, 0 } } }, // - RetainTileDataAction{ { 2, { 2, 2, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 3, { 3, 4, 0 } }, NotFound }, // child tile - GetTileDataAction{ { 3, { 3, 4, 1 } }, NotFound }, // ... - GetTileDataAction{ { 3, { 3, 5, 0 } }, NotFound }, // ... - GetTileDataAction{ { 3, { 3, 5, 1 } }, NotFound }, // ... - GetTileDataAction{ { 1, { 1, 1, 0 } }, Found }, // found parent tile - RetainTileDataAction{ { 1, { 1, 1, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // child tile + GetTileDataAction{ { 3, 0, { 3, 0, 1 } }, NotFound }, // ... + GetTileDataAction{ { 3, 0, { 3, 1, 0 } }, NotFound }, // ... + GetTileDataAction{ { 3, 0, { 3, 1, 1 } }, NotFound }, // ... + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // parent tile not ready + RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // missing parent tile + + GetTileDataAction{ { 2, 0, { 2, 2, 0 } }, NotFound }, // missing ideal tile + CreateTileDataAction{ { 2, 0, { 2, 2, 0 } } }, // + RetainTileDataAction{ { 2, 0, { 2, 2, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 3, 0, { 3, 4, 0 } }, NotFound }, // child tile + GetTileDataAction{ { 3, 0, { 3, 4, 1 } }, NotFound }, // ... + GetTileDataAction{ { 3, 0, { 3, 5, 0 } }, NotFound }, // ... + GetTileDataAction{ { 3, 0, { 3, 5, 1 } }, NotFound }, // ... + GetTileDataAction{ { 1, 0, { 1, 1, 0 } }, Found }, // found parent tile + RetainTileDataAction{ { 1, 0, { 1, 1, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 1, 1, 0 }, *tile_1_1_1_0 }, // render parent tile }), log); @@ -399,14 +399,14 @@ TEST(UpdateRenderables, UseParentTileWhenChildNotReady) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 1); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 1, { 1, 0, 1 } }, Found }, // found, but not ready - RetainTileDataAction{ { 1, { 1, 0, 1 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 2, { 2, 0, 2 } }, NotFound }, // child tile - GetTileDataAction{ { 2, { 2, 0, 3 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 1, 2 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 1, 3 } }, NotFound }, // ... - GetTileDataAction{ { 0, { 0, 0, 0 } }, Found }, // parent tile, ready - RetainTileDataAction{ { 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, Found }, // found, but not ready + RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, 0, { 2, 0, 2 } }, NotFound }, // child tile + GetTileDataAction{ { 2, 0, { 2, 0, 3 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 1, 2 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 1, 3 } }, NotFound }, // ... + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, // parent tile, ready + RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 0, 0, 0 }, *tile_0_0_0_0 }, // render parent tile }), log); @@ -417,8 +417,8 @@ TEST(UpdateRenderables, UseParentTileWhenChildNotReady) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 1); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 1, { 1, 0, 1 } }, Found }, // found and ready - RetainTileDataAction{ { 1, { 1, 0, 1 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, Found }, // found and ready + RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, Resource::Necessity::Required }, // RenderTileAction{ { 1, 0, 1 }, *tile_1_1_0_1 }, // render ideal tile }), log); @@ -444,19 +444,19 @@ TEST(UpdateRenderables, UseOverlappingParentTile) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 1); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 1, { 1, 0, 0 } }, NotFound }, // ideal tile not found - CreateTileDataAction{ { 1, { 1, 0, 0 } } }, // - RetainTileDataAction{ { 1, { 1, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // child tile - GetTileDataAction{ { 2, { 2, 0, 1 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 1, 0 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 1, 1 } }, NotFound }, // ... - GetTileDataAction{ { 0, { 0, 0, 0 } }, Found }, // parent tile found - RetainTileDataAction{ { 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ideal tile not found + CreateTileDataAction{ { 1, 0, { 1, 0, 0 } } }, // + RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // child tile + GetTileDataAction{ { 2, 0, { 2, 0, 1 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 1, 0 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 1, 1 } }, NotFound }, // ... + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, // parent tile found + RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 0, 0, 0 }, *tile_0_0_0_0 }, // - GetTileDataAction{ { 1, { 1, 0, 1 } }, Found }, // ideal tile found - RetainTileDataAction{ { 1, { 1, 0, 1 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, Found }, // ideal tile found + RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, Resource::Necessity::Required }, // RenderTileAction{ { 1, 0, 1 }, *tile_1_1_0_1 }, // }), log); @@ -480,17 +480,17 @@ TEST(UpdateRenderables, UseChildTiles) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 0); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 0, { 0, 0, 0 } }, NotFound }, // ideal tile, missing - CreateTileDataAction{ { 0, { 0, 0, 0 } } }, // - RetainTileDataAction{ { 0, { 0, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 1, { 1, 0, 0 } }, Found }, // child tile found - RetainTileDataAction{ { 1, { 1, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // ideal tile, missing + CreateTileDataAction{ { 0, 0, { 0, 0, 0 } } }, // + RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // child tile found + RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 1, 0, 0 }, *tile_1_1_0_0 }, // render child tile - GetTileDataAction{ { 1, { 1, 0, 1 } }, NotFound }, // child tile not found - GetTileDataAction{ { 1, { 1, 1, 0 } }, Found }, // child tile found - RetainTileDataAction{ { 1, { 1, 1, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, NotFound }, // child tile not found + GetTileDataAction{ { 1, 0, { 1, 1, 0 } }, Found }, // child tile found + RetainTileDataAction{ { 1, 0, { 1, 1, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 1, 1, 0 }, *tile_1_1_1_0 }, // render child tile - GetTileDataAction{ { 1, { 1, 1, 1 } }, NotFound }, // child tile not found + GetTileDataAction{ { 1, 0, { 1, 1, 1 } }, NotFound }, // child tile not found // no parent tile of 0 to consider }), log); @@ -514,17 +514,17 @@ TEST(UpdateRenderables, PreferChildTiles) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 1); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 1, { 1, 0, 0 } }, NotFound }, // ideal tile, not found - CreateTileDataAction{ { 1, { 1, 0, 0 } } }, // - RetainTileDataAction{ { 1, { 1, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 2, { 2, 0, 0 } }, Found }, // child tile, found - RetainTileDataAction{ { 2, { 2, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ideal tile, not found + CreateTileDataAction{ { 1, 0, { 1, 0, 0 } } }, // + RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // child tile, found + RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 2, 0, 0 }, *tile_2_2_0_0 }, // - GetTileDataAction{ { 2, { 2, 0, 1 } }, NotFound }, // child tile, not found - GetTileDataAction{ { 2, { 2, 1, 0 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 1, 1 } }, NotFound }, // ... - GetTileDataAction{ { 0, { 0, 0, 0 } }, Found }, // parent tile, found - RetainTileDataAction{ { 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 2, 0, { 2, 0, 1 } }, NotFound }, // child tile, not found + GetTileDataAction{ { 2, 0, { 2, 1, 0 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 1, 1 } }, NotFound }, // ... + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, // parent tile, found + RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 0, 0, 0 }, *tile_0_0_0_0 }, // }), log); @@ -537,19 +537,19 @@ TEST(UpdateRenderables, PreferChildTiles) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 1); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 1, { 1, 0, 0 } }, Found }, // ideal tile, not ready + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // ideal tile, not ready // ideal tile was added in previous invocation, but is not yet ready - RetainTileDataAction{ { 1, { 1, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 2, { 2, 0, 0 } }, Found }, // child tile, found - RetainTileDataAction{ { 2, { 2, 0, 0 } }, Resource::Necessity::Optional }, // + RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // child tile, found + RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 2, 0, 0 }, *tile_2_2_0_0 }, // - GetTileDataAction{ { 2, { 2, 0, 1 } }, Found }, // ... - RetainTileDataAction{ { 2, { 2, 0, 1 } }, Resource::Necessity::Optional }, // ... + GetTileDataAction{ { 2, 0, { 2, 0, 1 } }, Found }, // ... + RetainTileDataAction{ { 2, 0, { 2, 0, 1 } }, Resource::Necessity::Optional }, // ... RenderTileAction{ { 2, 0, 1 }, *tile_2_2_0_1 }, // - GetTileDataAction{ { 2, { 2, 1, 0 } }, NotFound }, // child tile, not found - GetTileDataAction{ { 2, { 2, 1, 1 } }, NotFound }, // ... - GetTileDataAction{ { 0, { 0, 0, 0 } }, Found }, // parent tile, found - RetainTileDataAction{ { 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 2, 0, { 2, 1, 0 } }, NotFound }, // child tile, not found + GetTileDataAction{ { 2, 0, { 2, 1, 1 } }, NotFound }, // ... + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, // parent tile, found + RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 0, 0, 0 }, *tile_0_0_0_0 }, // }), log); @@ -560,21 +560,21 @@ TEST(UpdateRenderables, PreferChildTiles) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 1); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 1, { 1, 0, 0 } }, Found }, // ideal tile, not ready + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // ideal tile, not ready // ideal tile was added in first invocation, but is not yet ready - RetainTileDataAction{ { 1, { 1, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 2, { 2, 0, 0 } }, Found }, // child tile, found - RetainTileDataAction{ { 2, { 2, 0, 0 } }, Resource::Necessity::Optional }, // + RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // child tile, found + RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 2, 0, 0 }, *tile_2_2_0_0 }, // - GetTileDataAction{ { 2, { 2, 0, 1 } }, Found }, // ... - RetainTileDataAction{ { 2, { 2, 0, 1 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 2, 0, { 2, 0, 1 } }, Found }, // ... + RetainTileDataAction{ { 2, 0, { 2, 0, 1 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 2, 0, 1 }, *tile_2_2_0_1 }, // - GetTileDataAction{ { 2, { 2, 1, 0 } }, Found }, // ... - RetainTileDataAction{ { 2, { 2, 1, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 2, 0, { 2, 1, 0 } }, Found }, // ... + RetainTileDataAction{ { 2, 0, { 2, 1, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 2, 1, 0 }, *tile_2_2_1_0 }, // - GetTileDataAction{ { 2, { 2, 1, 1 } }, NotFound }, // child tile, not found - GetTileDataAction{ { 0, { 0, 0, 0 } }, Found }, // parent tile, found - RetainTileDataAction{ { 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 2, 0, { 2, 1, 1 } }, NotFound }, // child tile, not found + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, // parent tile, found + RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 0, 0, 0 }, *tile_0_0_0_0 }, // }), log); @@ -586,20 +586,20 @@ TEST(UpdateRenderables, PreferChildTiles) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 1); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 1, { 1, 0, 0 } }, Found }, // ideal tile, not ready + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // ideal tile, not ready // ideal tile was added in first invocation, but is not yet ready - RetainTileDataAction{ { 1, { 1, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 2, { 2, 0, 0 } }, Found }, // child tile, found - RetainTileDataAction{ { 2, { 2, 0, 0 } }, Resource::Necessity::Optional }, // + RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // child tile, found + RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 2, 0, 0 }, *tile_2_2_0_0 }, // - GetTileDataAction{ { 2, { 2, 0, 1 } }, Found }, // ... - RetainTileDataAction{ { 2, { 2, 0, 1 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 2, 0, { 2, 0, 1 } }, Found }, // ... + RetainTileDataAction{ { 2, 0, { 2, 0, 1 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 2, 0, 1 }, *tile_2_2_0_1 }, // - GetTileDataAction{ { 2, { 2, 1, 0 } }, Found }, // ... - RetainTileDataAction{ { 2, { 2, 1, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 2, 0, { 2, 1, 0 } }, Found }, // ... + RetainTileDataAction{ { 2, 0, { 2, 1, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 2, 1, 0 }, *tile_2_2_1_0 }, // - GetTileDataAction{ { 2, { 2, 1, 1 } }, Found }, // ... - RetainTileDataAction{ { 2, { 2, 1, 1 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 2, 0, { 2, 1, 1 } }, Found }, // ... + RetainTileDataAction{ { 2, 0, { 2, 1, 1 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 2, 1, 1 }, *tile_2_2_1_1 }, // }), log); @@ -624,17 +624,17 @@ TEST(UpdateRenderables, UseParentAndChildTiles) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 1); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 1, { 1, 0, 0 } }, NotFound }, // ideal tile, missing - CreateTileDataAction{ { 1, { 1, 0, 0 } } }, // - RetainTileDataAction{ { 1, { 1, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 2, { 2, 0, 0 } }, Found }, // child tile - RetainTileDataAction{ { 2, { 2, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ideal tile, missing + CreateTileDataAction{ { 1, 0, { 1, 0, 0 } } }, // + RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // child tile + RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 2, 0, 0 }, *tile_2_2_0_0 }, // - GetTileDataAction{ { 2, { 2, 0, 1 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 1, 0 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 1, 1 } }, NotFound }, // - GetTileDataAction{ { 0, { 0, 0, 0 } }, Found }, // parent tile - RetainTileDataAction{ { 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 2, 0, { 2, 0, 1 } }, NotFound }, // + GetTileDataAction{ { 2, 0, { 2, 1, 0 } }, NotFound }, // + GetTileDataAction{ { 2, 0, { 2, 1, 1 } }, NotFound }, // + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, // parent tile + RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 0, 0, 0 }, *tile_0_0_0_0 }, // }), log); @@ -645,14 +645,14 @@ TEST(UpdateRenderables, UseParentAndChildTiles) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 1); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 1, { 1, 0, 0 } }, Found }, // ideal tile, not ready - RetainTileDataAction{ { 1, { 1, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 0, 1 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 1, 0 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 1, 1 } }, NotFound }, // - GetTileDataAction{ { 0, { 0, 0, 0 } }, Found }, // parent tile - RetainTileDataAction{ { 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // ideal tile, not ready + RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // + GetTileDataAction{ { 2, 0, { 2, 0, 1 } }, NotFound }, // + GetTileDataAction{ { 2, 0, { 2, 1, 0 } }, NotFound }, // + GetTileDataAction{ { 2, 0, { 2, 1, 1 } }, NotFound }, // + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, // parent tile + RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 0, 0, 0 }, *tile_0_0_0_0 }, // }), log); @@ -675,13 +675,13 @@ TEST(UpdateRenderables, DontUseTilesLowerThanMinzoom) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 2); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // ideal tile, missing - CreateTileDataAction{ { 2, { 2, 0, 0 } } }, // - RetainTileDataAction{ { 2, { 2, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 3, { 3, 0, 0 } }, NotFound }, // - GetTileDataAction{ { 3, { 3, 0, 1 } }, NotFound }, // - GetTileDataAction{ { 3, { 3, 1, 0 } }, NotFound }, // - GetTileDataAction{ { 3, { 3, 1, 1 } }, NotFound }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // ideal tile, missing + CreateTileDataAction{ { 2, 0, { 2, 0, 0 } } }, // + RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // + GetTileDataAction{ { 3, 0, { 3, 0, 1 } }, NotFound }, // + GetTileDataAction{ { 3, 0, { 3, 1, 0 } }, NotFound }, // + GetTileDataAction{ { 3, 0, { 3, 1, 1 } }, NotFound }, // // no requests for zoom 1 tiles }), log); @@ -705,58 +705,58 @@ TEST(UpdateRenderables, UseOverzoomedTileAfterMaxzoom) { source.idealTiles, source.zoomRange, 2); EXPECT_EQ( ActionLog({ - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // ideal tile, missing - CreateTileDataAction{ { 2, { 2, 0, 0 } } }, // - RetainTileDataAction{ { 2, { 2, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 3, { 2, 0, 0 } }, NotFound }, // overzoomed tile, not children! - GetTileDataAction{ { 1, { 1, 0, 0 } }, NotFound }, // - GetTileDataAction{ { 0, { 0, 0, 0 } }, NotFound }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // ideal tile, missing + CreateTileDataAction{ { 2, 0, { 2, 0, 0 } } }, // + RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 3, 0, { 2, 0, 0 } }, NotFound }, // overzoomed tile, not children! + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // }), log); // Mark the created tile as having tried the optional request. log.clear(); - source.dataTiles[{ 2, { 2, 0, 0 } }]->triedOptional = true; + source.dataTiles[{ 2, 0, { 2, 0, 0 } }]->triedOptional = true; algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 2); EXPECT_EQ( ActionLog({ - GetTileDataAction{ { 2, { 2, 0, 0 } }, Found }, // ideal tile, missing - RetainTileDataAction{ { 2, { 2, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 3, { 2, 0, 0 } }, NotFound }, // overzoomed tile, not children! - GetTileDataAction{ { 1, { 1, 0, 0 } }, NotFound }, // - CreateTileDataAction{ { 1, { 1, 0, 0 } } }, // - RetainTileDataAction{ { 1, { 1, 0, 0 } }, Resource::Necessity::Optional }, // - GetTileDataAction{ { 0, { 0, 0, 0 } }, NotFound }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // ideal tile, missing + RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 3, 0, { 2, 0, 0 } }, NotFound }, // overzoomed tile, not children! + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // + CreateTileDataAction{ { 1, 0, { 1, 0, 0 } } }, // + RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // }), log); // Only add a non-overzoomed ("parent") tile at first. log.clear(); - auto tile_2_2_0_0 = source.createTileData(OverscaledTileID{ 2, { 2, 0, 0 } }); + auto tile_2_2_0_0 = source.createTileData(OverscaledTileID{ 2, 0, { 2, 0, 0 } }); tile_2_2_0_0->renderable = true; algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 3); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 3, { 2, 0, 0 } }, NotFound }, // ideal tile, missing - CreateTileDataAction{ { 3, { 2, 0, 0 } } }, // - RetainTileDataAction{ { 3, { 2, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 4, { 2, 0, 0 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 0, 0 } }, Found }, // - RetainTileDataAction{ { 2, { 2, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 3, 0, { 2, 0, 0 } }, NotFound }, // ideal tile, missing + CreateTileDataAction{ { 3, 0, { 2, 0, 0 } } }, // + RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 4, 0, { 2, 0, 0 } }, NotFound }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // + RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 2, 0, 0 }, *tile_2_2_0_0 }, // }), log); // Then add the overzoomed tile matching the zoom level we're rendering. log.clear(); - auto tile_3_2_0_0 = source.createTileData(OverscaledTileID{ 3, { 2, 0, 0 } }); + auto tile_3_2_0_0 = source.createTileData(OverscaledTileID{ 3, 0, { 2, 0, 0 } }); tile_3_2_0_0->renderable = true; algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 3); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 3, { 2, 0, 0 } }, Found }, // - RetainTileDataAction{ { 3, { 2, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 3, 0, { 2, 0, 0 } }, Found }, // + RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, // RenderTileAction{ { 2, 0, 0 }, *tile_3_2_0_0 }, // }), log); @@ -766,26 +766,26 @@ TEST(UpdateRenderables, UseOverzoomedTileAfterMaxzoom) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 2); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 2, { 2, 0, 0 } }, Found }, // - RetainTileDataAction{ { 2, { 2, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // + RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, // RenderTileAction{ { 2, 0, 0 }, *tile_2_2_0_0 }, // }), log); // Now remove the best match. log.clear(); - source.dataTiles.erase(OverscaledTileID{ 2, { 2, 0, 0 } }); + source.dataTiles.erase(OverscaledTileID{ 2, 0, { 2, 0, 0 } }); tile_2_2_0_0 = nullptr; // Use the overzoomed tile even though it doesn't match the zoom level. algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 2); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // - CreateTileDataAction{ { 2, { 2, 0, 0 } } }, // - RetainTileDataAction{ { 2, { 2, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 3, { 2, 0, 0 } }, Found }, // use overzoomed tile! - RetainTileDataAction{ { 3, { 2, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // + CreateTileDataAction{ { 2, 0, { 2, 0, 0 } } }, // + RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 3, 0, { 2, 0, 0 } }, Found }, // use overzoomed tile! + RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 2, 0, 0 }, *tile_3_2_0_0 }, // }), log); @@ -803,69 +803,69 @@ TEST(UpdateRenderables, AscendToNonOverzoomedTiles) { source.idealTiles.emplace(UnwrappedTileID{ 2, 0, 0 }); // Add a matching overzoomed tile and make sure it gets selected. - auto tile_3_2_0_0 = source.createTileData(OverscaledTileID{ 3, { 2, 0, 0 } }); + auto tile_3_2_0_0 = source.createTileData(OverscaledTileID{ 3, 0, { 2, 0, 0 } }); tile_3_2_0_0->renderable = true; algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 3); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 3, { 2, 0, 0 } }, Found }, // - RetainTileDataAction{ { 3, { 2, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 3, 0, { 2, 0, 0 } }, Found }, // + RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, // RenderTileAction{ { 2, 0, 0 }, *tile_3_2_0_0 }, // }), log); // Then, swap it with a non-overzoomed tile. log.clear(); - source.dataTiles.erase(OverscaledTileID{ 3, { 2, 0, 0 } }); + source.dataTiles.erase(OverscaledTileID{ 3, 0, { 2, 0, 0 } }); tile_3_2_0_0 = nullptr; - auto tile_2_2_0_0 = source.createTileData(OverscaledTileID{ 2, { 2, 0, 0 } }); + auto tile_2_2_0_0 = source.createTileData(OverscaledTileID{ 2, 0, { 2, 0, 0 } }); tile_2_2_0_0->renderable = true; algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 3); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 3, { 2, 0, 0 } }, NotFound }, // - CreateTileDataAction{ { 3, { 2, 0, 0 } } }, // - RetainTileDataAction{ { 3, { 2, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 4, { 2, 0, 0 } }, NotFound }, // prefer using a child first - GetTileDataAction{ { 2, { 2, 0, 0 } }, Found }, // - RetainTileDataAction{ { 2, { 2, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 3, 0, { 2, 0, 0 } }, NotFound }, // + CreateTileDataAction{ { 3, 0, { 2, 0, 0 } } }, // + RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 4, 0, { 2, 0, 0 } }, NotFound }, // prefer using a child first + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // + RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 2, 0, 0 }, *tile_2_2_0_0 }, // }), log); // Then, swap it with a parent tile. log.clear(); - source.dataTiles.erase(OverscaledTileID{ 2, { 2, 0, 0 } }); + source.dataTiles.erase(OverscaledTileID{ 2, 0, { 2, 0, 0 } }); tile_2_2_0_0 = nullptr; - auto tile_1_1_0_0 = source.createTileData(OverscaledTileID{ 1, { 1, 0, 0 } }); + auto tile_1_1_0_0 = source.createTileData(OverscaledTileID{ 1, 0, { 1, 0, 0 } }); tile_1_1_0_0->renderable = true; algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 3); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 3, { 2, 0, 0 } }, Found }, // ideal tile, not ready - RetainTileDataAction{ { 3, { 2, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 4, { 2, 0, 0 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // - GetTileDataAction{ { 1, { 1, 0, 0 } }, Found }, // - RetainTileDataAction{ { 1, { 1, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 3, 0, { 2, 0, 0 } }, Found }, // ideal tile, not ready + RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 4, 0, { 2, 0, 0 } }, NotFound }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // + RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 1, 0, 0 }, *tile_1_1_0_0 }, // }), log); // Now, mark the created tile as found. log.clear(); - source.dataTiles[{ 3, { 2, 0, 0 } }]->triedOptional = true; + source.dataTiles[{ 3, 0, { 2, 0, 0 } }]->triedOptional = true; algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 3); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 3, { 2, 0, 0 } }, Found }, // ideal tile, not ready - RetainTileDataAction{ { 3, { 2, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 4, { 2, 0, 0 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // - CreateTileDataAction{ { 2, { 2, 0, 0 } } }, // - RetainTileDataAction{ { 2, { 2, 0, 0 } }, Resource::Necessity::Optional }, // - GetTileDataAction{ { 1, { 1, 0, 0 } }, Found }, // - RetainTileDataAction{ { 1, { 1, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 3, 0, { 2, 0, 0 } }, Found }, // ideal tile, not ready + RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 4, 0, { 2, 0, 0 } }, NotFound }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // + CreateTileDataAction{ { 2, 0, { 2, 0, 0 } } }, // + RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // + RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 1, 0, 0 }, *tile_1_1_0_0 }, // }), log); @@ -885,60 +885,60 @@ TEST(UpdateRenderables, DoNotAscendMultipleTimesIfNotFound) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 8); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 8, { 8, 0, 0 } }, NotFound }, // ideal tile - CreateTileDataAction{ { 8, { 8, 0, 0 } } }, // - RetainTileDataAction{ { 8, { 8, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 9, { 9, 0, 0 } }, NotFound }, // child tile - GetTileDataAction{ { 9, { 9, 0, 1 } }, NotFound }, // ... - GetTileDataAction{ { 9, { 9, 1, 0 } }, NotFound }, // ... - GetTileDataAction{ { 9, { 9, 1, 1 } }, NotFound }, // ... - GetTileDataAction{ { 7, { 7, 0, 0 } }, NotFound }, // ascent - GetTileDataAction{ { 6, { 6, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 5, { 5, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 4, { 4, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 3, { 3, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 1, { 1, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 0, { 0, 0, 0 } }, NotFound }, // ... - - GetTileDataAction{ { 8, { 8, 1, 0 } }, NotFound }, // ideal tile - CreateTileDataAction{ { 8, { 8, 1, 0 } } }, // - RetainTileDataAction{ { 8, { 8, 1, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 9, { 9, 2, 0 } }, NotFound }, // child tile - GetTileDataAction{ { 9, { 9, 2, 1 } }, NotFound }, // ... - GetTileDataAction{ { 9, { 9, 3, 0 } }, NotFound }, // ... - GetTileDataAction{ { 9, { 9, 3, 1 } }, NotFound }, // ... + GetTileDataAction{ { 8, 0, { 8, 0, 0 } }, NotFound }, // ideal tile + CreateTileDataAction{ { 8, 0, { 8, 0, 0 } } }, // + RetainTileDataAction{ { 8, 0, { 8, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 9, 0, { 9, 0, 0 } }, NotFound }, // child tile + GetTileDataAction{ { 9, 0, { 9, 0, 1 } }, NotFound }, // ... + GetTileDataAction{ { 9, 0, { 9, 1, 0 } }, NotFound }, // ... + GetTileDataAction{ { 9, 0, { 9, 1, 1 } }, NotFound }, // ... + GetTileDataAction{ { 7, 0, { 7, 0, 0 } }, NotFound }, // ascent + GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 5, 0, { 5, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 4, 0, { 4, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // ... + + GetTileDataAction{ { 8, 0, { 8, 1, 0 } }, NotFound }, // ideal tile + CreateTileDataAction{ { 8, 0, { 8, 1, 0 } } }, // + RetainTileDataAction{ { 8, 0, { 8, 1, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 9, 0, { 9, 2, 0 } }, NotFound }, // child tile + GetTileDataAction{ { 9, 0, { 9, 2, 1 } }, NotFound }, // ... + GetTileDataAction{ { 9, 0, { 9, 3, 0 } }, NotFound }, // ... + GetTileDataAction{ { 9, 0, { 9, 3, 1 } }, NotFound }, // ... // no second ascent to 0 }), log); // Now add a mid-level tile that stops the ascent log.clear(); - auto tile_4_0_0_0 = source.createTileData(OverscaledTileID{ 4, { 4, 0, 0 } }); + auto tile_4_0_0_0 = source.createTileData(OverscaledTileID{ 4, 0, { 4, 0, 0 } }); tile_4_0_0_0->renderable = true; algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 8); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 8, { 8, 0, 0 } }, Found }, // ideal tile, not ready - RetainTileDataAction{ { 8, { 8, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 9, { 9, 0, 0 } }, NotFound }, // child tile - GetTileDataAction{ { 9, { 9, 0, 1 } }, NotFound }, // ... - GetTileDataAction{ { 9, { 9, 1, 0 } }, NotFound }, // ... - GetTileDataAction{ { 9, { 9, 1, 1 } }, NotFound }, // ... - GetTileDataAction{ { 7, { 7, 0, 0 } }, NotFound }, // ascent - GetTileDataAction{ { 6, { 6, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 5, { 5, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 4, { 4, 0, 0 } }, Found }, // stops ascent - RetainTileDataAction{ { 4, { 4, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 8, 0, { 8, 0, 0 } }, Found }, // ideal tile, not ready + RetainTileDataAction{ { 8, 0, { 8, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 9, 0, { 9, 0, 0 } }, NotFound }, // child tile + GetTileDataAction{ { 9, 0, { 9, 0, 1 } }, NotFound }, // ... + GetTileDataAction{ { 9, 0, { 9, 1, 0 } }, NotFound }, // ... + GetTileDataAction{ { 9, 0, { 9, 1, 1 } }, NotFound }, // ... + GetTileDataAction{ { 7, 0, { 7, 0, 0 } }, NotFound }, // ascent + GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 5, 0, { 5, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 4, 0, { 4, 0, 0 } }, Found }, // stops ascent + RetainTileDataAction{ { 4, 0, { 4, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 4, 0, 0 }, *tile_4_0_0_0 }, // - GetTileDataAction{ { 8, { 8, 1, 0 } }, Found }, // ideal tile, not ready - RetainTileDataAction{ { 8, { 8, 1, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 9, { 9, 2, 0 } }, NotFound }, // child tile - GetTileDataAction{ { 9, { 9, 2, 1 } }, NotFound }, // ... - GetTileDataAction{ { 9, { 9, 3, 0 } }, NotFound }, // ... - GetTileDataAction{ { 9, { 9, 3, 1 } }, NotFound }, // ... + GetTileDataAction{ { 8, 0, { 8, 1, 0 } }, Found }, // ideal tile, not ready + RetainTileDataAction{ { 8, 0, { 8, 1, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 9, 0, { 9, 2, 0 } }, NotFound }, // child tile + GetTileDataAction{ { 9, 0, { 9, 2, 1 } }, NotFound }, // ... + GetTileDataAction{ { 9, 0, { 9, 3, 0 } }, NotFound }, // ... + GetTileDataAction{ { 9, 0, { 9, 3, 1 } }, NotFound }, // ... // no second ascent to 0 }), log); @@ -960,15 +960,15 @@ TEST(UpdateRenderables, DontRetainUnusedNonIdealTiles) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 2); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 2, { 2, 0, 0 } }, Found }, // ideal tile, not ready - RetainTileDataAction{ { 2, { 2, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 3, { 3, 0, 0 } }, NotFound }, // - GetTileDataAction{ { 3, { 3, 0, 1 } }, NotFound }, // - GetTileDataAction{ { 3, { 3, 1, 0 } }, NotFound }, // - GetTileDataAction{ { 3, { 3, 1, 1 } }, NotFound }, // - GetTileDataAction{ { 1, { 1, 0, 0 } }, Found }, // parent tile, not ready - RetainTileDataAction{ { 1, { 1, 0, 0 } }, Resource::Necessity::Optional }, // - GetTileDataAction{ { 0, { 0, 0, 0 } }, NotFound }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // ideal tile, not ready + RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // + GetTileDataAction{ { 3, 0, { 3, 0, 1 } }, NotFound }, // + GetTileDataAction{ { 3, 0, { 3, 1, 0 } }, NotFound }, // + GetTileDataAction{ { 3, 0, { 3, 1, 1 } }, NotFound }, // + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // parent tile, not ready + RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // }), log); } @@ -981,56 +981,54 @@ TEST(UpdateRenderables, WrappedTiles) { auto retainTileData = retainTileDataFn(log); auto renderTile = renderTileFn(log); - source.idealTiles.emplace(UnwrappedTileID{ 1, -1, 0 }); - source.idealTiles.emplace(UnwrappedTileID{ 1, 0, 0 }); - source.idealTiles.emplace(UnwrappedTileID{ 1, 1, 0 }); - source.idealTiles.emplace(UnwrappedTileID{ 1, 2, 0 }); + source.idealTiles.emplace(UnwrappedTileID{ 1, -1, 0 }); // 'wrap' -> -1 + source.idealTiles.emplace(UnwrappedTileID{ 1, 0, 0 }); // 'wrap' -> 0 + source.idealTiles.emplace(UnwrappedTileID{ 1, 1, 0 }); // 'wrap' -> 0 + source.idealTiles.emplace(UnwrappedTileID{ 1, 2, 0 }); // 'wrap' -> 1 - auto tile_0_0_0_0 = source.createTileData(OverscaledTileID{ 0, { 0, 0, 0 } }); + auto tile_0_0_0_0 = source.createTileData(OverscaledTileID{ 0, 0, { 0, 0, 0 } }); tile_0_0_0_0->renderable = true; algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 1); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 1, { 1, 1, 0 } }, NotFound }, // ideal tile 1/-1/0 - CreateTileDataAction{ { 1, { 1, 1, 0 } } }, // - RetainTileDataAction{ { 1, { 1, 1, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 2, { 2, 2, 0 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 2, 1 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 3, 0 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 3, 1 } }, NotFound }, // - GetTileDataAction{ { 0, { 0, 0, 0 } }, Found }, // - RetainTileDataAction{ { 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // - RenderTileAction{ { 0, -1, 0 }, *tile_0_0_0_0 }, // - - GetTileDataAction{ { 1, { 1, 0, 0 } }, NotFound }, // ideal tile 1/0/0 - CreateTileDataAction{ { 1, { 1, 0, 0 } } }, // - RetainTileDataAction{ { 1, { 1, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 0, 1 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 1, 0 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 1, 1 } }, NotFound }, // - GetTileDataAction{ { 0, { 0, 0, 0 } }, Found }, // - RetainTileDataAction{ { 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 1, -1, { 1, 1, 0 } }, NotFound }, // ideal tile 1/-1/0 (wrapped to -1) + CreateTileDataAction{ { 1, -1, { 1, 1, 0 } } }, // + RetainTileDataAction{ { 1, -1, { 1, 1, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, -1, { 2, 2, 0 } }, NotFound }, // + GetTileDataAction{ { 2, -1, { 2, 2, 1 } }, NotFound }, // + GetTileDataAction{ { 2, -1, { 2, 3, 0 } }, NotFound }, // + GetTileDataAction{ { 2, -1, { 2, 3, 1 } }, NotFound }, // + GetTileDataAction{ { 0, -1, { 0, 0, 0 } }, NotFound }, // { 0, 0, 0 } exists, but not the version wrapped to -1 + + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ideal tile 1/0/0 + CreateTileDataAction{ { 1, 0, { 1, 0, 0 } } }, // + RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // + GetTileDataAction{ { 2, 0, { 2, 0, 1 } }, NotFound }, // + GetTileDataAction{ { 2, 0, { 2, 1, 0 } }, NotFound }, // + GetTileDataAction{ { 2, 0, { 2, 1, 1 } }, NotFound }, // + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, // + RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 0, 0, 0 }, *tile_0_0_0_0 }, // - GetTileDataAction{ { 1, { 1, 1, 0 } }, Found }, // ideal tile 1/1/0 - RetainTileDataAction{ { 1, { 1, 1, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 2, { 2, 2, 0 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 2, 1 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 3, 0 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 3, 1 } }, NotFound }, // + GetTileDataAction{ { 1, 0, { 1, 1, 0 } }, NotFound }, // ideal tile 1/1/0, doesn't match 1/-/1/0 + CreateTileDataAction{ { 1, 0, { 1, 1, 0 } } }, + RetainTileDataAction{ { 1, 0, { 1, 1, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, 0, { 2, 2, 0 } }, NotFound }, // + GetTileDataAction{ { 2, 0, { 2, 2, 1 } }, NotFound }, // + GetTileDataAction{ { 2, 0, { 2, 3, 0 } }, NotFound }, // + GetTileDataAction{ { 2, 0, { 2, 3, 1 } }, NotFound }, // // do not ascent; 0/0/0 has been rendered already for 1/0/0 - GetTileDataAction{ { 1, { 1, 0, 0 } }, Found }, // ideal tile 1/2/0 - RetainTileDataAction{ { 1, { 1, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 0, 1 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 1, 0 } }, NotFound }, // - GetTileDataAction{ { 2, { 2, 1, 1 } }, NotFound }, // - GetTileDataAction{ { 0, { 0, 0, 0 } }, Found }, // - RetainTileDataAction{ { 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, // - RenderTileAction{ { 0, 1, 0 }, *tile_0_0_0_0 }, // + GetTileDataAction{ { 1, 1, { 1, 0, 0 } }, NotFound }, // ideal tile 1/2/0 (wrapped to 1) + CreateTileDataAction{ { 1, 1, { 1, 0, 0 } } }, + RetainTileDataAction{ { 1, 1, { 1, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 2, 1, { 2, 0, 0 } }, NotFound }, // + GetTileDataAction{ { 2, 1, { 2, 0, 1 } }, NotFound }, // + GetTileDataAction{ { 2, 1, { 2, 1, 0 } }, NotFound }, // + GetTileDataAction{ { 2, 1, { 2, 1, 1 } }, NotFound }, // + GetTileDataAction{ { 0, 1, { 0, 0, 0 } }, NotFound }, // { 0, 0, 0 } exists, but not the version wrapped to -1 }), log); } @@ -1048,19 +1046,19 @@ TEST(UpdateRenderables, RepeatedRenderWithMissingOptionals) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 6); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 6, { 6, 0, 0 } }, NotFound }, // ideal tile, not found - CreateTileDataAction{ { 6, { 6, 0, 0 } } }, // - RetainTileDataAction{ { 6, { 6, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 7, { 7, 0, 0 } }, NotFound }, // children - GetTileDataAction{ { 7, { 7, 0, 1 } }, NotFound }, // ... - GetTileDataAction{ { 7, { 7, 1, 0 } }, NotFound }, // ... - GetTileDataAction{ { 7, { 7, 1, 1 } }, NotFound }, // ... - GetTileDataAction{ { 5, { 5, 0, 0 } }, NotFound }, // ascent - GetTileDataAction{ { 4, { 4, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 3, { 3, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 1, { 1, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 0, { 0, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, NotFound }, // ideal tile, not found + CreateTileDataAction{ { 6, 0, { 6, 0, 0 } } }, // + RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 7, 0, { 7, 0, 0 } }, NotFound }, // children + GetTileDataAction{ { 7, 0, { 7, 0, 1 } }, NotFound }, // ... + GetTileDataAction{ { 7, 0, { 7, 1, 0 } }, NotFound }, // ... + GetTileDataAction{ { 7, 0, { 7, 1, 1 } }, NotFound }, // ... + GetTileDataAction{ { 5, 0, { 5, 0, 0 } }, NotFound }, // ascent + GetTileDataAction{ { 4, 0, { 4, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // ... }), log); @@ -1069,41 +1067,41 @@ TEST(UpdateRenderables, RepeatedRenderWithMissingOptionals) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 6); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 6, { 6, 0, 0 } }, Found }, // ideal tile, not ready - RetainTileDataAction{ { 6, { 6, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 7, { 7, 0, 0 } }, NotFound }, // children - GetTileDataAction{ { 7, { 7, 0, 1 } }, NotFound }, // ... - GetTileDataAction{ { 7, { 7, 1, 0 } }, NotFound }, // ... - GetTileDataAction{ { 7, { 7, 1, 1 } }, NotFound }, // ... - GetTileDataAction{ { 5, { 5, 0, 0 } }, NotFound }, // ascent - GetTileDataAction{ { 4, { 4, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 3, { 3, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 1, { 1, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 0, { 0, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, Found }, // ideal tile, not ready + RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 7, 0, { 7, 0, 0 } }, NotFound }, // children + GetTileDataAction{ { 7, 0, { 7, 0, 1 } }, NotFound }, // ... + GetTileDataAction{ { 7, 0, { 7, 1, 0 } }, NotFound }, // ... + GetTileDataAction{ { 7, 0, { 7, 1, 1 } }, NotFound }, // ... + GetTileDataAction{ { 5, 0, { 5, 0, 0 } }, NotFound }, // ascent + GetTileDataAction{ { 4, 0, { 4, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // ... }), log); // Mark next level has having tried optional. log.clear(); - source.dataTiles[{ 6, { 6, 0, 0 } }]->triedOptional = true; + source.dataTiles[{ 6, 0, { 6, 0, 0 } }]->triedOptional = true; algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 6); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 6, { 6, 0, 0 } }, Found }, // ideal tile, not ready - RetainTileDataAction{ { 6, { 6, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 7, { 7, 0, 0 } }, NotFound }, // children - GetTileDataAction{ { 7, { 7, 0, 1 } }, NotFound }, // ... - GetTileDataAction{ { 7, { 7, 1, 0 } }, NotFound }, // ... - GetTileDataAction{ { 7, { 7, 1, 1 } }, NotFound }, // ... - GetTileDataAction{ { 5, { 5, 0, 0 } }, NotFound }, // ascent - CreateTileDataAction{ { 5, { 5, 0, 0 } } }, // - RetainTileDataAction{ { 5, { 5, 0, 0 } }, Resource::Necessity::Optional }, // - GetTileDataAction{ { 4, { 4, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 3, { 3, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 1, { 1, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 0, { 0, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, Found }, // ideal tile, not ready + RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 7, 0, { 7, 0, 0 } }, NotFound }, // children + GetTileDataAction{ { 7, 0, { 7, 0, 1 } }, NotFound }, // ... + GetTileDataAction{ { 7, 0, { 7, 1, 0 } }, NotFound }, // ... + GetTileDataAction{ { 7, 0, { 7, 1, 1 } }, NotFound }, // ... + GetTileDataAction{ { 5, 0, { 5, 0, 0 } }, NotFound }, // ascent + CreateTileDataAction{ { 5, 0, { 5, 0, 0 } } }, // + RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 4, 0, { 4, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // ... }), log); @@ -1112,116 +1110,116 @@ TEST(UpdateRenderables, RepeatedRenderWithMissingOptionals) { algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 6); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 6, { 6, 0, 0 } }, Found }, // ideal tile, not ready - RetainTileDataAction{ { 6, { 6, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 7, { 7, 0, 0 } }, NotFound }, // children - GetTileDataAction{ { 7, { 7, 0, 1 } }, NotFound }, // ... - GetTileDataAction{ { 7, { 7, 1, 0 } }, NotFound }, // ... - GetTileDataAction{ { 7, { 7, 1, 1 } }, NotFound }, // ... - GetTileDataAction{ { 5, { 5, 0, 0 } }, Found }, // ascent - RetainTileDataAction{ { 5, { 5, 0, 0 } }, Resource::Necessity::Optional }, // - GetTileDataAction{ { 4, { 4, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 3, { 3, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 1, { 1, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 0, { 0, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, Found }, // ideal tile, not ready + RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 7, 0, { 7, 0, 0 } }, NotFound }, // children + GetTileDataAction{ { 7, 0, { 7, 0, 1 } }, NotFound }, // ... + GetTileDataAction{ { 7, 0, { 7, 1, 0 } }, NotFound }, // ... + GetTileDataAction{ { 7, 0, { 7, 1, 1 } }, NotFound }, // ... + GetTileDataAction{ { 5, 0, { 5, 0, 0 } }, Found }, // ascent + RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 4, 0, { 4, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // ... }), log); // Mark next level has having tried optional. log.clear(); - source.dataTiles[{ 5, { 5, 0, 0 } }]->triedOptional = true; + source.dataTiles[{ 5, 0, { 5, 0, 0 } }]->triedOptional = true; algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 6); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 6, { 6, 0, 0 } }, Found }, // ideal tile, not ready - RetainTileDataAction{ { 6, { 6, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 7, { 7, 0, 0 } }, NotFound }, // children - GetTileDataAction{ { 7, { 7, 0, 1 } }, NotFound }, // ... - GetTileDataAction{ { 7, { 7, 1, 0 } }, NotFound }, // ... - GetTileDataAction{ { 7, { 7, 1, 1 } }, NotFound }, // ... - GetTileDataAction{ { 5, { 5, 0, 0 } }, Found }, // ascent - RetainTileDataAction{ { 5, { 5, 0, 0 } }, Resource::Necessity::Optional }, // - GetTileDataAction{ { 4, { 4, 0, 0 } }, NotFound }, // ... - CreateTileDataAction{ { 4, { 4, 0, 0 } } }, // - RetainTileDataAction{ { 4, { 4, 0, 0 } }, Resource::Necessity::Optional }, // - GetTileDataAction{ { 3, { 3, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 1, { 1, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 0, { 0, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, Found }, // ideal tile, not ready + RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 7, 0, { 7, 0, 0 } }, NotFound }, // children + GetTileDataAction{ { 7, 0, { 7, 0, 1 } }, NotFound }, // ... + GetTileDataAction{ { 7, 0, { 7, 1, 0 } }, NotFound }, // ... + GetTileDataAction{ { 7, 0, { 7, 1, 1 } }, NotFound }, // ... + GetTileDataAction{ { 5, 0, { 5, 0, 0 } }, Found }, // ascent + RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 4, 0, { 4, 0, 0 } }, NotFound }, // ... + CreateTileDataAction{ { 4, 0, { 4, 0, 0 } } }, // + RetainTileDataAction{ { 4, 0, { 4, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // ... }), log); // Mark next level has having tried optional. log.clear(); - source.dataTiles[{ 4, { 4, 0, 0 } }]->triedOptional = true; + source.dataTiles[{ 4, 0, { 4, 0, 0 } }]->triedOptional = true; algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 6); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 6, { 6, 0, 0 } }, Found }, // ideal tile, not ready - RetainTileDataAction{ { 6, { 6, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 7, { 7, 0, 0 } }, NotFound }, // children - GetTileDataAction{ { 7, { 7, 0, 1 } }, NotFound }, // ... - GetTileDataAction{ { 7, { 7, 1, 0 } }, NotFound }, // ... - GetTileDataAction{ { 7, { 7, 1, 1 } }, NotFound }, // ... - GetTileDataAction{ { 5, { 5, 0, 0 } }, Found }, // ascent - RetainTileDataAction{ { 5, { 5, 0, 0 } }, Resource::Necessity::Optional }, // - GetTileDataAction{ { 4, { 4, 0, 0 } }, Found }, // ... - RetainTileDataAction{ { 4, { 4, 0, 0 } }, Resource::Necessity::Optional }, // - GetTileDataAction{ { 3, { 3, 0, 0 } }, NotFound }, // ... - CreateTileDataAction{ { 3, { 3, 0, 0 } } }, // - RetainTileDataAction{ { 3, { 3, 0, 0 } }, Resource::Necessity::Optional }, // - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 1, { 1, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 0, { 0, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, Found }, // ideal tile, not ready + RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 7, 0, { 7, 0, 0 } }, NotFound }, // children + GetTileDataAction{ { 7, 0, { 7, 0, 1 } }, NotFound }, // ... + GetTileDataAction{ { 7, 0, { 7, 1, 0 } }, NotFound }, // ... + GetTileDataAction{ { 7, 0, { 7, 1, 1 } }, NotFound }, // ... + GetTileDataAction{ { 5, 0, { 5, 0, 0 } }, Found }, // ascent + RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 4, 0, { 4, 0, 0 } }, Found }, // ... + RetainTileDataAction{ { 4, 0, { 4, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // ... + CreateTileDataAction{ { 3, 0, { 3, 0, 0 } } }, // + RetainTileDataAction{ { 3, 0, { 3, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // ... }), log); // Mark next level has having tried optional. log.clear(); - source.dataTiles[{ 3, { 3, 0, 0 } }]->triedOptional = true; + source.dataTiles[{ 3, 0, { 3, 0, 0 } }]->triedOptional = true; algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 6); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 6, { 6, 0, 0 } }, Found }, // ideal tile, not ready - RetainTileDataAction{ { 6, { 6, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 7, { 7, 0, 0 } }, NotFound }, // children - GetTileDataAction{ { 7, { 7, 0, 1 } }, NotFound }, // ... - GetTileDataAction{ { 7, { 7, 1, 0 } }, NotFound }, // ... - GetTileDataAction{ { 7, { 7, 1, 1 } }, NotFound }, // ... - GetTileDataAction{ { 5, { 5, 0, 0 } }, Found }, // ascent - RetainTileDataAction{ { 5, { 5, 0, 0 } }, Resource::Necessity::Optional }, // - GetTileDataAction{ { 4, { 4, 0, 0 } }, Found }, // ... - RetainTileDataAction{ { 4, { 4, 0, 0 } }, Resource::Necessity::Optional }, // - GetTileDataAction{ { 3, { 3, 0, 0 } }, Found }, // ... - RetainTileDataAction{ { 3, { 3, 0, 0 } }, Resource::Necessity::Optional }, // - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // ... - CreateTileDataAction{ { 2, { 2, 0, 0 } } }, // - RetainTileDataAction{ { 2, { 2, 0, 0 } }, Resource::Necessity::Optional }, // - GetTileDataAction{ { 1, { 1, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 0, { 0, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, Found }, // ideal tile, not ready + RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 7, 0, { 7, 0, 0 } }, NotFound }, // children + GetTileDataAction{ { 7, 0, { 7, 0, 1 } }, NotFound }, // ... + GetTileDataAction{ { 7, 0, { 7, 1, 0 } }, NotFound }, // ... + GetTileDataAction{ { 7, 0, { 7, 1, 1 } }, NotFound }, // ... + GetTileDataAction{ { 5, 0, { 5, 0, 0 } }, Found }, // ascent + RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 4, 0, { 4, 0, 0 } }, Found }, // ... + RetainTileDataAction{ { 4, 0, { 4, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, Found }, // ... + RetainTileDataAction{ { 3, 0, { 3, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // ... + CreateTileDataAction{ { 2, 0, { 2, 0, 0 } } }, // + RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // ... }), log); // Mark as found log.clear(); - auto tile_3_3_0_0 = source.dataTiles[{ 3, { 3, 0, 0 } }].get(); + auto tile_3_3_0_0 = source.dataTiles[{ 3, 0, { 3, 0, 0 } }].get(); tile_3_3_0_0->renderable = true; algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 6); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 6, { 6, 0, 0 } }, Found }, // ideal tile, not ready - RetainTileDataAction{ { 6, { 6, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 7, { 7, 0, 0 } }, NotFound }, // children - GetTileDataAction{ { 7, { 7, 0, 1 } }, NotFound }, // ... - GetTileDataAction{ { 7, { 7, 1, 0 } }, NotFound }, // ... - GetTileDataAction{ { 7, { 7, 1, 1 } }, NotFound }, // ... - GetTileDataAction{ { 5, { 5, 0, 0 } }, Found }, // ascent - RetainTileDataAction{ { 5, { 5, 0, 0 } }, Resource::Necessity::Optional }, // - GetTileDataAction{ { 4, { 4, 0, 0 } }, Found }, // ... - RetainTileDataAction{ { 4, { 4, 0, 0 } }, Resource::Necessity::Optional }, // - GetTileDataAction{ { 3, { 3, 0, 0 } }, Found }, // ... - RetainTileDataAction{ { 3, { 3, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, Found }, // ideal tile, not ready + RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 7, 0, { 7, 0, 0 } }, NotFound }, // children + GetTileDataAction{ { 7, 0, { 7, 0, 1 } }, NotFound }, // ... + GetTileDataAction{ { 7, 0, { 7, 1, 0 } }, NotFound }, // ... + GetTileDataAction{ { 7, 0, { 7, 1, 1 } }, NotFound }, // ... + GetTileDataAction{ { 5, 0, { 5, 0, 0 } }, Found }, // ascent + RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 4, 0, { 4, 0, 0 } }, Found }, // ... + RetainTileDataAction{ { 4, 0, { 4, 0, 0 } }, Resource::Necessity::Optional }, // + GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, Found }, // ... + RetainTileDataAction{ { 3, 0, { 3, 0, 0 } }, Resource::Necessity::Optional }, // RenderTileAction{ { 3, 0, 0 }, *tile_3_3_0_0 }, // }), log); @@ -1238,24 +1236,24 @@ TEST(UpdateRenderables, LoadRequiredIfIdealTileCantBeFound) { source.zoomRange.max = 6; source.idealTiles.emplace(UnwrappedTileID{ 6, 0, 0 }); - auto tile_6_6_0_0 = source.createTileData(OverscaledTileID{ 6, { 6, 0, 0 } }); + auto tile_6_6_0_0 = source.createTileData(OverscaledTileID{ 6, 0, { 6, 0, 0 } }); tile_6_6_0_0->triedOptional = true; tile_6_6_0_0->loaded = true; algorithm::updateRenderables(getTileData, createTileData, retainTileData, renderTile, source.idealTiles, source.zoomRange, 6); EXPECT_EQ(ActionLog({ - GetTileDataAction{ { 6, { 6, 0, 0 } }, Found }, // ideal tile, not found - RetainTileDataAction{ { 6, { 6, 0, 0 } }, Resource::Necessity::Required }, // - GetTileDataAction{ { 7, { 6, 0, 0 } }, NotFound }, // overzoomed child - GetTileDataAction{ { 5, { 5, 0, 0 } }, NotFound }, // ascent - CreateTileDataAction{ { 5, { 5, 0, 0 } } }, - RetainTileDataAction{ { 5, { 5, 0, 0 } }, Resource::Necessity::Required }, - GetTileDataAction{ { 4, { 4, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 3, { 3, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 2, { 2, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 1, { 1, 0, 0 } }, NotFound }, // ... - GetTileDataAction{ { 0, { 0, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, Found }, // ideal tile, not found + RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, Resource::Necessity::Required }, // + GetTileDataAction{ { 7, 0, { 6, 0, 0 } }, NotFound }, // overzoomed child + GetTileDataAction{ { 5, 0, { 5, 0, 0 } }, NotFound }, // ascent + CreateTileDataAction{ { 5, 0, { 5, 0, 0 } } }, + RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, Resource::Necessity::Required }, + GetTileDataAction{ { 4, 0, { 4, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ... + GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // ... }), log); } diff --git a/test/tile/tile_id.test.cpp b/test/tile/tile_id.test.cpp index 1ef19fea0e..2f328b78d7 100644 --- a/test/tile/tile_id.test.cpp +++ b/test/tile/tile_id.test.cpp @@ -127,17 +127,17 @@ TEST(TileID, Canonical) { TEST(TileID, Overscaled) { EXPECT_TRUE(OverscaledTileID(4, 2, 3) == OverscaledTileID(4, 2, 3)); EXPECT_FALSE(OverscaledTileID(4, 2, 3) != OverscaledTileID(4, 2, 3)); - EXPECT_TRUE(OverscaledTileID(4, { 4, 2, 3 }) == OverscaledTileID(4, 2, 3)); - EXPECT_FALSE(OverscaledTileID(4, { 4, 2, 3 }) != OverscaledTileID(4, 2, 3)); - EXPECT_TRUE(OverscaledTileID(4, 2, 3) == OverscaledTileID(4, { 4, 2, 3 })); - EXPECT_FALSE(OverscaledTileID(4, 2, 3) != OverscaledTileID(4, { 4, 2, 3 })); - - EXPECT_TRUE(OverscaledTileID(4, 2, 3) != OverscaledTileID(5, { 4, 2, 3 })); - EXPECT_FALSE(OverscaledTileID(4, 2, 3) == OverscaledTileID(5, { 4, 2, 3 })); - EXPECT_TRUE(OverscaledTileID(4, 2, 3) != OverscaledTileID(6, { 4, 2, 3 })); - EXPECT_FALSE(OverscaledTileID(4, 2, 3) == OverscaledTileID(6, { 4, 2, 3 })); - EXPECT_TRUE(OverscaledTileID(4, 2, 3) != OverscaledTileID(7, { 4, 2, 3 })); - EXPECT_FALSE(OverscaledTileID(4, 2, 3) == OverscaledTileID(7, { 4, 2, 3 })); + EXPECT_TRUE(OverscaledTileID(4, 0, { 4, 2, 3 }) == OverscaledTileID(4, 2, 3)); + EXPECT_FALSE(OverscaledTileID(4, 0, { 4, 2, 3 }) != OverscaledTileID(4, 2, 3)); + EXPECT_TRUE(OverscaledTileID(4, 2, 3) == OverscaledTileID(4, 0, { 4, 2, 3 })); + EXPECT_FALSE(OverscaledTileID(4, 2, 3) != OverscaledTileID(4, 0, { 4, 2, 3 })); + + EXPECT_TRUE(OverscaledTileID(4, 2, 3) != OverscaledTileID(5, 0, { 4, 2, 3 })); + EXPECT_FALSE(OverscaledTileID(4, 2, 3) == OverscaledTileID(5, 0, { 4, 2, 3 })); + EXPECT_TRUE(OverscaledTileID(4, 2, 3) != OverscaledTileID(6, 0, { 4, 2, 3 })); + EXPECT_FALSE(OverscaledTileID(4, 2, 3) == OverscaledTileID(6, 0, { 4, 2, 3 })); + EXPECT_TRUE(OverscaledTileID(4, 2, 3) != OverscaledTileID(7, 0, { 4, 2, 3 })); + EXPECT_FALSE(OverscaledTileID(4, 2, 3) == OverscaledTileID(7, 0, { 4, 2, 3 })); EXPECT_TRUE(OverscaledTileID(4, 2, 3) != OverscaledTileID(4, 2, 4)); EXPECT_FALSE(OverscaledTileID(4, 2, 3) == OverscaledTileID(4, 2, 4)); @@ -146,70 +146,70 @@ TEST(TileID, Overscaled) { EXPECT_TRUE(OverscaledTileID(4, 2, 3) != OverscaledTileID(5, 2, 3)); EXPECT_FALSE(OverscaledTileID(4, 2, 3) == OverscaledTileID(5, 2, 3)); - EXPECT_TRUE(OverscaledTileID(7, { 4, 2, 3 }) == OverscaledTileID(7, { 4, 2, 3 })); - EXPECT_FALSE(OverscaledTileID(7, { 4, 2, 3 }) != OverscaledTileID(7, { 4, 2, 3 })); + EXPECT_TRUE(OverscaledTileID(7, 0, { 4, 2, 3 }) == OverscaledTileID(7, 0, { 4, 2, 3 })); + EXPECT_FALSE(OverscaledTileID(7, 0, { 4, 2, 3 }) != OverscaledTileID(7, 0, { 4, 2, 3 })); EXPECT_FALSE(OverscaledTileID(4, 2, 3) < OverscaledTileID(4, 2, 3)); - EXPECT_TRUE(OverscaledTileID(4, 2, 3) < OverscaledTileID(5, { 4, 2, 3 })); - EXPECT_FALSE(OverscaledTileID(5, { 4, 2, 3 }) < OverscaledTileID(4, 2, 3)); - EXPECT_TRUE(OverscaledTileID(4, 2, 3) < OverscaledTileID(6, { 4, 2, 3 })); - EXPECT_FALSE(OverscaledTileID(6, { 4, 2, 3 }) < OverscaledTileID(4, 2, 3)); - EXPECT_TRUE(OverscaledTileID(4, 2, 3) < OverscaledTileID(7, { 4, 2, 3 })); - EXPECT_FALSE(OverscaledTileID(7, { 4, 2, 3 }) < OverscaledTileID(4, 2, 3)); - - EXPECT_EQ(8u, OverscaledTileID(7, { 4, 2, 3 }).overscaleFactor()); - EXPECT_EQ(4u, OverscaledTileID(6, { 4, 2, 3 }).overscaleFactor()); - EXPECT_EQ(2u, OverscaledTileID(5, { 4, 2, 3 }).overscaleFactor()); - EXPECT_EQ(1u, OverscaledTileID(4, { 4, 2, 3 }).overscaleFactor()); - EXPECT_EQ(2147483648u, OverscaledTileID(31, { 0, 0, 0 }).overscaleFactor()); - - EXPECT_EQ(OverscaledTileID(0, { 0, 0, 0 }), OverscaledTileID(4, 2, 3).scaledTo(0)); - EXPECT_EQ(OverscaledTileID(1, { 1, 0, 0 }), OverscaledTileID(4, 2, 3).scaledTo(1)); - EXPECT_EQ(OverscaledTileID(2, { 2, 0, 0 }), OverscaledTileID(4, 2, 3).scaledTo(2)); - EXPECT_EQ(OverscaledTileID(3, { 3, 1, 1 }), OverscaledTileID(4, 2, 3).scaledTo(3)); - EXPECT_EQ(OverscaledTileID(4, { 4, 2, 3 }), OverscaledTileID(4, 2, 3).scaledTo(4)); - EXPECT_EQ(OverscaledTileID(5, { 4, 2, 3 }), OverscaledTileID(4, 2, 3).scaledTo(5)); - EXPECT_EQ(OverscaledTileID(6, { 4, 2, 3 }), OverscaledTileID(4, 2, 3).scaledTo(6)); - EXPECT_EQ(OverscaledTileID(7, { 4, 2, 3 }), OverscaledTileID(4, 2, 3).scaledTo(7)); - EXPECT_EQ(OverscaledTileID(8, { 4, 2, 3 }), OverscaledTileID(4, 2, 3).scaledTo(8)); - EXPECT_EQ(OverscaledTileID(32, { 4, 2, 3 }), OverscaledTileID(4, 2, 3).scaledTo(32)); - - EXPECT_EQ(UnwrappedTileID(0, { 4, 2, 3 }), OverscaledTileID(4, 2, 3).unwrapTo(0)); - EXPECT_EQ(UnwrappedTileID(-1, { 4, 2, 3 }), OverscaledTileID(4, 2, 3).unwrapTo(-1)); - EXPECT_EQ(UnwrappedTileID(1, { 4, 2, 3 }), OverscaledTileID(4, 2, 3).unwrapTo(1)); - EXPECT_EQ(UnwrappedTileID(0, { 4, 2, 3 }), OverscaledTileID(5, { 4, 2, 3 }).unwrapTo(0)); - EXPECT_EQ(UnwrappedTileID(-1, { 4, 2, 3 }), OverscaledTileID(5, { 4, 2, 3 }).unwrapTo(-1)); - EXPECT_EQ(UnwrappedTileID(1, { 4, 2, 3 }), OverscaledTileID(5, { 4, 2, 3 }).unwrapTo(1)); + EXPECT_TRUE(OverscaledTileID(4, 2, 3) < OverscaledTileID(5, 0, { 4, 2, 3 })); + EXPECT_FALSE(OverscaledTileID(5, 0, { 4, 2, 3 }) < OverscaledTileID(4, 2, 3)); + EXPECT_TRUE(OverscaledTileID(4, 2, 3) < OverscaledTileID(6, 0, { 4, 2, 3 })); + EXPECT_FALSE(OverscaledTileID(6, 0, { 4, 2, 3 }) < OverscaledTileID(4, 2, 3)); + EXPECT_TRUE(OverscaledTileID(4, 2, 3) < OverscaledTileID(7,0, { 4, 2, 3 })); + EXPECT_FALSE(OverscaledTileID(7, 0, { 4, 2, 3 }) < OverscaledTileID(4, 2, 3)); + + EXPECT_EQ(8u, OverscaledTileID(7, 0, { 4, 2, 3 }).overscaleFactor()); + EXPECT_EQ(4u, OverscaledTileID(6, 0, { 4, 2, 3 }).overscaleFactor()); + EXPECT_EQ(2u, OverscaledTileID(5, 0, { 4, 2, 3 }).overscaleFactor()); + EXPECT_EQ(1u, OverscaledTileID(4, 0, { 4, 2, 3 }).overscaleFactor()); + EXPECT_EQ(2147483648u, OverscaledTileID(31, 0, { 0, 0, 0 }).overscaleFactor()); + + EXPECT_EQ(OverscaledTileID(0, 0, { 0, 0, 0 }), OverscaledTileID(4, 2, 3).scaledTo(0)); + EXPECT_EQ(OverscaledTileID(1, 0, { 1, 0, 0 }), OverscaledTileID(4, 2, 3).scaledTo(1)); + EXPECT_EQ(OverscaledTileID(2, 0, { 2, 0, 0 }), OverscaledTileID(4, 2, 3).scaledTo(2)); + EXPECT_EQ(OverscaledTileID(3, 0, { 3, 1, 1 }), OverscaledTileID(4, 2, 3).scaledTo(3)); + EXPECT_EQ(OverscaledTileID(4, 0, { 4, 2, 3 }), OverscaledTileID(4, 2, 3).scaledTo(4)); + EXPECT_EQ(OverscaledTileID(5, 0, { 4, 2, 3 }), OverscaledTileID(4, 2, 3).scaledTo(5)); + EXPECT_EQ(OverscaledTileID(6, 0, { 4, 2, 3 }), OverscaledTileID(4, 2, 3).scaledTo(6)); + EXPECT_EQ(OverscaledTileID(7, 0, { 4, 2, 3 }), OverscaledTileID(4, 2, 3).scaledTo(7)); + EXPECT_EQ(OverscaledTileID(8, 0, { 4, 2, 3 }), OverscaledTileID(4, 2, 3).scaledTo(8)); + EXPECT_EQ(OverscaledTileID(32, 0, { 4, 2, 3 }), OverscaledTileID(4, 2, 3).scaledTo(32)); + + EXPECT_EQ(UnwrappedTileID(0, { 4, 2, 3 }), OverscaledTileID(4, 2, 3).toUnwrapped()); + EXPECT_EQ(UnwrappedTileID(-1, { 4, 2, 3 }), OverscaledTileID(4, -1, { 4, 2, 3 }).toUnwrapped()); + EXPECT_EQ(UnwrappedTileID(1, { 4, 2, 3 }), OverscaledTileID(4, 1, { 4, 2, 3 }).toUnwrapped()); + EXPECT_EQ(UnwrappedTileID(0, { 4, 2, 3 }), OverscaledTileID(5, 0, { 4, 2, 3 }).toUnwrapped()); + EXPECT_EQ(UnwrappedTileID(-1, { 4, 2, 3 }), OverscaledTileID(5, -1, { 4, 2, 3 }).toUnwrapped()); + EXPECT_EQ(UnwrappedTileID(1, { 4, 2, 3 }), OverscaledTileID(5, 1, { 4, 2, 3 }).toUnwrapped()); EXPECT_FALSE(OverscaledTileID(2, 0, 0).isChildOf(OverscaledTileID(3, 1, 1))); EXPECT_FALSE(OverscaledTileID(3, 1, 1).isChildOf(OverscaledTileID(3, 1, 1))); EXPECT_TRUE(OverscaledTileID(4, 2, 3).isChildOf(OverscaledTileID(3, 1, 1))); - EXPECT_TRUE(OverscaledTileID(5, { 4, 2, 3 }).isChildOf(OverscaledTileID(3, 1, 1))); - EXPECT_TRUE(OverscaledTileID(6, { 4, 2, 3 }).isChildOf(OverscaledTileID(3, 1, 1))); - EXPECT_TRUE(OverscaledTileID(7, { 4, 2, 3 }).isChildOf(OverscaledTileID(3, 1, 1))); - - EXPECT_FALSE(OverscaledTileID(2, 0, 0).isChildOf(OverscaledTileID(5, { 4, 2, 3 }))); - EXPECT_FALSE(OverscaledTileID(3, 1, 1).isChildOf(OverscaledTileID(5, { 4, 2, 3 }))); - EXPECT_FALSE(OverscaledTileID(4, 2, 3).isChildOf(OverscaledTileID(5, { 4, 2, 3 }))); - EXPECT_FALSE(OverscaledTileID(5, { 4, 2, 3 }).isChildOf(OverscaledTileID(5, { 4, 2, 3 }))); - EXPECT_TRUE(OverscaledTileID(6, { 4, 2, 3 }).isChildOf(OverscaledTileID(5, { 4, 2, 3 }))); - EXPECT_TRUE(OverscaledTileID(7, { 4, 2, 3 }).isChildOf(OverscaledTileID(5, { 4, 2, 3 }))); - - EXPECT_FALSE(OverscaledTileID(2, 0, 0).isChildOf(OverscaledTileID(6, { 4, 2, 3 }))); - EXPECT_FALSE(OverscaledTileID(3, 1, 1).isChildOf(OverscaledTileID(6, { 4, 2, 3 }))); - EXPECT_FALSE(OverscaledTileID(4, 2, 3).isChildOf(OverscaledTileID(6, { 4, 2, 3 }))); - EXPECT_FALSE(OverscaledTileID(5, { 4, 2, 3 }).isChildOf(OverscaledTileID(6, { 4, 2, 3 }))); - EXPECT_FALSE(OverscaledTileID(6, { 4, 2, 3 }).isChildOf(OverscaledTileID(6, { 4, 2, 3 }))); - EXPECT_TRUE(OverscaledTileID(7, { 4, 2, 3 }).isChildOf(OverscaledTileID(6, { 4, 2, 3 }))); - - EXPECT_FALSE(OverscaledTileID(2, 0, 0).isChildOf(OverscaledTileID(5, { 4, 0, 0 }))); - EXPECT_FALSE(OverscaledTileID(3, 1, 1).isChildOf(OverscaledTileID(5, { 4, 0, 0 }))); - EXPECT_FALSE(OverscaledTileID(4, 2, 3).isChildOf(OverscaledTileID(5, { 4, 0, 0 }))); - EXPECT_FALSE(OverscaledTileID(5, { 4, 2, 3 }).isChildOf(OverscaledTileID(5, { 4, 0, 0 }))); - EXPECT_FALSE(OverscaledTileID(6, { 4, 2, 3 }).isChildOf(OverscaledTileID(5, { 4, 0, 0 }))); - EXPECT_FALSE(OverscaledTileID(7, { 4, 2, 3 }).isChildOf(OverscaledTileID(5, { 4, 0, 0 }))); - - EXPECT_FALSE(OverscaledTileID(4, { 4, 2, 3 }).isChildOf(OverscaledTileID(5, { 3, 1, 1 }))); + EXPECT_TRUE(OverscaledTileID(5, 0, { 4, 2, 3 }).isChildOf(OverscaledTileID(3, 1, 1))); + EXPECT_TRUE(OverscaledTileID(6, 0, { 4, 2, 3 }).isChildOf(OverscaledTileID(3, 1, 1))); + EXPECT_TRUE(OverscaledTileID(7, 0, { 4, 2, 3 }).isChildOf(OverscaledTileID(3, 1, 1))); + + EXPECT_FALSE(OverscaledTileID(2, 0, 0).isChildOf(OverscaledTileID(5, 0, { 4, 2, 3 }))); + EXPECT_FALSE(OverscaledTileID(3, 1, 1).isChildOf(OverscaledTileID(5, 0, { 4, 2, 3 }))); + EXPECT_FALSE(OverscaledTileID(4, 2, 3).isChildOf(OverscaledTileID(5, 0, { 4, 2, 3 }))); + EXPECT_FALSE(OverscaledTileID(5, 0, { 4, 2, 3 }).isChildOf(OverscaledTileID(5, 0, { 4, 2, 3 }))); + EXPECT_TRUE(OverscaledTileID(6, 0, { 4, 2, 3 }).isChildOf(OverscaledTileID(5, 0, { 4, 2, 3 }))); + EXPECT_TRUE(OverscaledTileID(7, 0, { 4, 2, 3 }).isChildOf(OverscaledTileID(5, 0, { 4, 2, 3 }))); + + EXPECT_FALSE(OverscaledTileID(2, 0, 0).isChildOf(OverscaledTileID(6, 0, { 4, 2, 3 }))); + EXPECT_FALSE(OverscaledTileID(3, 1, 1).isChildOf(OverscaledTileID(6, 0, { 4, 2, 3 }))); + EXPECT_FALSE(OverscaledTileID(4, 2, 3).isChildOf(OverscaledTileID(6, 0, { 4, 2, 3 }))); + EXPECT_FALSE(OverscaledTileID(5, 0, { 4, 2, 3 }).isChildOf(OverscaledTileID(6, 0, { 4, 2, 3 }))); + EXPECT_FALSE(OverscaledTileID(6, 0, { 4, 2, 3 }).isChildOf(OverscaledTileID(6, 0, { 4, 2, 3 }))); + EXPECT_TRUE(OverscaledTileID(7, 0, { 4, 2, 3 }).isChildOf(OverscaledTileID(6, 0, { 4, 2, 3 }))); + + EXPECT_FALSE(OverscaledTileID(2, 0, 0).isChildOf(OverscaledTileID(5, 0, { 4, 0, 0 }))); + EXPECT_FALSE(OverscaledTileID(3, 1, 1).isChildOf(OverscaledTileID(5, 0, { 4, 0, 0 }))); + EXPECT_FALSE(OverscaledTileID(4, 2, 3).isChildOf(OverscaledTileID(5, 0, { 4, 0, 0 }))); + EXPECT_FALSE(OverscaledTileID(5, 0, { 4, 2, 3 }).isChildOf(OverscaledTileID(5, 0, { 4, 0, 0 }))); + EXPECT_FALSE(OverscaledTileID(6, 0, { 4, 2, 3 }).isChildOf(OverscaledTileID(5, 0, { 4, 0, 0 }))); + EXPECT_FALSE(OverscaledTileID(7, 0, { 4, 2, 3 }).isChildOf(OverscaledTileID(5, 0, { 4, 0, 0 }))); + + EXPECT_FALSE(OverscaledTileID(4, 0, { 4, 2, 3 }).isChildOf(OverscaledTileID(5, 0, { 3, 1, 1 }))); } TEST(TileID, Unwrapped) { @@ -273,10 +273,10 @@ TEST(TileID, Unwrapped) { EXPECT_FALSE(UnwrappedTileID(0, 1, 0) < UnwrappedTileID(1, 0, 0)); EXPECT_FALSE(UnwrappedTileID(5, 3, 6) < UnwrappedTileID(5, 3, 6)); - EXPECT_EQ(OverscaledTileID(4, { 4, 2, 3 }), UnwrappedTileID(4, 2, 3).overscaleTo(4)); - EXPECT_EQ(OverscaledTileID(5, { 4, 2, 3 }), UnwrappedTileID(4, 2, 3).overscaleTo(5)); - EXPECT_EQ(OverscaledTileID(6, { 4, 2, 3 }), UnwrappedTileID(4, 2, 3).overscaleTo(6)); - EXPECT_EQ(OverscaledTileID(32, { 4, 2, 3 }), UnwrappedTileID(4, 2, 3).overscaleTo(32)); + EXPECT_EQ(OverscaledTileID(4, 0, { 4, 2, 3 }), UnwrappedTileID(4, 2, 3).overscaleTo(4)); + EXPECT_EQ(OverscaledTileID(5, 0, { 4, 2, 3 }), UnwrappedTileID(4, 2, 3).overscaleTo(5)); + EXPECT_EQ(OverscaledTileID(6, 0, { 4, 2, 3 }), UnwrappedTileID(4, 2, 3).overscaleTo(6)); + EXPECT_EQ(OverscaledTileID(32, 0, { 4, 2, 3 }), UnwrappedTileID(4, 2, 3).overscaleTo(32)); EXPECT_EQ(UnwrappedTileID(-1, { 1, 0, 0 }), UnwrappedTileID(1, -2, 0)); EXPECT_EQ(UnwrappedTileID(-1, { 1, 0, 1 }), UnwrappedTileID(1, -2, 1)); -- cgit v1.2.1 From a0e37fe35b1af9f607600d2e792e2ff56796af6e Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Tue, 6 Jun 2017 09:01:17 -0700 Subject: [core] Hold on to tile yStretch value for rendering old symbolBuckets while waiting for new ones. --- src/mbgl/tile/geometry_tile.cpp | 11 +++++++++-- src/mbgl/tile/geometry_tile.hpp | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp index ad5c2edd4c..1ee303b50f 100644 --- a/src/mbgl/tile/geometry_tile.cpp +++ b/src/mbgl/tile/geometry_tile.cpp @@ -42,7 +42,8 @@ GeometryTile::GeometryTile(const OverscaledTileID& id_, parameters.pixelRatio), glyphManager(parameters.glyphManager), imageManager(parameters.imageManager), - placementThrottler(Milliseconds(300), [this] { invokePlacement(); }) { + placementThrottler(Milliseconds(300), [this] { invokePlacement(); }), + lastYStretch(1.0f) { } GeometryTile::~GeometryTile() { @@ -143,6 +144,9 @@ void GeometryTile::onPlacement(PlacementResult result) { if (result.iconAtlasImage) { iconAtlasImage = std::move(*result.iconAtlasImage); } + if (collisionTile.get()) { + lastYStretch = collisionTile->yStretch; + } observer->onTileChanged(*this); } @@ -265,7 +269,10 @@ void GeometryTile::querySourceFeatures( } float GeometryTile::yStretch() const { - return collisionTile->yStretch; + // collisionTile gets reset in onLayout but we don't clear the symbolBuckets + // until a new placement result comes along, so keep the yStretch value in + // case we need to render them. + return lastYStretch; } } // namespace mbgl diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp index 3e2efe1093..943296e01b 100644 --- a/src/mbgl/tile/geometry_tile.hpp +++ b/src/mbgl/tile/geometry_tile.hpp @@ -122,6 +122,7 @@ private: std::unique_ptr collisionTile; util::Throttler placementThrottler; + float lastYStretch; public: optional glyphAtlasTexture; -- cgit v1.2.1 From 77734cfe1b9e77a0058fa3e0db79e3c20a264165 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Thu, 29 Jun 2017 12:04:13 -0400 Subject: [core] fix transformMat4 It used to overwrite values in the middle of the calculation which would cause problems when `out` and `a` were a reference to the same vector. --- src/mbgl/util/mat4.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/mbgl/util/mat4.cpp b/src/mbgl/util/mat4.cpp index d3d3617b7b..0ad0d371e5 100644 --- a/src/mbgl/util/mat4.cpp +++ b/src/mbgl/util/mat4.cpp @@ -336,10 +336,11 @@ void multiply(mat4& out, const mat4& a, const mat4& b) { } void transformMat4(vec4& out, const vec4& a, const mat4& m) { - out[0] = m[0] * a[0] + m[4] * a[1] + m[8] * a[2] + m[12] * a[3]; - out[1] = m[1] * a[0] + m[5] * a[1] + m[9] * a[2] + m[13] * a[3]; - out[2] = m[2] * a[0] + m[6] * a[1] + m[10] * a[2] + m[14] * a[3]; - out[3] = m[3] * a[0] + m[7] * a[1] + m[11] * a[2] + m[15] * a[3]; + double x = a[0], y = a[1], z = a[2], w = a[3]; + out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w; + out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w; + out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w; + out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w; } } // namespace matrix -- cgit v1.2.1 From e514138b691615be24f484986c40f486223df82a Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Fri, 16 Jun 2017 10:42:33 -0400 Subject: [core] improve legibility of labels that follow lines port https://github.com/mapbox/mapbox-gl-js/pull/4781 This improves legibility of labels that follow lines in pitched views. The previous approach used the limited information in the shader to calculate put the glyph in approximatelyright place. The new approach does this more accurately by doing it on the cpu where we have access to the entire line geometry. --- cmake/core-files.cmake | 2 + mapbox-gl-js | 2 +- src/mbgl/gl/context.cpp | 9 +- src/mbgl/gl/context.hpp | 13 +- src/mbgl/gl/types.hpp | 6 + src/mbgl/layout/symbol_instance.cpp | 23 +- src/mbgl/layout/symbol_instance.hpp | 9 +- src/mbgl/layout/symbol_layout.cpp | 98 ++++---- src/mbgl/layout/symbol_layout.hpp | 9 +- src/mbgl/layout/symbol_projection.cpp | 266 ++++++++++++++++++++ src/mbgl/layout/symbol_projection.hpp | 25 ++ src/mbgl/programs/attributes.hpp | 1 + src/mbgl/programs/symbol_program.cpp | 39 ++- src/mbgl/programs/symbol_program.hpp | 203 ++++++--------- src/mbgl/programs/uniforms.hpp | 1 - src/mbgl/renderer/buckets/symbol_bucket.cpp | 4 +- src/mbgl/renderer/buckets/symbol_bucket.hpp | 24 ++ src/mbgl/renderer/frame_history.cpp | 4 + src/mbgl/renderer/frame_history.hpp | 1 + src/mbgl/renderer/layers/render_symbol_layer.cpp | 2 + src/mbgl/renderer/layers/render_symbol_layer.hpp | 1 + src/mbgl/renderer/painters/painter_symbol.cpp | 29 ++- src/mbgl/renderer/render_tile.cpp | 27 +- src/mbgl/renderer/render_tile.hpp | 4 +- src/mbgl/shaders/collision_box.cpp | 2 +- src/mbgl/shaders/symbol_icon.cpp | 70 +++--- src/mbgl/shaders/symbol_sdf.cpp | 208 +++++---------- src/mbgl/text/quads.cpp | 307 ++++------------------- src/mbgl/text/quads.hpp | 31 +-- src/mbgl/text/shaping.cpp | 14 +- test/programs/symbol_program.test.cpp | 4 - test/text/quads.test.cpp | 34 +-- 32 files changed, 729 insertions(+), 743 deletions(-) create mode 100644 src/mbgl/layout/symbol_projection.cpp create mode 100644 src/mbgl/layout/symbol_projection.hpp diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index fc476fcd15..d912392e15 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -97,6 +97,8 @@ set(MBGL_CORE_FILES src/mbgl/layout/symbol_instance.hpp src/mbgl/layout/symbol_layout.cpp src/mbgl/layout/symbol_layout.hpp + src/mbgl/layout/symbol_projection.cpp + src/mbgl/layout/symbol_projection.hpp # map include/mbgl/map/backend.hpp diff --git a/mapbox-gl-js b/mapbox-gl-js index 3dd4116554..4fa52b9e3a 160000 --- a/mapbox-gl-js +++ b/mapbox-gl-js @@ -1 +1 @@ -Subproject commit 3dd4116554694559e3df2667ed91670438e8d1ae +Subproject commit 4fa52b9e3a0732c9a63f7d4221661a300c15c98f diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index 1b4d6fbcb7..3508b92a79 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -164,15 +164,20 @@ void Context::verifyProgramLinkage(ProgramID program_) { throw std::runtime_error("program failed to link"); } -UniqueBuffer Context::createVertexBuffer(const void* data, std::size_t size) { +UniqueBuffer Context::createVertexBuffer(const void* data, std::size_t size, const BufferUsageType usage) { BufferID id = 0; MBGL_CHECK_ERROR(glGenBuffers(1, &id)); UniqueBuffer result { std::move(id), { this } }; vertexBuffer = result; - MBGL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW)); + MBGL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, size, data, static_cast(usage))); return result; } +void Context::updateVertexBuffer(UniqueBuffer& buffer, const void* data, std::size_t size) { + vertexBuffer = buffer; + MBGL_CHECK_ERROR(glBufferSubData(GL_ARRAY_BUFFER, 0, size, data)); +} + UniqueBuffer Context::createIndexBuffer(const void* data, std::size_t size) { BufferID id = 0; MBGL_CHECK_ERROR(glGenBuffers(1, &id)); diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index 4f5b4c797c..f1f0ac7f8a 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -65,13 +65,19 @@ public: optional> getBinaryProgram(ProgramID) const; template - VertexBuffer createVertexBuffer(VertexVector&& v) { + VertexBuffer createVertexBuffer(VertexVector&& v, const BufferUsageType usage=BufferUsageType::StaticDraw) { return VertexBuffer { v.vertexSize(), - createVertexBuffer(v.data(), v.byteSize()) + createVertexBuffer(v.data(), v.byteSize(), usage) }; } + template + void updateVertexBuffer(VertexBuffer& buffer, VertexVector&& v) { + assert(v.vertexSize() == buffer.vertexCount); + updateVertexBuffer(buffer.buffer, v.data(), v.byteSize()); + } + template IndexBuffer createIndexBuffer(IndexVector&& v) { return IndexBuffer { @@ -239,7 +245,8 @@ private: State pointSize; #endif // MBGL_USE_GLES2 - UniqueBuffer createVertexBuffer(const void* data, std::size_t size); + UniqueBuffer createVertexBuffer(const void* data, std::size_t size, const BufferUsageType usage); + void updateVertexBuffer(UniqueBuffer& buffer, const void* data, std::size_t size); UniqueBuffer createIndexBuffer(const void* data, std::size_t size); UniqueTexture createTexture(Size size, const void* data, TextureFormat, TextureUnit); void updateTexture(TextureID, Size size, const void* data, TextureFormat, TextureUnit); diff --git a/src/mbgl/gl/types.hpp b/src/mbgl/gl/types.hpp index 74ce67fba6..8997fcbf31 100644 --- a/src/mbgl/gl/types.hpp +++ b/src/mbgl/gl/types.hpp @@ -96,5 +96,11 @@ enum class UniformDataType : uint32_t { SamplerCube = 0x8B60, }; +enum class BufferUsageType : uint32_t { + StreamDraw = 0x88E0, + StaticDraw = 0x88E4, + DynamicDraw = 0x88E8, +}; + } // namespace gl } // namespace mbgl diff --git a/src/mbgl/layout/symbol_instance.cpp b/src/mbgl/layout/symbol_instance.cpp index ffb70c7ca2..02fb800df6 100644 --- a/src/mbgl/layout/symbol_instance.cpp +++ b/src/mbgl/layout/symbol_instance.cpp @@ -5,8 +5,8 @@ namespace mbgl { using namespace style; -SymbolInstance::SymbolInstance(Anchor& anchor, - const GeometryCoordinates& line, +SymbolInstance::SymbolInstance(Anchor& anchor_, + GeometryCoordinates line_, const std::pair& shapedTextOrientations, optional shapedIcon, const SymbolLayoutProperties::Evaluated& layout, @@ -16,33 +16,38 @@ SymbolInstance::SymbolInstance(Anchor& anchor, const float textBoxScale, const float textPadding, const SymbolPlacementType textPlacement, + const std::array textOffset_, const float iconBoxScale, const float iconPadding, const SymbolPlacementType iconPlacement, + const std::array iconOffset_, const GlyphPositionMap& positions, const IndexedSubfeature& indexedFeature, const std::size_t featureIndex_) : - point(anchor.point), + anchor(anchor_), + line(line_), index(index_), hasText(shapedTextOrientations.first || shapedTextOrientations.second), hasIcon(shapedIcon), // Create the collision features that will be used to check whether this symbol instance can be placed - textCollisionFeature(line, anchor, shapedTextOrientations.second ?: shapedTextOrientations.first, textBoxScale, textPadding, textPlacement, indexedFeature), - iconCollisionFeature(line, anchor, shapedIcon, iconBoxScale, iconPadding, iconPlacement, indexedFeature), - featureIndex(featureIndex_) { + textCollisionFeature(line_, anchor, shapedTextOrientations.second ?: shapedTextOrientations.first, textBoxScale, textPadding, textPlacement, indexedFeature), + iconCollisionFeature(line_, anchor, shapedIcon, iconBoxScale, iconPadding, iconPlacement, indexedFeature), + featureIndex(featureIndex_), + textOffset(textOffset_), + iconOffset(iconOffset_) { // Create the quads used for rendering the icon and glyphs. if (addToBuffers) { if (shapedIcon) { - iconQuad = getIconQuad(anchor, *shapedIcon, line, layout, layoutTextSize, iconPlacement, shapedTextOrientations.first); + iconQuad = getIconQuad(*shapedIcon, layout, layoutTextSize, shapedTextOrientations.first); } if (shapedTextOrientations.first) { - auto quads = getGlyphQuads(anchor, shapedTextOrientations.first, textBoxScale, line, layout, textPlacement, positions); + auto quads = getGlyphQuads(shapedTextOrientations.first, layout, textPlacement, positions); glyphQuads.insert(glyphQuads.end(), quads.begin(), quads.end()); } if (shapedTextOrientations.second) { - auto quads = getGlyphQuads(anchor, shapedTextOrientations.second, textBoxScale, line, layout, textPlacement, positions); + auto quads = getGlyphQuads(shapedTextOrientations.second, layout, textPlacement, positions); glyphQuads.insert(glyphQuads.end(), quads.begin(), quads.end()); } } diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp index f199d929df..f1df416cd1 100644 --- a/src/mbgl/layout/symbol_instance.hpp +++ b/src/mbgl/layout/symbol_instance.hpp @@ -13,7 +13,7 @@ class IndexedSubfeature; class SymbolInstance { public: SymbolInstance(Anchor& anchor, - const GeometryCoordinates& line, + GeometryCoordinates line, const std::pair& shapedTextOrientations, optional shapedIcon, const style::SymbolLayoutProperties::Evaluated&, @@ -23,14 +23,17 @@ public: const float textBoxScale, const float textPadding, style::SymbolPlacementType textPlacement, + const std::array textOffset, const float iconBoxScale, const float iconPadding, style::SymbolPlacementType iconPlacement, + const std::array iconOffset, const GlyphPositionMap&, const IndexedSubfeature&, const std::size_t featureIndex); - Point point; + Anchor anchor; + GeometryCoordinates line; uint32_t index; bool hasText; bool hasIcon; @@ -40,6 +43,8 @@ public: CollisionFeature iconCollisionFeature; WritingModeType writingModes; std::size_t featureIndex; + std::array textOffset; + std::array iconOffset; }; } // namespace mbgl diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index a664957489..e308da618f 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -305,6 +305,8 @@ void SymbolLayout::addFeature(const std::size_t index, const float layoutTextSize = layout.evaluate(zoom + 1, feature); const float layoutIconSize = layout.evaluate(zoom + 1, feature); + const std::array textOffset = layout.evaluate(zoom, feature); + const std::array iconOffset = layout.evaluate(zoom, feature); // To reduce the number of labels that jump around when zooming we need // to use a text-size value that is the same for all zoom levels. @@ -355,8 +357,8 @@ void SymbolLayout::addFeature(const std::size_t index, symbolInstances.emplace_back(anchor, line, shapedTextOrientations, shapedIcon, layout.evaluate(zoom, feature), layoutTextSize, addToBuffers, symbolInstances.size(), - textBoxScale, textPadding, textPlacement, - iconBoxScale, iconPadding, iconPlacement, + textBoxScale, textPadding, textPlacement, textOffset, + iconBoxScale, iconPadding, iconPlacement, iconOffset, glyphPositionMap, indexedFeature, index); }; @@ -455,8 +457,8 @@ std::unique_ptr SymbolLayout::place(CollisionTile& collisionTile) const float cos = std::cos(collisionTile.config.angle); std::sort(symbolInstances.begin(), symbolInstances.end(), [sin, cos](SymbolInstance &a, SymbolInstance &b) { - const int32_t aRotated = sin * a.point.x + cos * a.point.y; - const int32_t bRotated = sin * b.point.x + cos * b.point.y; + const int32_t aRotated = sin * a.anchor.point.x + cos * a.anchor.point.y; + const int32_t bRotated = sin * b.anchor.point.x + cos * b.anchor.point.y; return aRotated != bRotated ? aRotated < bRotated : a.index > b.index; @@ -501,10 +503,21 @@ std::unique_ptr SymbolLayout::place(CollisionTile& collisionTile) const float placementZoom = util::max(util::log2(glyphScale) + zoom, 0.0f); collisionTile.insertFeature(symbolInstance.textCollisionFeature, glyphScale, layout.get()); if (glyphScale < collisionTile.maxScale) { + + const float labelAngle = std::fmod((symbolInstance.anchor.angle + collisionTile.config.angle) + 2 * M_PI, 2 * M_PI); + const bool inVerticalRange = ( + (labelAngle > M_PI * 1.0 / 4.0 && labelAngle <= M_PI * 3.0 / 4) || + (labelAngle > M_PI * 5.0 / 4.0 && labelAngle <= M_PI * 7.0 / 4)); + const bool useVerticalMode = symbolInstance.writingModes & WritingModeType::Vertical && inVerticalRange; + + const Range sizeData = bucket->textSizeBinder->getVertexSizeData(feature); + bucket->text.placedSymbols.emplace_back(symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, sizeData.max, + symbolInstance.textOffset, placementZoom, useVerticalMode, symbolInstance.line); + for (const auto& symbol : symbolInstance.glyphQuads) { addSymbol( - bucket->text, *bucket->textSizeBinder, symbol, feature, placementZoom, - keepUpright, textPlacement, collisionTile.config.angle, symbolInstance.writingModes, symbolInstance.point); + bucket->text, sizeData, symbol, placementZoom, + keepUpright, textPlacement, symbolInstance.anchor, bucket->text.placedSymbols.back()); } } } @@ -513,9 +526,12 @@ std::unique_ptr SymbolLayout::place(CollisionTile& collisionTile) const float placementZoom = util::max(util::log2(iconScale) + zoom, 0.0f); collisionTile.insertFeature(symbolInstance.iconCollisionFeature, iconScale, layout.get()); if (iconScale < collisionTile.maxScale && symbolInstance.iconQuad) { + const Range sizeData = bucket->iconSizeBinder->getVertexSizeData(feature); + bucket->icon.placedSymbols.emplace_back(symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, sizeData.max, + symbolInstance.iconOffset, placementZoom, false, symbolInstance.line); addSymbol( - bucket->icon, *bucket->iconSizeBinder, *symbolInstance.iconQuad, feature, placementZoom, - keepUpright, iconPlacement, collisionTile.config.angle, symbolInstance.writingModes, symbolInstance.point); + bucket->icon, sizeData, *symbolInstance.iconQuad, placementZoom, + keepUpright, iconPlacement, symbolInstance.anchor, bucket->icon.placedSymbols.back()); } } @@ -534,15 +550,13 @@ std::unique_ptr SymbolLayout::place(CollisionTile& collisionTile) template void SymbolLayout::addSymbol(Buffer& buffer, - SymbolSizeBinder& sizeBinder, + const Range sizeData, const SymbolQuad& symbol, - const SymbolFeature& feature, const float placementZoom, const bool keepUpright, const style::SymbolPlacementType placement, - const float placementAngle, - const WritingModeType writingModes, - const Point labelAnchor) { + const Anchor& labelAnchor, + PlacedSymbol& placedSymbol) { constexpr const uint16_t vertexLength = 4; const auto &tl = symbol.tl; @@ -551,30 +565,9 @@ void SymbolLayout::addSymbol(Buffer& buffer, const auto &br = symbol.br; const auto &tex = symbol.tex; - float minZoom = util::max(zoom + util::log2(symbol.minScale), placementZoom); - float maxZoom = util::min(zoom + util::log2(symbol.maxScale), util::MAX_ZOOM_F); - const auto &anchorPoint = symbol.anchorPoint; - - // drop incorrectly oriented glyphs - const float a = std::fmod(symbol.anchorAngle + placementAngle + M_PI, M_PI * 2); - if (writingModes & WritingModeType::Vertical) { - if (placement == style::SymbolPlacementType::Line && symbol.writingMode == WritingModeType::Vertical) { - if (keepUpright && placement == style::SymbolPlacementType::Line && (a <= (M_PI * 5 / 4) || a > (M_PI * 7 / 4))) - return; - } else if (keepUpright && placement == style::SymbolPlacementType::Line && (a <= (M_PI * 3 / 4) || a > (M_PI * 5 / 4))) - return; - } else if (keepUpright && placement == style::SymbolPlacementType::Line && - (a <= M_PI / 2 || a > M_PI * 3 / 2)) { - return; - } - - if (maxZoom <= minZoom) - return; - - // Lower min zoom so that while fading out the label - // it can be shown outside of collision-free zoom levels - if (minZoom == placementZoom) { - minZoom = 0; + if (placement == style::SymbolPlacementType::Line && keepUpright) { + // drop incorrectly oriented glyphs + if ((symbol.writingMode == WritingModeType::Vertical) != placedSymbol.useVerticalMode) return; } if (buffer.segments.empty() || buffer.segments.back().vertexLength + vertexLength > std::numeric_limits::max()) { @@ -587,20 +580,17 @@ void SymbolLayout::addSymbol(Buffer& buffer, assert(segment.vertexLength <= std::numeric_limits::max()); uint16_t index = segment.vertexLength; - // Encode angle of glyph - uint8_t glyphAngle = std::round((symbol.glyphAngle / (M_PI * 2)) * 256); - // coordinates (2 triangles) - buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(anchorPoint, tl, labelAnchor, tex.x, tex.y, - minZoom, maxZoom, placementZoom, glyphAngle)); - buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(anchorPoint, tr, labelAnchor, tex.x + tex.w, tex.y, - minZoom, maxZoom, placementZoom, glyphAngle)); - buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(anchorPoint, bl, labelAnchor, tex.x, tex.y + tex.h, - minZoom, maxZoom, placementZoom, glyphAngle)); - buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(anchorPoint, br, labelAnchor, tex.x + tex.w, tex.y + tex.h, - minZoom, maxZoom, placementZoom, glyphAngle)); + buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(labelAnchor.point, tl, symbol.glyphOffset.y, tex.x, tex.y, sizeData)); + buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(labelAnchor.point, tr, symbol.glyphOffset.y, tex.x + tex.w, tex.y, sizeData)); + buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(labelAnchor.point, bl, symbol.glyphOffset.y, tex.x, tex.y + tex.h, sizeData)); + buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(labelAnchor.point, br, symbol.glyphOffset.y, tex.x + tex.w, tex.y + tex.h, sizeData)); - sizeBinder.populateVertexVector(feature); + auto dynamicVertex = SymbolDynamicLayoutAttributes::vertex(labelAnchor.point, 0, placementZoom); + buffer.dynamicVertices.emplace_back(dynamicVertex); + buffer.dynamicVertices.emplace_back(dynamicVertex); + buffer.dynamicVertices.emplace_back(dynamicVertex); + buffer.dynamicVertices.emplace_back(dynamicVertex); // add the two triangles, referencing the four coordinates we just inserted. buffer.triangles.emplace_back(index + 0, index + 1, index + 2); @@ -608,6 +598,8 @@ void SymbolLayout::addSymbol(Buffer& buffer, segment.vertexLength += vertexLength; segment.indexLength += 6; + + placedSymbol.glyphOffsets.push_back(symbol.glyphOffset.x); } void SymbolLayout::addToDebugBuffers(CollisionTile& collisionTile, SymbolBucket& bucket) { @@ -647,10 +639,10 @@ void SymbolLayout::addToDebugBuffers(CollisionTile& collisionTile, SymbolBucket& auto& segment = collisionBox.segments.back(); uint16_t index = segment.vertexLength; - collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.point, tl, maxZoom, placementZoom)); - collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.point, tr, maxZoom, placementZoom)); - collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.point, br, maxZoom, placementZoom)); - collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.point, bl, maxZoom, placementZoom)); + collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.anchor.point, tl, maxZoom, placementZoom)); + collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.anchor.point, tr, maxZoom, placementZoom)); + collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.anchor.point, br, maxZoom, placementZoom)); + collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.anchor.point, bl, maxZoom, placementZoom)); collisionBox.lines.emplace_back(index + 0, index + 1); collisionBox.lines.emplace_back(index + 1, index + 2); diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp index 5dc0f3eb76..90f5b3c91d 100644 --- a/src/mbgl/layout/symbol_layout.hpp +++ b/src/mbgl/layout/symbol_layout.hpp @@ -20,6 +20,7 @@ class CollisionTile; class SymbolBucket; class Anchor; class RenderLayer; +class PlacedSymbol; namespace style { class Filter; @@ -58,15 +59,13 @@ private: // Adds placed items to the buffer. template void addSymbol(Buffer&, - SymbolSizeBinder& sizeBinder, + const Range sizeData, const SymbolQuad&, - const SymbolFeature& feature, float scale, const bool keepUpright, const style::SymbolPlacementType, - const float placementAngle, - WritingModeType writingModes, - const Point labelAnchor); + const Anchor& labelAnchor, + PlacedSymbol& placedSymbol); // Stores the layer so that we can hold on to GeometryTileFeature instances in SymbolFeature, // which may reference data from this object. diff --git a/src/mbgl/layout/symbol_projection.cpp b/src/mbgl/layout/symbol_projection.cpp new file mode 100644 index 0000000000..99555f7997 --- /dev/null +++ b/src/mbgl/layout/symbol_projection.cpp @@ -0,0 +1,266 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mbgl { + + /* + * # Overview of coordinate spaces + * + * ## Tile coordinate spaces + * Each label has an anchor. Some labels have corresponding line geometries. + * The points for both anchors and lines are stored in tile units. Each tile has it's own + * coordinate space going from (0, 0) at the top left to (EXTENT, EXTENT) at the bottom right. + * + * ## GL coordinate space + * At the end of everything, the vertex shader needs to produce a position in GL coordinate space, + * which is (-1, 1) at the top left and (1, -1) in the bottom right. + * + * ## Map pixel coordinate spaces + * Each tile has a pixel coordinate space. It's just the tile units scaled so that one unit is + * whatever counts as 1 pixel at the current zoom. + * This space is used for pitch-alignment=map, rotation-alignment=map + * + * ## Rotated map pixel coordinate spaces + * Like the above, but rotated so axis of the space are aligned with the viewport instead of the tile. + * This space is used for pitch-alignment=map, rotation-alignment=viewport + * + * ## Viewport pixel coordinate space + * (0, 0) is at the top left of the canvas and (pixelWidth, pixelHeight) is at the bottom right corner + * of the canvas. This space is used for pitch-alignment=viewport + * + * + * # Vertex projection + * It goes roughly like this: + * 1. project the anchor and line from tile units into the correct label coordinate space + * - map pixel space pitch-alignment=map rotation-alignment=map + * - rotated map pixel space pitch-alignment=map rotation-alignment=viewport + * - viewport pixel space pitch-alignment=viewport rotation-alignment=* + * 2. if the label follows a line, find the point along the line that is the correct distance from the anchor. + * 3. add the glyph's corner offset to the point from step 3 + * 4. convert from the label coordinate space to gl coordinates + * + * For horizontal labels we want to do step 1 in the shader for performance reasons (no cpu work). + * This is what `u_label_plane_matrix` is used for. + * For labels aligned with lines we have to steps 1 and 2 on the cpu since we need access to the line geometry. + * This is what `updateLineLabels(...)` does. + * Since the conversion is handled on the cpu we just set `u_label_plane_matrix` to an identity matrix. + * + * Steps 3 and 4 are done in the shaders for all labels. + */ + + /* + * Returns a matrix for converting from tile units to the correct label coordinate space. + */ + mat4 getLabelPlaneMatrix(const mat4& posMatrix, const bool pitchWithMap, const bool rotateWithMap, const TransformState& state, const float pixelsToTileUnits) { + mat4 m; + matrix::identity(m); + if (pitchWithMap) { + matrix::scale(m, m, 1 / pixelsToTileUnits, 1 / pixelsToTileUnits, 1); + if (!rotateWithMap) { + matrix::rotate_z(m, m, state.getAngle()); + } + } else { + matrix::scale(m, m, state.getSize().width / 2.0, -(state.getSize().height / 2.0), 1.0); + matrix::translate(m, m, 1, -1, 0); + matrix::multiply(m, m, posMatrix); + } + return m; + } + + /* + * Returns a matrix for converting from the correct label coordinate space to gl coords. + */ + mat4 getGlCoordMatrix(const mat4& posMatrix, const bool pitchWithMap, const bool rotateWithMap, const TransformState& state, const float pixelsToTileUnits) { + mat4 m; + matrix::identity(m); + if (pitchWithMap) { + matrix::multiply(m, m, posMatrix); + matrix::scale(m, m, pixelsToTileUnits, pixelsToTileUnits, 1); + if (!rotateWithMap) { + matrix::rotate_z(m, m, -state.getAngle()); + } + } else { + matrix::scale(m, m, 1, -1, 1); + matrix::translate(m, m, -1, -1, 0); + matrix::scale(m, m, 2.0 / state.getSize().width, 2.0 / state.getSize().height, 1.0); + } + return m; + } + + + Point project(const Point& point, const mat4& matrix) { + vec4 pos = {{ point.x, point.y, 0, 1 }}; + matrix::transformMat4(pos, pos, matrix); + return { static_cast(pos[0] / pos[3]), static_cast(pos[1] / pos[3]) }; + } + + float evaluateSizeForFeature(const ZoomEvaluatedSize& zoomEvaluatedSize, const PlacedSymbol& placedSymbol) { + if (zoomEvaluatedSize.isFeatureConstant) { + return zoomEvaluatedSize.size; + } else { + if (zoomEvaluatedSize.isZoomConstant) { + return placedSymbol.lowerSize; + } else { + return placedSymbol.lowerSize + zoomEvaluatedSize.sizeT * (placedSymbol.upperSize - placedSymbol.lowerSize); + } + } + } + + bool isVisible(const vec4& anchorPos, const float placementZoom, const std::array& clippingBuffer, const FrameHistory& frameHistory) { + const float x = anchorPos[0] / anchorPos[3]; + const float y = anchorPos[1] / anchorPos[3]; + const bool inPaddedViewport = ( + x >= -clippingBuffer[0] && + x <= clippingBuffer[0] && + y >= -clippingBuffer[1] && + y <= clippingBuffer[1]); + return inPaddedViewport && frameHistory.isVisible(placementZoom); + } + + void addDynamicAttributes(const Point& anchorPoint, const float angle, const float placementZoom, + gl::VertexVector& dynamicVertexArray) { + auto dynamicVertex = SymbolDynamicLayoutAttributes::vertex(anchorPoint, angle, placementZoom); + dynamicVertexArray.emplace_back(dynamicVertex); + dynamicVertexArray.emplace_back(dynamicVertex); + dynamicVertexArray.emplace_back(dynamicVertex); + dynamicVertexArray.emplace_back(dynamicVertex); + } + + void hideGlyphs(size_t numGlyphs, gl::VertexVector& dynamicVertexArray) { + const Point offscreenPoint = { -INFINITY, -INFINITY }; + for (size_t i = 0; i < numGlyphs; i++) { + addDynamicAttributes(offscreenPoint, 0, 25, dynamicVertexArray); + } + } + + struct PlacedGlyph { + PlacedGlyph(Point point_, float angle_) : point(point_), angle(angle_) {} + Point point; + float angle; + }; + + optional placeGlyphAlongLine(const float offsetX, const float lineOffsetX, const float lineOffsetY, const bool flip, + Point anchorPoint, const uint16_t anchorSegment, const GeometryCoordinates& line, const mat4& labelPlaneMatrix) { + + const float combinedOffsetX = flip ? + offsetX - lineOffsetX : + offsetX + lineOffsetX; + + int16_t dir = combinedOffsetX > 0 ? 1 : -1; + + float angle = 0.0; + if (flip) { + // The label needs to be flipped to keep text upright. + // Iterate in the reverse direction. + dir *= -1; + angle = M_PI; + } + + if (dir < 0) angle += M_PI; + + int32_t currentIndex = dir > 0 ? anchorSegment : anchorSegment + 1; + + Point current = anchorPoint; + Point prev = anchorPoint; + float distanceToPrev = 0.0; + float currentSegmentDistance = 0.0; + const float absOffsetX = std::abs(combinedOffsetX); + + while (distanceToPrev + currentSegmentDistance <= absOffsetX) { + currentIndex += dir; + + // offset does not fit on the projected line + if (currentIndex < 0 || currentIndex >= static_cast(line.size())) return {}; + + prev = current; + current = project(convertPoint(line.at(currentIndex)), labelPlaneMatrix); + + distanceToPrev += currentSegmentDistance; + currentSegmentDistance = util::dist(prev, current); + } + + // The point is on the current segment. Interpolate to find it. + const float segmentInterpolationT = (absOffsetX - distanceToPrev) / currentSegmentDistance; + const Point prevToCurrent = current - prev; + Point p = (prevToCurrent * segmentInterpolationT) + prev; + + // offset the point from the line to text-offset and icon-offset + p += util::perp(prevToCurrent) * static_cast(lineOffsetY * dir / util::mag(prevToCurrent)); + + const float segmentAngle = angle + std::atan2(current.y - prev.y, current.x - prev.x); + + return {{ p, segmentAngle }}; + } + + void placeGlyphsAlongLine(const PlacedSymbol& symbol, const float fontSize, const bool flip, const mat4& labelPlaneMatrix, + gl::VertexVector& dynamicVertexArray) { + const float fontScale = fontSize / 24.0; + const float lineOffsetX = symbol.lineOffset[0] * fontSize; + const float lineOffsetY = symbol.lineOffset[1] * fontSize; + + const Point anchorPoint = project(symbol.anchorPoint, labelPlaneMatrix); + + std::vector placedGlyphs; + for (auto glyphOffsetX : symbol.glyphOffsets) { + auto placedGlyph = placeGlyphAlongLine(glyphOffsetX * fontScale, lineOffsetX, lineOffsetY, flip, anchorPoint, symbol.segment, symbol.line, labelPlaneMatrix); + if (placedGlyph) { + placedGlyphs.push_back(*placedGlyph); + } else { + hideGlyphs(symbol.glyphOffsets.size(), dynamicVertexArray); + return; + } + } + + for (auto& placedGlyph : placedGlyphs) { + addDynamicAttributes(placedGlyph.point, placedGlyph.angle, symbol.placementZoom, dynamicVertexArray); + } + } + + void reprojectLineLabels(gl::VertexVector& dynamicVertexArray, const std::vector& placedSymbols, + const mat4& posMatrix, const style::SymbolPropertyValues& values, + const RenderTile& tile, const SymbolSizeBinder& sizeBinder, const TransformState& state, const FrameHistory& frameHistory) { + + const ZoomEvaluatedSize partiallyEvaluatedSize = sizeBinder.evaluateForZoom(state.getZoom()); + + const std::array clippingBuffer = {{ 256.0 / state.getSize().width * 2.0 + 1.0, 256.0 / state.getSize().height * 2.0 + 1.0 }}; + + const mat4 labelPlaneMatrix = getLabelPlaneMatrix(posMatrix, values.pitchAlignment == style::AlignmentType::Map, + values.rotationAlignment == style::AlignmentType::Map, state, tile.id.pixelsToTileUnits(1, state.getZoom())); + + dynamicVertexArray.clear(); + + for (auto& placedSymbol : placedSymbols) { + vec4 anchorPos = {{ placedSymbol.anchorPoint.x, placedSymbol.anchorPoint.y, 0, 1 }}; + matrix::transformMat4(anchorPos, anchorPos, posMatrix); + + // Don't bother calculating the correct point for invisible labels. + if (!isVisible(anchorPos, placedSymbol.placementZoom, clippingBuffer, frameHistory)) { + hideGlyphs(placedSymbol.glyphOffsets.size(), dynamicVertexArray); + continue; + } + + bool flip = false; + if (values.keepUpright) { + const Point a = project(convertPoint(placedSymbol.line.at(placedSymbol.segment)), posMatrix); + const Point b = project(convertPoint(placedSymbol.line.at(placedSymbol.segment + 1)), posMatrix); + flip = placedSymbol.useVerticalMode ? b.y > a.y : b.x < a.x; + } + + const float cameraToAnchorDistance = anchorPos[3]; + const float perspectiveRatio = 1 + 0.5 * ((cameraToAnchorDistance / state.getCameraToCenterDistance()) - 1.0); + + const float fontSize = evaluateSizeForFeature(partiallyEvaluatedSize, placedSymbol); + const float pitchScaledFontSize = values.pitchAlignment == style::AlignmentType::Map ? + fontSize * perspectiveRatio : + fontSize / perspectiveRatio; + + placeGlyphsAlongLine(placedSymbol, pitchScaledFontSize, flip, labelPlaneMatrix, dynamicVertexArray); + } + } +} // end namespace mbgl diff --git a/src/mbgl/layout/symbol_projection.hpp b/src/mbgl/layout/symbol_projection.hpp new file mode 100644 index 0000000000..2652fe7ace --- /dev/null +++ b/src/mbgl/layout/symbol_projection.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include + +namespace mbgl { + + class TransformState; + class RenderTile; + class FrameHistory; + class SymbolSizeBinder; + class PlacedSymbol; + namespace style { + class SymbolPropertyValues; + } // end namespace style + + mat4 getLabelPlaneMatrix(const mat4& posMatrix, const bool pitchWithMap, const bool rotateWithMap, const TransformState& state, const float pixelsToTileUnits); + mat4 getGlCoordMatrix(const mat4& posMatrix, const bool pitchWithMap, const bool rotateWithMap, const TransformState& state, const float pixelsToTileUnits); + + void reprojectLineLabels(gl::VertexVector&, const std::vector&, + const mat4& posMatrix, const style::SymbolPropertyValues&, + const RenderTile&, const SymbolSizeBinder& sizeBinder, const TransformState&, const FrameHistory& frameHistory); + +} // end namespace mbgl diff --git a/src/mbgl/programs/attributes.hpp b/src/mbgl/programs/attributes.hpp index f39af2deec..684d9d6099 100644 --- a/src/mbgl/programs/attributes.hpp +++ b/src/mbgl/programs/attributes.hpp @@ -23,6 +23,7 @@ inline uint16_t packUint8Pair(T a, T b) { MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_pos); MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_extrude); MBGL_DEFINE_ATTRIBUTE(int16_t, 4, a_pos_offset); +MBGL_DEFINE_ATTRIBUTE(float, 3, a_projected_pos); MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_label_pos); MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_anchor_pos); MBGL_DEFINE_ATTRIBUTE(uint16_t, 2, a_texture_pos); diff --git a/src/mbgl/programs/symbol_program.cpp b/src/mbgl/programs/symbol_program.cpp index bd43237b8f..8790adcc63 100644 --- a/src/mbgl/programs/symbol_program.cpp +++ b/src/mbgl/programs/symbol_program.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -10,7 +11,7 @@ namespace mbgl { using namespace style; -static_assert(sizeof(SymbolLayoutVertex) == 20, "expected SymbolLayoutVertex size"); +static_assert(sizeof(SymbolLayoutVertex) == 16, "expected SymbolLayoutVertex size"); std::unique_ptr SymbolSizeBinder::create(const float tileZoom, const style::DataDrivenPropertyValue& sizeProperty, @@ -33,6 +34,7 @@ Values makeValues(const bool isText, const style::SymbolPropertyValues& values, const Size& texsize, const std::array& pixelsToGLUnits, + const bool alongLine, const RenderTile& tile, const TransformState& state, Args&&... args) { @@ -46,21 +48,41 @@ Values makeValues(const bool isText, pixelsToGLUnits[1] * state.getCameraToCenterDistance() }}; } + + const float pixelsToTileUnits = tile.id.pixelsToTileUnits(1.0, state.getZoom()); + const bool pitchWithMap = values.pitchAlignment == style::AlignmentType::Map; + const bool rotateWithMap = values.rotationAlignment == style::AlignmentType::Map; + + mat4 labelPlaneMatrix; + if (alongLine) { + // For labels that follow lines the first part of the projection is handled on the cpu. + // Pass an identity matrix because no transformation needs to be done in the vertex shader. + matrix::identity(labelPlaneMatrix); + } else { + labelPlaneMatrix = getLabelPlaneMatrix(tile.matrix, pitchWithMap, rotateWithMap, state, pixelsToTileUnits); + } + + mat4 glCoordMatrix = getGlCoordMatrix(tile.matrix, pitchWithMap, rotateWithMap, state, pixelsToTileUnits); return Values { uniforms::u_matrix::Value{ tile.translatedMatrix(values.translate, values.translateAnchor, state) }, + uniforms::u_label_plane_matrix::Value{labelPlaneMatrix}, + uniforms::u_gl_coord_matrix::Value{ tile.translateVtxMatrix(glCoordMatrix, + values.translate, + values.translateAnchor, + state, + true) }, uniforms::u_extrude_scale::Value{ extrudeScale }, uniforms::u_texsize::Value{ texsize }, - uniforms::u_zoom::Value{ float(state.getZoom()) }, - uniforms::u_rotate_with_map::Value{ values.rotationAlignment == AlignmentType::Map }, uniforms::u_texture::Value{ 0 }, uniforms::u_fadetexture::Value{ 1 }, uniforms::u_is_text::Value{ isText }, uniforms::u_collision_y_stretch::Value{ tile.tile.yStretch() }, uniforms::u_camera_to_center_distance::Value{ state.getCameraToCenterDistance() }, uniforms::u_pitch::Value{ state.getPitch() }, + uniforms::u_pitch_with_map::Value{ pitchWithMap }, uniforms::u_max_camera_distance::Value{ values.maxCameraDistance }, std::forward(args)... }; @@ -71,6 +93,7 @@ SymbolIconProgram::uniformValues(const bool isText, const style::SymbolPropertyValues& values, const Size& texsize, const std::array& pixelsToGLUnits, + const bool alongLine, const RenderTile& tile, const TransformState& state) { @@ -79,6 +102,7 @@ SymbolIconProgram::uniformValues(const bool isText, values, texsize, pixelsToGLUnits, + alongLine, tile, state ); @@ -90,25 +114,24 @@ typename SymbolSDFProgram::UniformValues SymbolSDFProgram& pixelsToGLUnits, + const bool alongLine, const RenderTile& tile, const TransformState& state, const SymbolSDFPart part) { const float gammaScale = (values.pitchAlignment == AlignmentType::Map - ? std::cos(state.getPitch()) - : 1.0) * state.getCameraToCenterDistance(); + ? std::cos(state.getPitch()) * state.getCameraToCenterDistance() + : 1.0); return makeValues::UniformValues>( isText, values, texsize, pixelsToGLUnits, + alongLine, tile, state, uniforms::u_gamma_scale::Value{ gammaScale }, - uniforms::u_bearing::Value{ -1.0f * state.getAngle() }, - uniforms::u_aspect_ratio::Value{ (state.getSize().width * 1.0f) / (state.getSize().height * 1.0f) }, - uniforms::u_pitch_with_map::Value{ values.pitchAlignment == AlignmentType::Map }, uniforms::u_is_halo::Value{ part == SymbolSDFPart::Halo } ); } diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index 130e556b46..79a961ad21 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -29,9 +29,9 @@ class RenderTile; class TransformState; namespace uniforms { -MBGL_DEFINE_UNIFORM_SCALAR(bool, u_rotate_with_map); +MBGL_DEFINE_UNIFORM_MATRIX(double, 4, u_gl_coord_matrix); +MBGL_DEFINE_UNIFORM_MATRIX(double, 4, u_label_plane_matrix); MBGL_DEFINE_UNIFORM_SCALAR(gl::TextureUnit, u_texture); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_aspect_ratio); MBGL_DEFINE_UNIFORM_SCALAR(bool, u_is_halo); MBGL_DEFINE_UNIFORM_SCALAR(float, u_gamma_scale); @@ -40,57 +40,58 @@ MBGL_DEFINE_UNIFORM_SCALAR(bool, u_is_size_zoom_constant); MBGL_DEFINE_UNIFORM_SCALAR(bool, u_is_size_feature_constant); MBGL_DEFINE_UNIFORM_SCALAR(float, u_size_t); MBGL_DEFINE_UNIFORM_SCALAR(float, u_size); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_layout_size); MBGL_DEFINE_UNIFORM_SCALAR(float, u_max_camera_distance); } // namespace uniforms struct SymbolLayoutAttributes : gl::Attributes< attributes::a_pos_offset, - attributes::a_label_pos, attributes::a_data> { - static Vertex vertex(Point a, + static Vertex vertex(Point labelAnchor, Point o, - Point labelAnchor, + float glyphOffsetY, uint16_t tx, uint16_t ty, - float minzoom, - float maxzoom, - float labelminzoom, - uint8_t labelangle) { + const Range& sizeData) { return Vertex { // combining pos and offset to reduce number of vertex attributes passed to shader (8 max for some devices) - {{ - static_cast(a.x), - static_cast(a.y), - static_cast(::round(o.x * 64)), // use 1/64 pixels for placement - static_cast(::round(o.y * 64)) - }}, {{ static_cast(labelAnchor.x), - static_cast(labelAnchor.y) + static_cast(labelAnchor.y), + static_cast(::round(o.x * 64)), // use 1/64 pixels for placement + static_cast(::round((o.y + glyphOffsetY) * 64)) }}, {{ tx, ty, - mbgl::attributes::packUint8Pair( - static_cast(labelminzoom * 10), // 1/10 zoom levels: z16 == 160 - static_cast(labelangle) - ), - mbgl::attributes::packUint8Pair( - static_cast(minzoom * 10), - static_cast(::fmin(maxzoom, 25) * 10) - ) + static_cast(sizeData.min * 10), + static_cast(sizeData.max * 10) }} }; } }; + +struct SymbolDynamicLayoutAttributes : gl::Attributes { + static Vertex vertex(Point anchorPoint, float labelAngle, float labelminzoom) { + return Vertex { + {{ + anchorPoint.x, + anchorPoint.y, + static_cast(mbgl::attributes::packUint8Pair( + static_cast(std::fmod(labelAngle + 2 * M_PI, 2 * M_PI) / (2 * M_PI) * 255), + static_cast(labelminzoom * 10))) + }} + }; + } +}; -class SymbolSizeAttributes : public gl::Attributes { -public: - using Attribute = attributes::a_size::Type; +struct ZoomEvaluatedSize { + bool isZoomConstant; + bool isFeatureConstant; + float sizeT; + float size; + float layoutSize; }; - // Mimic the PaintPropertyBinder technique specifically for the {text,icon}-size layout properties // in order to provide a 'custom' scheme for encoding the necessary attribute data. As with // PaintPropertyBinder, SymbolSizeBinder is an abstract class whose implementations handle the @@ -103,18 +104,25 @@ public: uniforms::u_is_size_zoom_constant, uniforms::u_is_size_feature_constant, uniforms::u_size_t, - uniforms::u_size, - uniforms::u_layout_size>; + uniforms::u_size>; using UniformValues = Uniforms::Values; static std::unique_ptr create(const float tileZoom, const style::DataDrivenPropertyValue& sizeProperty, const float defaultValue); - virtual SymbolSizeAttributes::Bindings attributeBindings() const = 0; - virtual void populateVertexVector(const GeometryTileFeature& feature) = 0; - virtual UniformValues uniformValues(float currentZoom) const = 0; - virtual void upload(gl::Context&) = 0; + virtual Range getVertexSizeData(const GeometryTileFeature& feature) = 0; + virtual ZoomEvaluatedSize evaluateForZoom(float currentZoom) const = 0; + + UniformValues uniformValues(float currentZoom) const { + const ZoomEvaluatedSize u = evaluateForZoom(currentZoom); + return UniformValues { + uniforms::u_is_size_zoom_constant::Value{ u.isZoomConstant }, + uniforms::u_is_size_feature_constant::Value{ u.isFeatureConstant}, + uniforms::u_size_t::Value{ u.sizeT }, + uniforms::u_size::Value{ u.size } + }; + } }; // Return the smallest range of stops that covers the interval [lowerZoom, upperZoom] @@ -160,14 +168,9 @@ public: ); } - SymbolSizeAttributes::Bindings attributeBindings() const override { - return SymbolSizeAttributes::Bindings { gl::DisabledAttribute() }; - } - - void upload(gl::Context&) override {} - void populateVertexVector(const GeometryTileFeature&) override {}; + Range getVertexSizeData(const GeometryTileFeature&) override { return { 0.0f, 0.0f }; }; - UniformValues uniformValues(float currentZoom) const override { + ZoomEvaluatedSize evaluateForZoom(float currentZoom) const override { float size = layoutSize; bool isZoomConstant = !(coveringRanges || function); if (coveringRanges) { @@ -186,14 +189,9 @@ public: } else if (function) { size = function->evaluate(currentZoom); } - - return UniformValues { - uniforms::u_is_size_zoom_constant::Value{ isZoomConstant }, - uniforms::u_is_size_feature_constant::Value{ true }, - uniforms::u_size_t::Value{ 0.0f }, // unused - uniforms::u_size::Value{ size }, - uniforms::u_layout_size::Value{ layoutSize } - }; + + const float unused = 0.0f; + return { isZoomConstant, true, unused, size, layoutSize }; } float layoutSize; @@ -215,49 +213,22 @@ public: defaultValue(defaultValue_) { } - SymbolSizeAttributes::Bindings attributeBindings() const override { - return SymbolSizeAttributes::Bindings { SymbolSizeAttributes::Attribute::binding(*buffer, 0, 1) }; - } - - void populateVertexVector(const GeometryTileFeature& feature) override { - const auto sizeVertex = Vertex { - {{ - static_cast(function.evaluate(feature, defaultValue) * 10) - }} - }; - - vertices.emplace_back(sizeVertex); - vertices.emplace_back(sizeVertex); - vertices.emplace_back(sizeVertex); - vertices.emplace_back(sizeVertex); + Range getVertexSizeData(const GeometryTileFeature& feature) override { + const float size = function.evaluate(feature, defaultValue); + return { size, size }; }; - UniformValues uniformValues(float) const override { - return UniformValues { - uniforms::u_is_size_zoom_constant::Value{ true }, - uniforms::u_is_size_feature_constant::Value{ false }, - uniforms::u_size_t::Value{ 0.0f }, // unused - uniforms::u_size::Value{ 0.0f }, // unused - uniforms::u_layout_size::Value{ 0.0f } // unused - }; - } - - void upload(gl::Context& context) override { - buffer = VertexBuffer { context.createVertexBuffer(std::move(vertices)) }; + ZoomEvaluatedSize evaluateForZoom(float) const override { + const float unused = 0.0f; + return { true, false, unused, unused, unused }; } const style::SourceFunction& function; const float defaultValue; - - VertexVector vertices; - optional buffer; }; class CompositeFunctionSymbolSizeBinder final : public SymbolSizeBinder { public: - using Vertex = SymbolSizeAttributes::Vertex; - using VertexVector = gl::VertexVector; - using VertexBuffer = gl::VertexBuffer; CompositeFunctionSymbolSizeBinder(const float tileZoom, const style::CompositeFunction& function_, const float defaultValue_) : function(function_), @@ -268,51 +239,27 @@ public: return getCoveringStops(stops, tileZoom, tileZoom + 1); })) {} - SymbolSizeAttributes::Bindings attributeBindings() const override { - return SymbolSizeAttributes::Bindings { SymbolSizeAttributes::Attribute::binding(*buffer, 0) }; - } - - void populateVertexVector(const GeometryTileFeature& feature) override { - const auto sizeVertex = Vertex { - {{ - static_cast(function.evaluate(coveringZoomStops.min, feature, defaultValue) * 10), - static_cast(function.evaluate(coveringZoomStops.max, feature, defaultValue) * 10), - static_cast(function.evaluate(layoutZoom, feature, defaultValue) * 10) - }} + Range getVertexSizeData(const GeometryTileFeature& feature) override { + return { + function.evaluate(coveringZoomStops.min, feature, defaultValue), + function.evaluate(coveringZoomStops.max, feature, defaultValue) }; - - vertices.emplace_back(sizeVertex); - vertices.emplace_back(sizeVertex); - vertices.emplace_back(sizeVertex); - vertices.emplace_back(sizeVertex); }; - UniformValues uniformValues(float currentZoom) const override { + ZoomEvaluatedSize evaluateForZoom(float currentZoom) const override { float sizeInterpolationT = util::clamp( util::interpolationFactor(1.0f, coveringZoomStops, currentZoom), 0.0f, 1.0f ); - return UniformValues { - uniforms::u_is_size_zoom_constant::Value{ false }, - uniforms::u_is_size_feature_constant::Value{ false }, - uniforms::u_size_t::Value{ sizeInterpolationT }, - uniforms::u_size::Value{ 0.0f }, // unused - uniforms::u_layout_size::Value{ 0.0f } // unused - }; - } - - void upload(gl::Context& context) override { - buffer = VertexBuffer { context.createVertexBuffer(std::move(vertices)) }; + const float unused = 0.0f; + return { false, false, sizeInterpolationT, unused, unused }; } const style::CompositeFunction& function; const float defaultValue; float layoutZoom; Range coveringZoomStops; - - VertexVector vertices; - optional buffer; }; @@ -326,7 +273,7 @@ public: using LayoutAttributes = LayoutAttrs; using LayoutVertex = typename LayoutAttributes::Vertex; - using LayoutAndSizeAttributes = gl::ConcatenateAttributes; + using LayoutAndSizeAttributes = gl::ConcatenateAttributes; using PaintProperties = PaintProps; using PaintPropertyBinders = typename PaintProperties::Binders; @@ -359,6 +306,7 @@ public: gl::ColorMode colorMode, UniformValues&& uniformValues, const gl::VertexBuffer& layoutVertexBuffer, + const gl::VertexBuffer& dynamicLayoutVertexBuffer, const SymbolSizeBinder& symbolSizeBinder, const gl::IndexBuffer& indexBuffer, const gl::SegmentVector& segments, @@ -375,7 +323,7 @@ public: .concat(symbolSizeBinder.uniformValues(currentZoom)) .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)), LayoutAttributes::bindings(layoutVertexBuffer) - .concat(symbolSizeBinder.attributeBindings()) + .concat(SymbolDynamicLayoutAttributes::bindings(dynamicLayoutVertexBuffer)) .concat(paintPropertyBinders.attributeBindings(currentProperties)), indexBuffer, segments @@ -389,16 +337,17 @@ class SymbolIconProgram : public SymbolProgram< SymbolLayoutAttributes, gl::Uniforms< uniforms::u_matrix, + uniforms::u_label_plane_matrix, + uniforms::u_gl_coord_matrix, uniforms::u_extrude_scale, uniforms::u_texsize, - uniforms::u_zoom, - uniforms::u_rotate_with_map, uniforms::u_texture, uniforms::u_fadetexture, uniforms::u_is_text, uniforms::u_collision_y_stretch, uniforms::u_camera_to_center_distance, uniforms::u_pitch, + uniforms::u_pitch_with_map, uniforms::u_max_camera_distance>, style::IconPaintProperties> { @@ -409,6 +358,7 @@ public: const style::SymbolPropertyValues&, const Size& texsize, const std::array& pixelsToGLUnits, + const bool alongLine, const RenderTile&, const TransformState&); }; @@ -425,21 +375,19 @@ class SymbolSDFProgram : public SymbolProgram< SymbolLayoutAttributes, gl::Uniforms< uniforms::u_matrix, + uniforms::u_label_plane_matrix, + uniforms::u_gl_coord_matrix, uniforms::u_extrude_scale, uniforms::u_texsize, - uniforms::u_zoom, - uniforms::u_rotate_with_map, uniforms::u_texture, uniforms::u_fadetexture, uniforms::u_is_text, uniforms::u_collision_y_stretch, uniforms::u_camera_to_center_distance, uniforms::u_pitch, + uniforms::u_pitch_with_map, uniforms::u_max_camera_distance, uniforms::u_gamma_scale, - uniforms::u_bearing, - uniforms::u_aspect_ratio, - uniforms::u_pitch_with_map, uniforms::u_is_halo>, PaintProperties> { @@ -449,21 +397,19 @@ public: SymbolLayoutAttributes, gl::Uniforms< uniforms::u_matrix, + uniforms::u_label_plane_matrix, + uniforms::u_gl_coord_matrix, uniforms::u_extrude_scale, uniforms::u_texsize, - uniforms::u_zoom, - uniforms::u_rotate_with_map, uniforms::u_texture, uniforms::u_fadetexture, uniforms::u_is_text, uniforms::u_collision_y_stretch, uniforms::u_camera_to_center_distance, uniforms::u_pitch, + uniforms::u_pitch_with_map, uniforms::u_max_camera_distance, uniforms::u_gamma_scale, - uniforms::u_bearing, - uniforms::u_aspect_ratio, - uniforms::u_pitch_with_map, uniforms::u_is_halo>, PaintProperties>; @@ -477,6 +423,7 @@ public: const style::SymbolPropertyValues&, const Size& texsize, const std::array& pixelsToGLUnits, + const bool alongLine, const RenderTile&, const TransformState&, const SymbolSDFPart); diff --git a/src/mbgl/programs/uniforms.hpp b/src/mbgl/programs/uniforms.hpp index 861f3271c9..285d243251 100644 --- a/src/mbgl/programs/uniforms.hpp +++ b/src/mbgl/programs/uniforms.hpp @@ -15,7 +15,6 @@ MBGL_DEFINE_UNIFORM_SCALAR(float, u_blur); MBGL_DEFINE_UNIFORM_SCALAR(float, u_zoom); MBGL_DEFINE_UNIFORM_SCALAR(float, u_collision_y_stretch); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_camera_to_center_distance); MBGL_DEFINE_UNIFORM_SCALAR(float, u_pitch); MBGL_DEFINE_UNIFORM_SCALAR(float, u_bearing); MBGL_DEFINE_UNIFORM_SCALAR(float, u_radius); diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp index 28e6a47250..194a5d6bd8 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.cpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp @@ -38,14 +38,14 @@ SymbolBucket::SymbolBucket(style::SymbolLayoutProperties::PossiblyEvaluated layo void SymbolBucket::upload(gl::Context& context) { if (hasTextData()) { text.vertexBuffer = context.createVertexBuffer(std::move(text.vertices)); + text.dynamicVertexBuffer = context.createVertexBuffer(std::move(text.dynamicVertices), gl::BufferUsageType::StreamDraw); text.indexBuffer = context.createIndexBuffer(std::move(text.triangles)); - textSizeBinder->upload(context); } if (hasIconData()) { icon.vertexBuffer = context.createVertexBuffer(std::move(icon.vertices)); + icon.dynamicVertexBuffer = context.createVertexBuffer(std::move(icon.dynamicVertices), gl::BufferUsageType::StreamDraw); icon.indexBuffer = context.createIndexBuffer(std::move(icon.triangles)); - iconSizeBinder->upload(context); } if (!collisionBox.vertices.empty()) { diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp index 002b6e28b3..ffa22e9021 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.hpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp @@ -15,6 +15,23 @@ namespace mbgl { +class PlacedSymbol { +public: + PlacedSymbol(Point anchorPoint_, uint16_t segment_, float lowerSize_, float upperSize_, + std::array lineOffset_, float placementZoom_, bool useVerticalMode_, GeometryCoordinates line_) : + anchorPoint(anchorPoint_), segment(segment_), lowerSize(lowerSize_), upperSize(upperSize_), + lineOffset(lineOffset_), placementZoom(placementZoom_), useVerticalMode(useVerticalMode_), line(std::move(line_)) {} + Point anchorPoint; + uint16_t segment; + float lowerSize; + float upperSize; + std::array lineOffset; + float placementZoom; + bool useVerticalMode; + GeometryCoordinates line; + std::vector glyphOffsets; +}; + class SymbolBucket : public Bucket { public: SymbolBucket(style::SymbolLayoutProperties::PossiblyEvaluated, @@ -44,10 +61,13 @@ public: struct TextBuffer { gl::VertexVector vertices; + gl::VertexVector dynamicVertices; gl::IndexVector triangles; gl::SegmentVector segments; + std::vector placedSymbols; optional> vertexBuffer; + optional> dynamicVertexBuffer; optional> indexBuffer; } text; @@ -55,11 +75,14 @@ public: struct IconBuffer { gl::VertexVector vertices; + gl::VertexVector dynamicVertices; gl::IndexVector triangles; gl::SegmentVector segments; + std::vector placedSymbols; PremultipliedImage atlasImage; optional> vertexBuffer; + optional> dynamicVertexBuffer; optional> indexBuffer; } icon; @@ -69,6 +92,7 @@ public: gl::SegmentVector segments; optional> vertexBuffer; + optional> dynamicVertexBuffer; optional> indexBuffer; } collisionBox; }; diff --git a/src/mbgl/renderer/frame_history.cpp b/src/mbgl/renderer/frame_history.cpp index 869222b4eb..de153b6963 100644 --- a/src/mbgl/renderer/frame_history.cpp +++ b/src/mbgl/renderer/frame_history.cpp @@ -74,4 +74,8 @@ void FrameHistory::bind(gl::Context& context, uint32_t unit) { context.bindTexture(*texture, unit); } +bool FrameHistory::isVisible(const float zoom) const { + return opacities.data[std::floor(zoom * 10)] != 0; +} + } // namespace mbgl diff --git a/src/mbgl/renderer/frame_history.hpp b/src/mbgl/renderer/frame_history.hpp index f2b11f5f41..75a8b60a71 100644 --- a/src/mbgl/renderer/frame_history.hpp +++ b/src/mbgl/renderer/frame_history.hpp @@ -22,6 +22,7 @@ public: bool needsAnimation(const Duration&) const; void bind(gl::Context&, uint32_t); void upload(gl::Context&, uint32_t); + bool isVisible(const float zoom) const; private: std::array changeTimes; diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index 573e9db72e..2fe6dd971e 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -84,6 +84,7 @@ style::SymbolPropertyValues RenderSymbolLayer::iconPropertyValues(const style::S return style::SymbolPropertyValues { layout_.get(), // icon-pitch-alignment is not yet implemented; inherit the rotation alignment layout_.get(), + layout_.get(), evaluated.get(), evaluated.get(), evaluated.get().constantOr(Color::black()).a > 0 && @@ -109,6 +110,7 @@ style::SymbolPropertyValues RenderSymbolLayer::textPropertyValues(const style::S return style::SymbolPropertyValues { layout_.get(), layout_.get(), + layout_.get(), evaluated.get(), evaluated.get(), evaluated.get().constantOr(Color::black()).a > 0 && diff --git a/src/mbgl/renderer/layers/render_symbol_layer.hpp b/src/mbgl/renderer/layers/render_symbol_layer.hpp index e788336cbd..a201b6298f 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.hpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.hpp @@ -40,6 +40,7 @@ public: // Layout AlignmentType pitchAlignment; AlignmentType rotationAlignment; + bool keepUpright; // Paint std::array translate; diff --git a/src/mbgl/renderer/painters/painter_symbol.cpp b/src/mbgl/renderer/painters/painter_symbol.cpp index dc80f096f4..51c3967ae7 100644 --- a/src/mbgl/renderer/painters/painter_symbol.cpp +++ b/src/mbgl/renderer/painters/painter_symbol.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -52,6 +53,7 @@ void Painter::renderSymbol(PaintParameters& parameters, colorModeForRenderPass(), std::move(uniformValues), *buffers.vertexBuffer, + *buffers.dynamicVertexBuffer, *symbolSizeBinder, *buffers.indexBuffer, buffers.segments, @@ -64,10 +66,19 @@ void Painter::renderSymbol(PaintParameters& parameters, assert(dynamic_cast(&tile.tile)); GeometryTile& geometryTile = static_cast(tile.tile); + if (bucket.hasIconData()) { auto values = layer.iconPropertyValues(layout); auto paintPropertyValues = layer.iconPaintProperties(); + const bool alongLine = bucket.layout.get() == SymbolPlacementType::Line && + bucket.layout.get() == AlignmentType::Map; + + if (alongLine) { + reprojectLineLabels(bucket.icon.dynamicVertices, bucket.icon.placedSymbols, tile.matrix, values, tile, *(bucket.iconSizeBinder), state, frameHistory); + context.updateVertexBuffer(*bucket.icon.dynamicVertexBuffer, std::move(bucket.icon.dynamicVertices)); + } + const bool iconScaled = layout.get().constantOr(1.0) != 1.0 || bucket.iconsNeedLinear; const bool iconTransformed = values.rotationAlignment == AlignmentType::Map || state.getPitch() != 0; @@ -80,7 +91,7 @@ void Painter::renderSymbol(PaintParameters& parameters, if (bucket.sdfIcons) { if (values.hasHalo) { draw(parameters.programs.symbolIconSDF, - SymbolSDFIconProgram::uniformValues(false, values, texsize, pixelsToGLUnits, tile, state, SymbolSDFPart::Halo), + SymbolSDFIconProgram::uniformValues(false, values, texsize, pixelsToGLUnits, alongLine, tile, state, SymbolSDFPart::Halo), bucket.icon, bucket.iconSizeBinder, values, @@ -90,7 +101,7 @@ void Painter::renderSymbol(PaintParameters& parameters, if (values.hasFill) { draw(parameters.programs.symbolIconSDF, - SymbolSDFIconProgram::uniformValues(false, values, texsize, pixelsToGLUnits, tile, state, SymbolSDFPart::Fill), + SymbolSDFIconProgram::uniformValues(false, values, texsize, pixelsToGLUnits, alongLine, tile, state, SymbolSDFPart::Fill), bucket.icon, bucket.iconSizeBinder, values, @@ -99,7 +110,7 @@ void Painter::renderSymbol(PaintParameters& parameters, } } else { draw(parameters.programs.symbolIcon, - SymbolIconProgram::uniformValues(false, values, texsize, pixelsToGLUnits, tile, state), + SymbolIconProgram::uniformValues(false, values, texsize, pixelsToGLUnits, alongLine, tile, state), bucket.icon, bucket.iconSizeBinder, values, @@ -114,11 +125,19 @@ void Painter::renderSymbol(PaintParameters& parameters, auto values = layer.textPropertyValues(layout); auto paintPropertyValues = layer.textPaintProperties(); + const bool alongLine = bucket.layout.get() == SymbolPlacementType::Line && + bucket.layout.get() == AlignmentType::Map; + + if (alongLine) { + reprojectLineLabels(bucket.text.dynamicVertices, bucket.text.placedSymbols, tile.matrix, values, tile, *(bucket.textSizeBinder), state, frameHistory); + context.updateVertexBuffer(*bucket.text.dynamicVertexBuffer, std::move(bucket.text.dynamicVertices)); + } + const Size texsize = geometryTile.glyphAtlasTexture->size; if (values.hasHalo) { draw(parameters.programs.symbolGlyph, - SymbolSDFTextProgram::uniformValues(true, values, texsize, pixelsToGLUnits, tile, state, SymbolSDFPart::Halo), + SymbolSDFTextProgram::uniformValues(true, values, texsize, pixelsToGLUnits, alongLine, tile, state, SymbolSDFPart::Halo), bucket.text, bucket.textSizeBinder, values, @@ -128,7 +147,7 @@ void Painter::renderSymbol(PaintParameters& parameters, if (values.hasFill) { draw(parameters.programs.symbolGlyph, - SymbolSDFTextProgram::uniformValues(true, values, texsize, pixelsToGLUnits, tile, state, SymbolSDFPart::Fill), + SymbolSDFTextProgram::uniformValues(true, values, texsize, pixelsToGLUnits, alongLine, tile, state, SymbolSDFPart::Fill), bucket.text, bucket.textSizeBinder, values, diff --git a/src/mbgl/renderer/render_tile.cpp b/src/mbgl/renderer/render_tile.cpp index 59c3ea076b..7e7e3e6d23 100644 --- a/src/mbgl/renderer/render_tile.cpp +++ b/src/mbgl/renderer/render_tile.cpp @@ -2,6 +2,7 @@ #include #include #include +#include namespace mbgl { @@ -10,24 +11,26 @@ using namespace style; mat4 RenderTile::translateVtxMatrix(const mat4& tileMatrix, const std::array& translation, TranslateAnchorType anchor, - const TransformState& state) const { + const TransformState& state, + const bool inViewportPixelUnits) const { if (translation[0] == 0 && translation[1] == 0) { return tileMatrix; } mat4 vtxMatrix; - if (anchor == TranslateAnchorType::Viewport) { - const double sin_a = std::sin(-state.getAngle()); - const double cos_a = std::cos(-state.getAngle()); - matrix::translate(vtxMatrix, tileMatrix, - id.pixelsToTileUnits(translation[0] * cos_a - translation[1] * sin_a, state.getZoom()), - id.pixelsToTileUnits(translation[0] * sin_a + translation[1] * cos_a, state.getZoom()), - 0); + const float angle = inViewportPixelUnits ? + (anchor == TranslateAnchorType::Map ? state.getAngle() : 0) : + (anchor == TranslateAnchorType::Viewport ? -state.getAngle() : 0); + + Point translate = util::rotate(Point{ translation[0], translation[1] }, angle); + + if (inViewportPixelUnits) { + matrix::translate(vtxMatrix, tileMatrix, translate.x, translate.y, 0); } else { matrix::translate(vtxMatrix, tileMatrix, - id.pixelsToTileUnits(translation[0], state.getZoom()), - id.pixelsToTileUnits(translation[1], state.getZoom()), + id.pixelsToTileUnits(translate.x, state.getZoom()), + id.pixelsToTileUnits(translate.y, state.getZoom()), 0); } @@ -37,13 +40,13 @@ mat4 RenderTile::translateVtxMatrix(const mat4& tileMatrix, mat4 RenderTile::translatedMatrix(const std::array& translation, TranslateAnchorType anchor, const TransformState& state) const { - return translateVtxMatrix(matrix, translation, anchor, state); + return translateVtxMatrix(matrix, translation, anchor, state, false); } mat4 RenderTile::translatedClipMatrix(const std::array& translation, TranslateAnchorType anchor, const TransformState& state) const { - return translateVtxMatrix(nearClippedMatrix, translation, anchor, state); + return translateVtxMatrix(nearClippedMatrix, translation, anchor, state, false); } void RenderTile::startRender(Painter& painter) { diff --git a/src/mbgl/renderer/render_tile.hpp b/src/mbgl/renderer/render_tile.hpp index 07e2d699f7..6d374c29cb 100644 --- a/src/mbgl/renderer/render_tile.hpp +++ b/src/mbgl/renderer/render_tile.hpp @@ -38,11 +38,11 @@ public: void startRender(Painter&); -private: mat4 translateVtxMatrix(const mat4& tileMatrix, const std::array& translation, style::TranslateAnchorType anchor, - const TransformState& state) const; + const TransformState& state, + const bool inViewportPixelUnits) const; }; } // namespace mbgl diff --git a/src/mbgl/shaders/collision_box.cpp b/src/mbgl/shaders/collision_box.cpp index 05f306ef65..07fa94e338 100644 --- a/src/mbgl/shaders/collision_box.cpp +++ b/src/mbgl/shaders/collision_box.cpp @@ -36,7 +36,7 @@ void main() { v_max_zoom = a_data.x; v_placement_zoom = a_data.y; - v_perspective_zoom_adjust = log2(collision_perspective_ratio * collision_adjustment) * 10.0; + v_perspective_zoom_adjust = floor(log2(collision_perspective_ratio * collision_adjustment) * 10.0); v_fade_tex = vec2((v_placement_zoom + v_perspective_zoom_adjust) / 255.0, 0.0); } diff --git a/src/mbgl/shaders/symbol_icon.cpp b/src/mbgl/shaders/symbol_icon.cpp index 8960e02c28..cb00cdad05 100644 --- a/src/mbgl/shaders/symbol_icon.cpp +++ b/src/mbgl/shaders/symbol_icon.cpp @@ -7,17 +7,16 @@ namespace shaders { const char* symbol_icon::name = "symbol_icon"; const char* symbol_icon::vertexSource = R"MBGL_SHADER( +const float PI = 3.141592653589793; + attribute vec4 a_pos_offset; -attribute vec2 a_label_pos; attribute vec4 a_data; +attribute vec3 a_projected_pos; -// icon-size data (see symbol_sdf.vertex.glsl for more) -attribute vec3 a_size; uniform bool u_is_size_zoom_constant; uniform bool u_is_size_feature_constant; uniform highp float u_size_t; // used to interpolate between zoom stops when size is a composite function uniform highp float u_size; // used when size is both zoom and feature constant -uniform highp float u_layout_size; // used when size is feature constant uniform highp float u_camera_to_center_distance; uniform highp float u_pitch; uniform highp float u_collision_y_stretch; @@ -31,13 +30,12 @@ varying lowp float opacity; uniform lowp float u_opacity; #endif -// matrix is for the vertex position. uniform mat4 u_matrix; +uniform mat4 u_label_plane_matrix; +uniform mat4 u_gl_coord_matrix; uniform bool u_is_text; -uniform highp float u_zoom; -uniform bool u_rotate_with_map; -uniform vec2 u_extrude_scale; +uniform bool u_pitch_with_map; uniform vec2 u_texsize; @@ -56,61 +54,49 @@ void main() { vec2 a_offset = a_pos_offset.zw; vec2 a_tex = a_data.xy; - highp vec2 label_data = unpack_float(a_data[2]); - highp float a_labelminzoom = label_data[0]; - highp vec2 a_zoom = unpack_float(a_data[3]); - highp float a_minzoom = a_zoom[0]; - highp float a_maxzoom = a_zoom[1]; + vec2 a_size = a_data.zw; + + highp vec2 angle_labelminzoom = unpack_float(a_projected_pos[2]); + highp float segment_angle = -angle_labelminzoom[0] / 255.0 * 2.0 * PI; + mediump float a_labelminzoom = angle_labelminzoom[1]; float size; - // In order to accommodate placing labels around corners in - // symbol-placement: line, each glyph in a label could have multiple - // "quad"s only one of which should be shown at a given zoom level. - // The min/max zoom assigned to each quad is based on the font size at - // the vector tile's zoom level, which might be different than at the - // currently rendered zoom level if text-size is zoom-dependent. - // Thus, we compensate for this difference by calculating an adjustment - // based on the scale of rendered text size relative to layout text size. - highp float layoutSize; if (!u_is_size_zoom_constant && !u_is_size_feature_constant) { size = mix(a_size[0], a_size[1], u_size_t) / 10.0; - layoutSize = a_size[2] / 10.0; } else if (u_is_size_zoom_constant && !u_is_size_feature_constant) { size = a_size[0] / 10.0; - layoutSize = size; } else if (!u_is_size_zoom_constant && u_is_size_feature_constant) { size = u_size; - layoutSize = u_layout_size; } else { size = u_size; - layoutSize = u_size; } - float fontScale = u_is_text ? size / 24.0 : size; + vec4 projectedPoint = u_matrix * vec4(a_pos, 0, 1); + highp float camera_to_anchor_distance = projectedPoint.w; + // See comments in symbol_sdf.vertex + highp float distance_ratio = u_pitch_with_map ? + camera_to_anchor_distance / u_camera_to_center_distance : + u_camera_to_center_distance / camera_to_anchor_distance; + highp float perspective_ratio = 0.5 + 0.5 * distance_ratio; - highp float zoomAdjust = log2(size / layoutSize); - highp float adjustedZoom = (u_zoom - zoomAdjust) * 10.0; - // result: z = 0 if a_minzoom <= adjustedZoom < a_maxzoom, and 1 otherwise - highp float z = 2.0 - step(a_minzoom, adjustedZoom) - (1.0 - step(a_maxzoom, adjustedZoom)); + size *= perspective_ratio; - vec4 projectedPoint = u_matrix * vec4(a_label_pos, 0, 1); - highp float camera_to_anchor_distance = projectedPoint.w; - highp float perspective_ratio = 1.0 + 0.5*((camera_to_anchor_distance / u_camera_to_center_distance) - 1.0); + float fontScale = u_is_text ? size / 24.0 : size; - vec2 extrude = fontScale * u_extrude_scale * perspective_ratio * (a_offset / 64.0); - if (u_rotate_with_map) { - gl_Position = u_matrix * vec4(a_pos + extrude, 0, 1); - gl_Position.z += z * gl_Position.w; - } else { - gl_Position = u_matrix * vec4(a_pos, 0, 1) + vec4(extrude, 0, 0); - } + highp float angle_sin = sin(segment_angle); + highp float angle_cos = cos(segment_angle); + mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); + + vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, 0.0, 1.0); + gl_Position = u_gl_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 64.0 * fontScale), 0.0, 1.0); v_tex = a_tex / u_texsize; // See comments in symbol_sdf.vertex highp float incidence_stretch = camera_to_anchor_distance / (u_camera_to_center_distance * cos(u_pitch)); highp float collision_adjustment = max(1.0, incidence_stretch / u_collision_y_stretch); - highp float perspective_zoom_adjust = log2(perspective_ratio * collision_adjustment) * 10.0; + highp float collision_perspective_ratio = 1.0 + 0.5*((camera_to_anchor_distance / u_camera_to_center_distance) - 1.0); + highp float perspective_zoom_adjust = floor(log2(collision_perspective_ratio * collision_adjustment) * 10.0); v_fade_tex = vec2((a_labelminzoom + perspective_zoom_adjust) / 255.0, 0.0); } diff --git a/src/mbgl/shaders/symbol_sdf.cpp b/src/mbgl/shaders/symbol_sdf.cpp index bae01a5b59..b4158bacc5 100644 --- a/src/mbgl/shaders/symbol_sdf.cpp +++ b/src/mbgl/shaders/symbol_sdf.cpp @@ -9,11 +9,9 @@ const char* symbol_sdf::name = "symbol_sdf"; const char* symbol_sdf::vertexSource = R"MBGL_SHADER( const float PI = 3.141592653589793; -// NOTE: the a_data attribute in this shader is manually bound (see https://github.com/mapbox/mapbox-gl-js/issues/4607). -// If removing or renaming a_data, revisit the manual binding in painter.js accordingly. attribute vec4 a_pos_offset; -attribute vec2 a_label_pos; attribute vec4 a_data; +attribute vec3 a_projected_pos; // contents of a_size vary based on the type of property value // used for {text,icon}-size. @@ -21,17 +19,14 @@ attribute vec4 a_data; // For source functions, we bind only one value per vertex: the value of {text,icon}-size evaluated for the current feature. // For composite functions: // [ text-size(lowerZoomStop, feature), -// text-size(upperZoomStop, feature), -// layoutSize == text-size(layoutZoomLevel, feature) ] -attribute vec3 a_size; +// text-size(upperZoomStop, feature) ] uniform bool u_is_size_zoom_constant; uniform bool u_is_size_feature_constant; uniform highp float u_size_t; // used to interpolate between zoom stops when size is a composite function uniform highp float u_size; // used when size is both zoom and feature constant -uniform highp float u_layout_size; // used when size is feature constant -#ifdef HAS_UNIFORM_u_fill_color +#ifndef HAS_UNIFORM_u_fill_color uniform lowp float a_fill_color_t; attribute highp vec4 a_fill_color; varying highp vec4 fill_color; @@ -39,8 +34,7 @@ varying highp vec4 fill_color; uniform highp vec4 u_fill_color; #endif - -#ifdef HAS_UNIFORM_u_halo_color +#ifndef HAS_UNIFORM_u_halo_color uniform lowp float a_halo_color_t; attribute highp vec4 a_halo_color; varying highp vec4 halo_color; @@ -48,8 +42,7 @@ varying highp vec4 halo_color; uniform highp vec4 u_halo_color; #endif - -#ifdef HAS_UNIFORM_u_opacity +#ifndef HAS_UNIFORM_u_opacity uniform lowp float a_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; @@ -57,8 +50,7 @@ varying lowp float opacity; uniform lowp float u_opacity; #endif - -#ifdef HAS_UNIFORM_u_halo_width +#ifndef HAS_UNIFORM_u_halo_width uniform lowp float a_halo_width_t; attribute lowp vec2 a_halo_width; varying lowp float halo_width; @@ -66,8 +58,7 @@ varying lowp float halo_width; uniform lowp float u_halo_width; #endif - -#ifdef HAS_UNIFORM_u_halo_blur +#ifndef HAS_UNIFORM_u_halo_blur uniform lowp float a_halo_blur_t; attribute lowp vec2 a_halo_blur; varying lowp float halo_blur; @@ -75,168 +66,100 @@ varying lowp float halo_blur; uniform lowp float u_halo_blur; #endif - -// matrix is for the vertex position. uniform mat4 u_matrix; +uniform mat4 u_label_plane_matrix; +uniform mat4 u_gl_coord_matrix; uniform bool u_is_text; -uniform highp float u_zoom; -uniform bool u_rotate_with_map; uniform bool u_pitch_with_map; uniform highp float u_pitch; -uniform highp float u_bearing; -uniform highp float u_aspect_ratio; uniform highp float u_camera_to_center_distance; -uniform highp float u_max_camera_distance; uniform highp float u_collision_y_stretch; -uniform vec2 u_extrude_scale; uniform vec2 u_texsize; -varying vec2 v_tex; -varying vec2 v_fade_tex; -varying float v_gamma_scale; -varying float v_size; - -// Used below to move the vertex out of the clip space for when the current -// zoom is out of the glyph's zoom range. -highp float clipUnusedGlyphAngles(const highp float render_size, - const highp float layout_size, - const highp float min_zoom, - const highp float max_zoom) { - highp float zoom_adjust = log2(render_size / layout_size); - highp float adjusted_zoom = (u_zoom - zoom_adjust) * 10.0; - // result: 0 if min_zoom <= adjusted_zoom < max_zoom, and 1 otherwise - return 2.0 - step(min_zoom, adjusted_zoom) - (1.0 - step(max_zoom, adjusted_zoom)); -} +varying vec4 v_data0; +varying vec2 v_data1; void main() { - + #ifndef HAS_UNIFORM_u_fill_color fill_color = unpack_mix_vec4(a_fill_color, a_fill_color_t); #else highp vec4 fill_color = u_fill_color; #endif - #ifndef HAS_UNIFORM_u_halo_color halo_color = unpack_mix_vec4(a_halo_color, a_halo_color_t); #else highp vec4 halo_color = u_halo_color; #endif - #ifndef HAS_UNIFORM_u_opacity opacity = unpack_mix_vec2(a_opacity, a_opacity_t); #else lowp float opacity = u_opacity; #endif - #ifndef HAS_UNIFORM_u_halo_width halo_width = unpack_mix_vec2(a_halo_width, a_halo_width_t); #else lowp float halo_width = u_halo_width; #endif - #ifndef HAS_UNIFORM_u_halo_blur halo_blur = unpack_mix_vec2(a_halo_blur, a_halo_blur_t); #else lowp float halo_blur = u_halo_blur; #endif - vec2 a_pos = a_pos_offset.xy; vec2 a_offset = a_pos_offset.zw; vec2 a_tex = a_data.xy; + vec2 a_size = a_data.zw; + + highp vec2 angle_labelminzoom = unpack_float(a_projected_pos[2]); + highp float segment_angle = -angle_labelminzoom[0] / 255.0 * 2.0 * PI; + mediump float a_labelminzoom = angle_labelminzoom[1]; + float size; - highp vec2 label_data = unpack_float(a_data[2]); - highp float a_labelminzoom = label_data[0]; - highp float a_lineangle = (label_data[1] / 256.0 * 2.0 * PI); - highp vec2 a_zoom = unpack_float(a_data[3]); - highp float a_minzoom = a_zoom[0]; - highp float a_maxzoom = a_zoom[1]; - - // In order to accommodate placing labels around corners in - // symbol-placement: line, each glyph in a label could have multiple - // "quad"s only one of which should be shown at a given zoom level. - // The min/max zoom assigned to each quad is based on the font size at - // the vector tile's zoom level, which might be different than at the - // currently rendered zoom level if text-size is zoom-dependent. - // Thus, we compensate for this difference by calculating an adjustment - // based on the scale of rendered text size relative to layout text size. - highp float layoutSize; if (!u_is_size_zoom_constant && !u_is_size_feature_constant) { - v_size = mix(a_size[0], a_size[1], u_size_t) / 10.0; - layoutSize = a_size[2] / 10.0; + size = mix(a_size[0], a_size[1], u_size_t) / 10.0; } else if (u_is_size_zoom_constant && !u_is_size_feature_constant) { - v_size = a_size[0] / 10.0; - layoutSize = v_size; + size = a_size[0] / 10.0; } else if (!u_is_size_zoom_constant && u_is_size_feature_constant) { - v_size = u_size; - layoutSize = u_layout_size; + size = u_size; } else { - v_size = u_size; - layoutSize = u_size; + size = u_size; } - float fontScale = u_is_text ? v_size / 24.0 : v_size; - - vec4 projectedPoint = u_matrix * vec4(a_label_pos, 0, 1); + vec4 projectedPoint = u_matrix * vec4(a_pos, 0, 1); highp float camera_to_anchor_distance = projectedPoint.w; - highp float perspective_ratio = 1.0 + 0.5*((camera_to_anchor_distance / u_camera_to_center_distance) - 1.0); - - // pitch-alignment: map - // rotation-alignment: map | viewport - if (u_pitch_with_map) { - highp float angle = u_rotate_with_map ? a_lineangle : u_bearing; - highp float asin = sin(angle); - highp float acos = cos(angle); - mat2 RotationMatrix = mat2(acos, asin, -1.0 * asin, acos); - vec2 offset = RotationMatrix * a_offset; - vec2 extrude = fontScale * u_extrude_scale * perspective_ratio * (offset / 64.0); - - gl_Position = u_matrix * vec4(a_pos + extrude, 0, 1); - gl_Position.z += clipUnusedGlyphAngles(v_size*perspective_ratio, layoutSize, a_minzoom, a_maxzoom) * gl_Position.w; - // pitch-alignment: viewport - // rotation-alignment: map - } else if (u_rotate_with_map) { - // foreshortening factor to apply on pitched maps - // as a label goes from horizontal <=> vertical in angle - // it goes from 0% foreshortening to up to around 70% foreshortening - highp float pitchfactor = 1.0 - cos(u_pitch * sin(u_pitch * 0.75)); - - // use the lineangle to position points a,b along the line - // project the points and calculate the label angle in projected space - // this calculation allows labels to be rendered unskewed on pitched maps - vec4 a = u_matrix * vec4(a_pos, 0, 1); - vec4 b = u_matrix * vec4(a_pos + vec2(cos(a_lineangle), sin(a_lineangle)), 0, 1); - highp float angle = atan((b[1] / b[3] - a[1] / a[3]) / u_aspect_ratio, b[0] / b[3] - a[0] / a[3]); - highp float asin = sin(angle); - highp float acos = cos(angle); - mat2 RotationMatrix = mat2(acos, -1.0 * asin, asin, acos); - highp float foreshortening = (1.0 - pitchfactor) + (pitchfactor * cos(angle * 2.0)); - - vec2 offset = RotationMatrix * (vec2(foreshortening, 1.0) * a_offset); - vec2 extrude = fontScale * u_extrude_scale * perspective_ratio * (offset / 64.0); - - gl_Position = u_matrix * vec4(a_pos, 0, 1) + vec4(extrude, 0, 0); - gl_Position.z += clipUnusedGlyphAngles(v_size * perspective_ratio, layoutSize, a_minzoom, a_maxzoom) * gl_Position.w; - // pitch-alignment: viewport - // rotation-alignment: viewport - } else { - vec2 extrude = fontScale * u_extrude_scale * perspective_ratio * (a_offset / 64.0); - gl_Position = u_matrix * vec4(a_pos, 0, 1) + vec4(extrude, 0, 0); - } - - gl_Position.z += - step(u_max_camera_distance * u_camera_to_center_distance, camera_to_anchor_distance) * gl_Position.w; - - v_gamma_scale = gl_Position.w / perspective_ratio; - - v_tex = a_tex / u_texsize; + // If the label is pitched with the map, layout is done in pitched space, + // which makes labels in the distance smaller relative to viewport space. + // We counteract part of that effect by multiplying by the perspective ratio. + // If the label isn't pitched with the map, we do layout in viewport space, + // which makes labels in the distance larger relative to the features around + // them. We counteract part of that effect by dividing by the perspective ratio. + highp float distance_ratio = u_pitch_with_map ? + camera_to_anchor_distance / u_camera_to_center_distance : + u_camera_to_center_distance / camera_to_anchor_distance; + highp float perspective_ratio = 0.5 + 0.5 * distance_ratio; + + size *= perspective_ratio; + + float fontScale = u_is_text ? size / 24.0 : size; + + highp float angle_sin = sin(segment_angle); + highp float angle_cos = cos(segment_angle); + mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); + + vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, 0.0, 1.0); + gl_Position = u_gl_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 64.0 * fontScale), 0.0, 1.0); + float gamma_scale = gl_Position.w; + + vec2 tex = a_tex / u_texsize; // incidence_stretch is the ratio of how much y space a label takes up on a tile while drawn perpendicular to the viewport vs // how much space it would take up if it were drawn flat on the tile // Using law of sines, camera_to_anchor/sin(ground_angle) = camera_to_center/sin(incidence_angle) @@ -256,8 +179,12 @@ void main() { highp float collision_adjustment = max(1.0, incidence_stretch / u_collision_y_stretch); // Floor to 1/10th zoom to dodge precision issues that can cause partially hidden labels - highp float perspective_zoom_adjust = floor(log2(perspective_ratio * collision_adjustment) * 10.0); - v_fade_tex = vec2((a_labelminzoom + perspective_zoom_adjust) / 255.0, 0.0); + highp float collision_perspective_ratio = 1.0 + 0.5*((camera_to_anchor_distance / u_camera_to_center_distance) - 1.0); + highp float perspective_zoom_adjust = floor(log2(collision_perspective_ratio * collision_adjustment) * 10.0); + vec2 fade_tex = vec2((a_labelminzoom + perspective_zoom_adjust) / 255.0, 0.0); + + v_data0 = vec4(tex.x, tex.y, fade_tex.x, fade_tex.y); + v_data1 = vec2(gamma_scale, size); } )MBGL_SHADER"; @@ -273,73 +200,66 @@ varying highp vec4 fill_color; uniform highp vec4 u_fill_color; #endif - #ifndef HAS_UNIFORM_u_halo_color varying highp vec4 halo_color; #else uniform highp vec4 u_halo_color; #endif - #ifndef HAS_UNIFORM_u_opacity varying lowp float opacity; #else uniform lowp float u_opacity; #endif - #ifndef HAS_UNIFORM_u_halo_width varying lowp float halo_width; #else uniform lowp float u_halo_width; #endif - #ifndef HAS_UNIFORM_u_halo_blur varying lowp float halo_blur; #else uniform lowp float u_halo_blur; #endif - uniform sampler2D u_texture; uniform sampler2D u_fadetexture; uniform highp float u_gamma_scale; uniform bool u_is_text; -varying vec2 v_tex; -varying vec2 v_fade_tex; -varying float v_gamma_scale; -varying float v_size; +varying vec4 v_data0; +varying vec2 v_data1; void main() { - + #ifdef HAS_UNIFORM_u_fill_color highp vec4 fill_color = u_fill_color; #endif - #ifdef HAS_UNIFORM_u_halo_color highp vec4 halo_color = u_halo_color; #endif - #ifdef HAS_UNIFORM_u_opacity lowp float opacity = u_opacity; #endif - #ifdef HAS_UNIFORM_u_halo_width lowp float halo_width = u_halo_width; #endif - #ifdef HAS_UNIFORM_u_halo_blur lowp float halo_blur = u_halo_blur; #endif + vec2 tex = v_data0.xy; + vec2 fade_tex = v_data0.zw; + float gamma_scale = v_data1.x; + float size = v_data1.y; - float fontScale = u_is_text ? v_size / 24.0 : v_size; + float fontScale = u_is_text ? size / 24.0 : size; lowp vec4 color = fill_color; highp float gamma = EDGE_GAMMA / (fontScale * u_gamma_scale); @@ -350,9 +270,9 @@ void main() { buff = (6.0 - halo_width / fontScale) / SDF_PX; } - lowp float dist = texture2D(u_texture, v_tex).a; - lowp float fade_alpha = texture2D(u_fadetexture, v_fade_tex).a; - highp float gamma_scaled = gamma * v_gamma_scale; + lowp float dist = texture2D(u_texture, tex).a; + lowp float fade_alpha = texture2D(u_fadetexture, fade_tex).a; + highp float gamma_scaled = gamma * gamma_scale; highp float alpha = smoothstep(buff - gamma_scaled, buff + gamma_scaled, dist) * fade_alpha; gl_FragColor = color * (alpha * opacity); diff --git a/src/mbgl/text/quads.cpp b/src/mbgl/text/quads.cpp index ab10c5a6b7..7908ea4abc 100644 --- a/src/mbgl/text/quads.cpp +++ b/src/mbgl/text/quads.cpp @@ -13,14 +13,9 @@ namespace mbgl { using namespace style; -const float globalMinScale = 0.5f; // underscale by 1 zoom level - -SymbolQuad getIconQuad(const Anchor& anchor, - const PositionedIcon& shapedIcon, - const GeometryCoordinates& line, +SymbolQuad getIconQuad(const PositionedIcon& shapedIcon, const SymbolLayoutProperties::Evaluated& layout, const float layoutTextSize, - const style::SymbolPlacementType placement, const Shaping& shapedText) { const ImagePosition& image = shapedIcon.image(); @@ -71,18 +66,7 @@ SymbolQuad getIconQuad(const Anchor& anchor, bl = {left, bottom}; } - float angle = shapedIcon.angle(); - if (placement == style::SymbolPlacementType::Line) { - assert(static_cast(anchor.segment) < line.size()); - const GeometryCoordinate &prev= line[anchor.segment]; - if (anchor.point.y == prev.y && anchor.point.x == prev.x && - static_cast(anchor.segment + 1) < line.size()) { - const GeometryCoordinate &next= line[anchor.segment + 1]; - angle += std::atan2(anchor.point.y - next.y, anchor.point.x - next.x) + M_PI; - } else { - angle += std::atan2(anchor.point.y - prev.y, anchor.point.x - prev.x); - } - } + const float angle = shapedIcon.angle(); if (angle) { // Compute the transformation matrix. @@ -104,212 +88,19 @@ SymbolQuad getIconQuad(const Anchor& anchor, static_cast(image.textureRect.h + border * 2) }; - return SymbolQuad { tl, tr, bl, br, textureRect, 0, 0, anchor.point, globalMinScale, std::numeric_limits::infinity(), shapedText.writingMode }; -} - -struct GlyphInstance { - explicit GlyphInstance(Point anchorPoint_) : anchorPoint(std::move(anchorPoint_)) {} - explicit GlyphInstance(Point anchorPoint_, bool upsideDown_, float minScale_, float maxScale_, - float angle_) - : anchorPoint(std::move(anchorPoint_)), upsideDown(upsideDown_), minScale(minScale_), maxScale(maxScale_), angle(angle_) {} - - const Point anchorPoint; - const bool upsideDown = false; - const float minScale = globalMinScale; - const float maxScale = std::numeric_limits::infinity(); - const float angle = 0.0f; -}; - -using GlyphInstances = std::vector; - -struct VirtualSegment { - Point anchor; - Point end; - size_t index; - float minScale; - float maxScale; -}; - -inline void insertSegmentGlyph(std::back_insert_iterator glyphs, - const VirtualSegment& virtualSegment, - const bool glyphIsLogicallyForward, - const bool upsideDown) { - float segmentAngle = std::atan2(virtualSegment.end.y - virtualSegment.anchor.y, virtualSegment.end.x - virtualSegment.anchor.x); - // If !glyphIsLogicallyForward, we're iterating through the segments in reverse logical order as well, so we need to flip the segment angle - float glyphAngle = glyphIsLogicallyForward ? segmentAngle : segmentAngle + M_PI; - - // Insert a glyph rotated at this angle for display in the range from [scale, previous(larger) scale]. - glyphs = GlyphInstance{ - /* anchor */ virtualSegment.anchor, - /* upsideDown */ upsideDown, - /* minScale */ virtualSegment.minScale, - /* maxScale */ virtualSegment.maxScale, - /* angle */ static_cast(std::fmod((glyphAngle + 2.0 * M_PI), (2.0 * M_PI)))}; -} - -/** - Given the distance along the line from the label anchor to the beginning of the current segment, - project a "virtual anchor" point at the same distance along the line extending out from this segment. - - B <-- beginning of current segment -* . . . . . . . *--------* E <-- end of current segment -VA | - / VA = "virtual segment anchor" - / - ---*-----` - A = label anchor - - Distance _along line_ from A to B == straight-line distance from VA to B. - */ -inline Point getVirtualSegmentAnchor(const Point& segmentBegin, const Point& segmentEnd, float distanceFromAnchorToSegmentBegin) { - Point segmentDirectionUnitVector = util::normal(segmentBegin, segmentEnd); - return segmentBegin - (segmentDirectionUnitVector * distanceFromAnchorToSegmentBegin); -} - -/* - Given the segment joining `segmentAnchor` and `segmentEnd` and a desired offset - `glyphDistanceFromAnchor` at which a glyph is to be placed, calculate the minimum - "scale" at which the glyph will fall on the segment (i.e., not past the end) - - "Scale" here refers to the ratio between the *rendered* zoom level and the text-layout - zoom level, which is 1 + (source tile's zoom level). `glyphDistanceFromAnchor`, although - passed in units consistent with the text-layout zoom level, is based on text size. So - when the tile is being rendered at z < text-layout zoom, the glyph's actual distance from - the anchor is larger relative to the segment's length than at layout time: - - - GLYPH - z == layout-zoom, scale == 1: segmentAnchor *--------------^-------------* segmentEnd - z == layout-zoom - 1, scale == 0.5: segmentAnchor *--------------^* segmentEnd - - <--------------> - Anchor-to-glyph distance stays visually fixed, - so it changes relative to the segment. -*/ -inline float getMinScaleForSegment(const float glyphDistanceFromAnchor, - const Point& segmentAnchor, - const Point& segmentEnd) { - const auto distanceFromAnchorToEnd = util::dist(segmentAnchor, segmentEnd); - return glyphDistanceFromAnchor / distanceFromAnchorToEnd; -} - -inline Point getSegmentEnd(const bool glyphIsLogicallyForward, - const GeometryCoordinates& line, - const size_t segmentIndex) { - return convertPoint(glyphIsLogicallyForward ? line[segmentIndex+1] : line[segmentIndex]); -} - -optional getNextVirtualSegment(const VirtualSegment& previousVirtualSegment, - const GeometryCoordinates& line, - const float glyphDistanceFromAnchor, - const bool glyphIsLogicallyForward) { - auto nextSegmentBegin = previousVirtualSegment.end; - - auto end = nextSegmentBegin; - size_t index = previousVirtualSegment.index; - - // skip duplicate nodes - while (end == nextSegmentBegin) { - // look ahead by 2 points in the line because the segment index refers to the beginning - // of the segment, and we need an endpoint too - if (glyphIsLogicallyForward && (index + 2 < line.size())) { - index += 1; - } else if (!glyphIsLogicallyForward && index != 0) { - index -= 1; - } else { - return {}; - } - - end = getSegmentEnd(glyphIsLogicallyForward, line, index); - } - - const auto anchor = getVirtualSegmentAnchor(nextSegmentBegin, end, - util::dist(previousVirtualSegment.anchor, - previousVirtualSegment.end)); - return VirtualSegment { - anchor, - end, - index, - getMinScaleForSegment(glyphDistanceFromAnchor, anchor, end), - previousVirtualSegment.minScale - }; -} - -/* - Given (1) a glyph positioned relative to an anchor point and (2) a line to follow, - calculates which segment of the line the glyph will fall on for each possible - scale range, and for each range produces a "virtual" anchor point and an angle that will - place the glyph on the right segment and rotated to the correct angle. - - Because one glyph quad is made ahead of time for each possible orientation, the - symbol_sdf shader can quickly handle changing layout as we zoom in and out - - If the "keepUpright" property is set, we call getLineGlyphs twice (once upright and - once "upside down"). This will generate two sets of glyphs following the line in opposite - directions. Later, SymbolLayout::place will look at the glyphs and based on the placement - angle determine if their original anchor was "upright" or not -- based on that, it throws - away one set of glyphs or the other (this work has to be done in the CPU, but it's just a - filter so it's fast) - */ -void getLineGlyphs(std::back_insert_iterator glyphs, - Anchor& anchor, - float glyphHorizontalOffsetFromAnchor, - const GeometryCoordinates& line, - size_t anchorSegment, - bool upsideDown) { - assert(line.size() > anchorSegment+1); - - // This is true if the glyph is "logically forward" of the anchor point, based on the ordering of line segments - // The actual angle of the line is irrelevant - // If "upsideDown" is set, everything is flipped - const bool glyphIsLogicallyForward = (glyphHorizontalOffsetFromAnchor >= 0) ^ upsideDown; - const float glyphDistanceFromAnchor = std::fabs(glyphHorizontalOffsetFromAnchor); - - const auto initialSegmentEnd = getSegmentEnd(glyphIsLogicallyForward, line, anchorSegment); - VirtualSegment virtualSegment = { - anchor.point, - initialSegmentEnd, - anchorSegment, - getMinScaleForSegment(glyphDistanceFromAnchor, anchor.point, initialSegmentEnd), - std::numeric_limits::infinity() - }; - - while (true) { - insertSegmentGlyph(glyphs, - virtualSegment, - glyphIsLogicallyForward, - upsideDown); - - if (virtualSegment.minScale <= anchor.scale) { - // No need to calculate below the scale where the label starts showing - return; - } - - optional nextVirtualSegment = getNextVirtualSegment(virtualSegment, - line, - glyphDistanceFromAnchor, - glyphIsLogicallyForward); - if (!nextVirtualSegment) { - // There are no more segments, so we can't fit this glyph on the line at a lower scale - // This implies we can't show the label at all at lower scale, so we update the anchor's min scale - anchor.scale = virtualSegment.minScale; - return; - } else { - virtualSegment = *nextVirtualSegment; - } - } - + return SymbolQuad { tl, tr, bl, br, textureRect, shapedText.writingMode, { 0.0f, 0.0f } }; } -SymbolQuads getGlyphQuads(Anchor& anchor, - const Shaping& shapedText, - const float boxScale, - const GeometryCoordinates& line, +SymbolQuads getGlyphQuads(const Shaping& shapedText, const SymbolLayoutProperties::Evaluated& layout, const style::SymbolPlacementType placement, const GlyphPositionMap& positions) { const float textRotate = layout.get() * util::DEG2RAD; - const bool keepUpright = layout.get(); + + const float oneEm = 24.0; + std::array textOffset = layout.get(); + textOffset[0] *= oneEm; + textOffset[1] *= oneEm; SymbolQuads quads; @@ -320,67 +111,55 @@ SymbolQuads getGlyphQuads(Anchor& anchor, const GlyphPosition& glyph = positionsIt->second; const Rect& rect = glyph.rect; - const float centerX = (positionedGlyph.x + glyph.metrics.advance / 2.0f) * boxScale; - - GlyphInstances glyphInstances; - if (placement == style::SymbolPlacementType::Line) { - getLineGlyphs(std::back_inserter(glyphInstances), anchor, centerX, line, anchor.segment, false); - if (keepUpright) - getLineGlyphs(std::back_inserter(glyphInstances), anchor, centerX, line, anchor.segment, true); - } else { - glyphInstances.emplace_back(GlyphInstance{anchor.point}); - } // The rects have an addditional buffer that is not included in their size; const float glyphPadding = 1.0f; const float rectBuffer = 3.0f + glyphPadding; - const float x1 = positionedGlyph.x + glyph.metrics.left - rectBuffer; - const float y1 = positionedGlyph.y - glyph.metrics.top - rectBuffer; + const float halfAdvance = glyph.metrics.advance / 2.0; + const bool alongLine = layout.get() == AlignmentType::Map && placement == SymbolPlacementType::Line; + + const Point glyphOffset = alongLine ? + Point{ positionedGlyph.x + halfAdvance, positionedGlyph.y } : + Point{ 0.0f, 0.0f }; + + const Point builtInOffset = alongLine ? + Point{ 0.0f, 0.0f } : + Point{ positionedGlyph.x + halfAdvance + textOffset[0], positionedGlyph.y + textOffset[1] }; + + + const float x1 = glyph.metrics.left - rectBuffer - halfAdvance + builtInOffset.x; + const float y1 = -glyph.metrics.top - rectBuffer + builtInOffset.y; const float x2 = x1 + rect.w; const float y2 = y1 + rect.h; - const Point center{positionedGlyph.x, static_cast(static_cast(glyph.metrics.advance) / 2.0)}; + const Point center{builtInOffset.x - halfAdvance, static_cast(static_cast(glyph.metrics.advance) / 2.0)}; - Point otl{x1, y1}; - Point otr{x2, y1}; - Point obl{x1, y2}; - Point obr{x2, y2}; + Point tl{x1, y1}; + Point tr{x2, y1}; + Point bl{x1, y2}; + Point br{x2, y2}; if (positionedGlyph.angle != 0) { - otl = util::rotate(otl - center, positionedGlyph.angle) + center; - otr = util::rotate(otr - center, positionedGlyph.angle) + center; - obl = util::rotate(obl - center, positionedGlyph.angle) + center; - obr = util::rotate(obr - center, positionedGlyph.angle) + center; + tl = util::rotate(tl - center, positionedGlyph.angle) + center; + tr = util::rotate(tr - center, positionedGlyph.angle) + center; + bl = util::rotate(bl - center, positionedGlyph.angle) + center; + br = util::rotate(br - center, positionedGlyph.angle) + center; } - for (const GlyphInstance &instance : glyphInstances) { - Point tl = otl; - Point tr = otr; - Point bl = obl; - Point br = obr; + if (textRotate) { + // Compute the transformation matrix. + float angle_sin = std::sin(textRotate); + float angle_cos = std::cos(textRotate); + std::array matrix = {{angle_cos, -angle_sin, angle_sin, angle_cos}}; - if (textRotate) { - // Compute the transformation matrix. - float angle_sin = std::sin(textRotate); - float angle_cos = std::cos(textRotate); - std::array matrix = {{angle_cos, -angle_sin, angle_sin, angle_cos}}; - - tl = util::matrixMultiply(matrix, tl); - tr = util::matrixMultiply(matrix, tr); - bl = util::matrixMultiply(matrix, bl); - br = util::matrixMultiply(matrix, br); - } - - // Prevent label from extending past the end of the line - const float glyphMinScale = std::max(instance.minScale, anchor.scale); - - // All the glyphs for a label are tagged with either the "right side up" or "upside down" anchor angle, - // which is used at placement time to determine which set to show - const float anchorAngle = std::fmod((anchor.angle + (instance.upsideDown ? M_PI : 0.0) + 2 * M_PI), (2 * M_PI)); - const float glyphAngle = std::fmod((instance.angle + (instance.upsideDown ? M_PI : 0.0) + 2 * M_PI), (2 * M_PI)); - quads.emplace_back(tl, tr, bl, br, rect, anchorAngle, glyphAngle, instance.anchorPoint, glyphMinScale, instance.maxScale, shapedText.writingMode); + tl = util::matrixMultiply(matrix, tl); + tr = util::matrixMultiply(matrix, tr); + bl = util::matrixMultiply(matrix, bl); + br = util::matrixMultiply(matrix, br); } + + quads.emplace_back(tl, tr, bl, br, rect, shapedText.writingMode, glyphOffset); } return quads; diff --git a/src/mbgl/text/quads.hpp b/src/mbgl/text/quads.hpp index b29f6b0ad3..33d003c935 100644 --- a/src/mbgl/text/quads.hpp +++ b/src/mbgl/text/quads.hpp @@ -19,50 +19,33 @@ public: Point bl_, Point br_, Rect tex_, - float anchorAngle_, - float glyphAngle_, - Point anchorPoint_, - float minScale_, - float maxScale_, - WritingModeType writingMode_) + WritingModeType writingMode_, + Point glyphOffset_) : tl(std::move(tl_)), tr(std::move(tr_)), bl(std::move(bl_)), br(std::move(br_)), tex(std::move(tex_)), - anchorAngle(anchorAngle_), - glyphAngle(glyphAngle_), - anchorPoint(std::move(anchorPoint_)), - minScale(minScale_), - maxScale(maxScale_), - writingMode(writingMode_) {} + writingMode(writingMode_), + glyphOffset(glyphOffset_) {} Point tl; Point tr; Point bl; Point br; Rect tex; - float anchorAngle, glyphAngle; - Point anchorPoint; - float minScale; - float maxScale; WritingModeType writingMode; + Point glyphOffset; }; using SymbolQuads = std::vector; -SymbolQuad getIconQuad(const Anchor& anchor, - const PositionedIcon& shapedIcon, - const GeometryCoordinates& line, +SymbolQuad getIconQuad(const PositionedIcon& shapedIcon, const style::SymbolLayoutProperties::Evaluated&, const float layoutTextSize, - style::SymbolPlacementType placement, const Shaping& shapedText); -SymbolQuads getGlyphQuads(Anchor& anchor, - const Shaping& shapedText, - const float boxScale, - const GeometryCoordinates& line, +SymbolQuads getGlyphQuads(const Shaping& shapedText, const style::SymbolLayoutProperties::Evaluated&, style::SymbolPlacementType placement, const GlyphPositionMap& positions); diff --git a/src/mbgl/text/shaping.cpp b/src/mbgl/text/shaping.cpp index 338abe2e43..c81f25d4eb 100644 --- a/src/mbgl/text/shaping.cpp +++ b/src/mbgl/text/shaping.cpp @@ -27,12 +27,9 @@ void align(Shaping& shaping, const float verticalAlign, const float maxLineLength, const float lineHeight, - const std::size_t lineCount, - const Point& translate) { - const float shiftX = - (justify - horizontalAlign) * maxLineLength + ::round(translate.x); - const float shiftY = - (-verticalAlign * lineCount + 0.5) * lineHeight + ::round(translate.y); + const std::size_t lineCount) { + const float shiftX = (justify - horizontalAlign) * maxLineLength; + const float shiftY = (-verticalAlign * lineCount + 0.5) * lineHeight; for (auto& glyph : shaping.positionedGlyphs) { glyph.x += shiftX; @@ -205,7 +202,6 @@ void shapeLines(Shaping& shaping, const float horizontalAlign, const float verticalAlign, const float justify, - const Point& translate, const float verticalHeight, const WritingModeType writingMode, const Glyphs& glyphs) { @@ -259,7 +255,7 @@ void shapeLines(Shaping& shaping, } align(shaping, justify, horizontalAlign, verticalAlign, maxLineLength, lineHeight, - lines.size(), translate); + lines.size()); const uint32_t height = lines.size() * lineHeight; // Calculate the bounding box @@ -288,7 +284,7 @@ const Shaping getShaping(const std::u16string& logicalInput, determineLineBreaks(logicalInput, spacing, maxWidth, writingMode, glyphs)); shapeLines(shaping, reorderedLines, spacing, lineHeight, horizontalAlign, verticalAlign, - justify, translate, verticalHeight, writingMode, glyphs); + justify, verticalHeight, writingMode, glyphs); return shaping; } diff --git a/test/programs/symbol_program.test.cpp b/test/programs/symbol_program.test.cpp index ef1e71c269..62a2e58d7b 100644 --- a/test/programs/symbol_program.test.cpp +++ b/test/programs/symbol_program.test.cpp @@ -10,7 +10,6 @@ TEST(SymbolProgram, SymbolSizeBinder) { EXPECT_EQ(uniformValues.get().t, true); EXPECT_EQ(uniformValues.get().t, true); EXPECT_EQ(uniformValues.get().t, 12.0f); - EXPECT_EQ(uniformValues.get().t, 12.0f); binder = SymbolSizeBinder::create(1.0f, style::CameraFunction(style::ExponentialStops({ {0.0f, 8.0f}, @@ -20,7 +19,6 @@ TEST(SymbolProgram, SymbolSizeBinder) { EXPECT_EQ(uniformValues.get().t, false); EXPECT_EQ(uniformValues.get().t, true); EXPECT_EQ(uniformValues.get().t, 9.5f); - EXPECT_EQ(uniformValues.get().t, 10.0f); binder = SymbolSizeBinder::create(0.0f, style::CameraFunction(style::ExponentialStops({ {1.0f, 8.0f}, @@ -30,7 +28,6 @@ TEST(SymbolProgram, SymbolSizeBinder) { EXPECT_EQ(uniformValues.get().t, false); EXPECT_EQ(uniformValues.get().t, true); EXPECT_EQ(uniformValues.get().t, 8.0f); - EXPECT_EQ(uniformValues.get().t, 8.0f); binder = SymbolSizeBinder::create(12.0f, style::CameraFunction(style::ExponentialStops({ {1.0f, 8.0f}, @@ -40,7 +37,6 @@ TEST(SymbolProgram, SymbolSizeBinder) { EXPECT_EQ(uniformValues.get().t, false); EXPECT_EQ(uniformValues.get().t, true); EXPECT_EQ(uniformValues.get().t, 18.0f); - EXPECT_EQ(uniformValues.get().t, 18.0f); binder = SymbolSizeBinder::create(0.0f, style::SourceFunction("x", style::ExponentialStops({ {1.0f, 8.0f}, diff --git a/test/text/quads.test.cpp b/test/text/quads.test.cpp index efc3912aaa..f24b01ca87 100644 --- a/test/text/quads.test.cpp +++ b/test/text/quads.test.cpp @@ -23,10 +23,8 @@ TEST(getIconQuads, normal) { Shaping shapedText; SymbolQuad quad = - getIconQuad(anchor, shapedIcon, line, layout, 16.0f, SymbolPlacementType::Point, shapedText); + getIconQuad(shapedIcon, layout, 16.0f, shapedText); - EXPECT_EQ(quad.anchorPoint.x, 2); - EXPECT_EQ(quad.anchorPoint.y, 3); EXPECT_EQ(quad.tl.x, -14); EXPECT_EQ(quad.tl.y, -10); EXPECT_EQ(quad.tr.x, 1); @@ -35,9 +33,6 @@ TEST(getIconQuads, normal) { EXPECT_EQ(quad.bl.y, 1); EXPECT_EQ(quad.br.x, 1); EXPECT_EQ(quad.br.y, 1); - EXPECT_EQ(quad.anchorAngle, 0.0f); - EXPECT_EQ(quad.glyphAngle, 0.0f); - EXPECT_EQ(quad.minScale, 0.5f); } TEST(getIconQuads, style) { @@ -61,10 +56,8 @@ TEST(getIconQuads, style) { { SymbolLayoutProperties::Evaluated layout; SymbolQuad quad = - getIconQuad(anchor, shapedIcon, line, layout, 12.0f, SymbolPlacementType::Point, shapedText); + getIconQuad(shapedIcon, layout, 12.0f, shapedText); - EXPECT_EQ(quad.anchorPoint.x, 0); - EXPECT_EQ(quad.anchorPoint.y, 0); EXPECT_EQ(quad.tl.x, -19.5); EXPECT_EQ(quad.tl.y, -19.5); EXPECT_EQ(quad.tr.x, 0.5); @@ -73,9 +66,6 @@ TEST(getIconQuads, style) { EXPECT_EQ(quad.bl.y, 0.5); EXPECT_EQ(quad.br.x, 0.5); EXPECT_EQ(quad.br.y, 0.5); - EXPECT_EQ(quad.anchorAngle, 0.0f); - EXPECT_EQ(quad.glyphAngle, 0.0f); - EXPECT_EQ(quad.minScale, 0.5f); } // width @@ -84,7 +74,7 @@ TEST(getIconQuads, style) { layout.get() = 24.0f; layout.get() = IconTextFitType::Width; SymbolQuad quad = - getIconQuad(anchor, shapedIcon, line, layout, 24.0f, SymbolPlacementType::Point, shapedText); + getIconQuad(shapedIcon, layout, 24.0f, shapedText); EXPECT_EQ(quad.tl.x, -60); EXPECT_EQ(quad.tl.y, 0); @@ -102,7 +92,7 @@ TEST(getIconQuads, style) { layout.get() = 12.0f; layout.get() = IconTextFitType::Width; SymbolQuad quad = - getIconQuad(anchor, shapedIcon, line, layout, 12.0f, SymbolPlacementType::Point, shapedText); + getIconQuad(shapedIcon, layout, 12.0f, shapedText); EXPECT_EQ(quad.tl.x, -30); EXPECT_EQ(quad.tl.y, -5); @@ -124,7 +114,7 @@ TEST(getIconQuads, style) { layout.get()[2] = 5.0f; layout.get()[3] = 10.0f; SymbolQuad quad = - getIconQuad(anchor, shapedIcon, line, layout, 12.0f, SymbolPlacementType::Point, shapedText); + getIconQuad(shapedIcon, layout, 12.0f, shapedText); EXPECT_EQ(quad.tl.x, -40); EXPECT_EQ(quad.tl.y, -10); @@ -142,7 +132,7 @@ TEST(getIconQuads, style) { layout.get() = 24.0f; layout.get() = IconTextFitType::Height; SymbolQuad quad = - getIconQuad(anchor, shapedIcon, line, layout, 24.0f, SymbolPlacementType::Point, shapedText); + getIconQuad(shapedIcon, layout, 24.0f, shapedText); EXPECT_EQ(quad.tl.x, -30); EXPECT_EQ(quad.tl.y, -10); @@ -160,7 +150,7 @@ TEST(getIconQuads, style) { layout.get() = 12.0f; layout.get() = IconTextFitType::Height; SymbolQuad quad = - getIconQuad(anchor, shapedIcon, line, layout, 12.0f, SymbolPlacementType::Point, shapedText); + getIconQuad(shapedIcon, layout, 12.0f, shapedText); EXPECT_EQ(quad.tl.x, -20); EXPECT_EQ(quad.tl.y, -5); @@ -182,7 +172,7 @@ TEST(getIconQuads, style) { layout.get()[2] = 5.0f; layout.get()[3] = 10.0f; SymbolQuad quad = - getIconQuad(anchor, shapedIcon, line, layout, 12.0f, SymbolPlacementType::Point, shapedText); + getIconQuad(shapedIcon, layout, 12.0f, shapedText); EXPECT_EQ(quad.tl.x, -30); EXPECT_EQ(quad.tl.y, -10); @@ -200,7 +190,7 @@ TEST(getIconQuads, style) { layout.get() = 24.0f; layout.get() = IconTextFitType::Both; SymbolQuad quad = - getIconQuad(anchor, shapedIcon, line, layout, 24.0f, SymbolPlacementType::Point, shapedText); + getIconQuad(shapedIcon, layout, 24.0f, shapedText); EXPECT_EQ(quad.tl.x, -60); EXPECT_EQ(quad.tl.y, -10); @@ -218,7 +208,7 @@ TEST(getIconQuads, style) { layout.get() = 12.0f; layout.get() = IconTextFitType::Both; SymbolQuad quad = - getIconQuad(anchor, shapedIcon, line, layout, 12.0f, SymbolPlacementType::Point, shapedText); + getIconQuad(shapedIcon, layout, 12.0f, shapedText); EXPECT_EQ(quad.tl.x, -30); EXPECT_EQ(quad.tl.y, -5); @@ -240,7 +230,7 @@ TEST(getIconQuads, style) { layout.get()[2] = 5.0f; layout.get()[3] = 10.0f; SymbolQuad quad = - getIconQuad(anchor, shapedIcon, line, layout, 12.0f, SymbolPlacementType::Point, shapedText); + getIconQuad(shapedIcon, layout, 12.0f, shapedText); EXPECT_EQ(quad.tl.x, -40); EXPECT_EQ(quad.tl.y, -10); @@ -262,7 +252,7 @@ TEST(getIconQuads, style) { layout.get()[2] = 10.0f; layout.get()[3] = 15.0f; SymbolQuad quad = - getIconQuad(anchor, shapedIcon, line, layout, 12.0f, SymbolPlacementType::Point, shapedText); + getIconQuad(shapedIcon, layout, 12.0f, shapedText); EXPECT_EQ(quad.tl.x, -45); EXPECT_EQ(quad.tl.y, -5); -- cgit v1.2.1 From d661b4ba61a7bd7770c96464c190bfadf9a42414 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Fri, 30 Jun 2017 15:38:43 -0400 Subject: [core] port pitch-label collision hack https://github.com/mapbox/mapbox-gl-js/pull/4781/commits/81363951ed56c54f331ffc8d88e4e5079226a224 --- src/mbgl/text/collision_feature.cpp | 30 +++++++++++++++++++++++++----- src/mbgl/text/collision_feature.hpp | 9 +++++++-- src/mbgl/text/collision_tile.cpp | 29 +++++++++++++++++------------ src/mbgl/text/collision_tile.hpp | 2 +- 4 files changed, 50 insertions(+), 20 deletions(-) diff --git a/src/mbgl/text/collision_feature.cpp b/src/mbgl/text/collision_feature.cpp index 58a7949a8e..022ee50644 100644 --- a/src/mbgl/text/collision_feature.cpp +++ b/src/mbgl/text/collision_feature.cpp @@ -42,7 +42,7 @@ CollisionFeature::CollisionFeature(const GeometryCoordinates& line, bboxifyLabel(line, anchorPoint, anchor.segment, length, height); } } else { - boxes.emplace_back(anchor.point, x1, y1, x2, y2, std::numeric_limits::infinity()); + boxes.emplace_back(anchor.point, Point{ 0, 0 }, x1, y1, x2, y2, std::numeric_limits::infinity()); } } @@ -50,10 +50,10 @@ void CollisionFeature::bboxifyLabel(const GeometryCoordinates& line, GeometryCoo const int segment, const float labelLength, const float boxSize) { const float step = boxSize / 2; const int nBoxes = std::floor(labelLength / step); - // We calculate line collision boxes out to 150% of what would normally be our + // We calculate line collision boxes out to 300% of what would normally be our // max size, to allow collision detection to work on labels that expand as // they move into the distance - const int nPitchPaddingBoxes = std::floor(nBoxes / 4); + const int nPitchPaddingBoxes = std::floor(nBoxes / 2); // offset the center of the first box by half a box so that the edge of the // box is at the edge of the label. @@ -90,7 +90,13 @@ void CollisionFeature::bboxifyLabel(const GeometryCoordinates& line, GeometryCoo for (int i = -nPitchPaddingBoxes; i < nBoxes + nPitchPaddingBoxes; i++) { // the distance the box will be from the anchor - const float boxDistanceToAnchor = labelStartDistance + i * step; + const float boxOffset = i * step; + float boxDistanceToAnchor = labelStartDistance + boxOffset; + + // make the distance between pitch padding boxes bigger + if (boxOffset < 0) boxDistanceToAnchor += boxOffset; + if (boxOffset > labelLength) boxDistanceToAnchor += boxOffset - labelLength; + if (boxDistanceToAnchor < anchorDistance) { // The line doesn't extend far enough back for this box, skip it // (This could allow for line collisions on distant tiles) @@ -143,8 +149,22 @@ void CollisionFeature::bboxifyLabel(const GeometryCoordinates& line, GeometryCoo maxScale = std::min(maxScale, 0.99f); } - boxes.emplace_back(boxAnchor, -boxSize / 2, -boxSize / 2, boxSize / 2, boxSize / 2, maxScale); + boxes.emplace_back(boxAnchor, boxAnchor - convertPoint(anchorPoint), -boxSize / 2, -boxSize / 2, boxSize / 2, boxSize / 2, maxScale); } } +float CollisionBox::adjustedMaxScale(const std::array& rotationMatrix, const float yStretch) const { + // When the map is pitched the distance covered by a line changes. + // Adjust the max scale by (approximatePitchedLength / approximateRegularLength) + // to compensate for this. + const Point rotatedOffset = util::matrixMultiply(rotationMatrix, offset); + const float xSqr = rotatedOffset.x * rotatedOffset.x; + const float ySqr = rotatedOffset.y * rotatedOffset.y; + const float yStretchSqr = ySqr * yStretch * yStretch; + const float adjustmentFactor = xSqr + ySqr != 0 ? + std::sqrt((xSqr + yStretchSqr) / (xSqr + ySqr)) : + 1.0f; + return maxScale * adjustmentFactor; +} + } // namespace mbgl diff --git a/src/mbgl/text/collision_feature.hpp b/src/mbgl/text/collision_feature.hpp index c94ec23513..3b6e461a26 100644 --- a/src/mbgl/text/collision_feature.hpp +++ b/src/mbgl/text/collision_feature.hpp @@ -11,11 +11,16 @@ namespace mbgl { class CollisionBox { public: - CollisionBox(Point _anchor, float _x1, float _y1, float _x2, float _y2, float _maxScale) : - anchor(std::move(_anchor)), x1(_x1), y1(_y1), x2(_x2), y2(_y2), maxScale(_maxScale) {} + CollisionBox(Point _anchor, Point _offset, float _x1, float _y1, float _x2, float _y2, float _maxScale) : + anchor(std::move(_anchor)), offset(_offset), x1(_x1), y1(_y1), x2(_x2), y2(_y2), maxScale(_maxScale) {} + + float adjustedMaxScale(const std::array& rotationMatrix, const float yStretch) const; // the box is centered around the anchor point Point anchor; + + // the offset of the box from the label's anchor point + Point offset; // distances to the edges from the anchor float x1; diff --git a/src/mbgl/text/collision_tile.cpp b/src/mbgl/text/collision_tile.cpp index 520f66ead8..b3fbe6f8a3 100644 --- a/src/mbgl/text/collision_tile.cpp +++ b/src/mbgl/text/collision_tile.cpp @@ -34,7 +34,7 @@ CollisionTile::CollisionTile(PlacementConfig config_) : config(std::move(config_ } -float CollisionTile::findPlacementScale(const Point& anchor, const CollisionBox& box, const Point& blockingAnchor, const CollisionBox& blocking) { +float CollisionTile::findPlacementScale(const Point& anchor, const CollisionBox& box, const float boxMaxScale, const Point& blockingAnchor, const CollisionBox& blocking) { float minPlacementScale = minScale; // Find the lowest scale at which the two boxes can fit side by side without overlapping. @@ -55,10 +55,10 @@ float CollisionTile::findPlacementScale(const Point& anchor, const Collis collisionFreeScale = blocking.maxScale; } - if (collisionFreeScale > box.maxScale) { + if (collisionFreeScale > boxMaxScale) { // If the box can only be shown after it is visible, then the box can never be shown. // But the label can be shown after this box is not visible. - collisionFreeScale = box.maxScale; + collisionFreeScale = boxMaxScale; } if (collisionFreeScale > minPlacementScale && @@ -77,13 +77,13 @@ float CollisionTile::placeFeature(const CollisionFeature& feature, bool allowOve static const float infinity = std::numeric_limits::infinity(); static const std::array edges {{ // left - CollisionBox(Point(0, 0), 0, -infinity, 0, infinity, infinity), + CollisionBox(Point(0, 0), { 0, 0 }, 0, -infinity, 0, infinity, infinity), // right - CollisionBox(Point(util::EXTENT, 0), 0, -infinity, 0, infinity, infinity), + CollisionBox(Point(util::EXTENT, 0), { 0, 0 }, 0, -infinity, 0, infinity, infinity), // top - CollisionBox(Point(0, 0), -infinity, 0, infinity, 0, infinity), + CollisionBox(Point(0, 0), { 0, 0 }, -infinity, 0, infinity, 0, infinity), // bottom - CollisionBox(Point(0, util::EXTENT), -infinity, 0, infinity, 0, infinity) + CollisionBox(Point(0, util::EXTENT), { 0, 0 }, -infinity, 0, infinity, 0, infinity) }}; float minPlacementScale = minScale; @@ -91,12 +91,14 @@ float CollisionTile::placeFeature(const CollisionFeature& feature, bool allowOve for (auto& box : feature.boxes) { const auto anchor = util::matrixMultiply(rotationMatrix, box.anchor); + const float boxMaxScale = box.adjustedMaxScale(rotationMatrix, yStretch); + if (!allowOverlap) { for (auto it = tree.qbegin(bgi::intersects(getTreeBox(anchor, box))); it != tree.qend(); ++it) { const CollisionBox& blocking = std::get<1>(*it); Point blockingAnchor = util::matrixMultiply(rotationMatrix, blocking.anchor); - minPlacementScale = util::max(minPlacementScale, findPlacementScale(anchor, box, blockingAnchor, blocking)); + minPlacementScale = util::max(minPlacementScale, findPlacementScale(anchor, box, boxMaxScale, blockingAnchor, blocking)); if (minPlacementScale >= maxScale) return minPlacementScale; } } @@ -107,14 +109,15 @@ float CollisionTile::placeFeature(const CollisionFeature& feature, bool allowOve const Point rbl = util::matrixMultiply(reverseRotationMatrix, { box.x1, box.y2 }); const Point rbr = util::matrixMultiply(reverseRotationMatrix, { box.x2, box.y2 }); CollisionBox rotatedBox(box.anchor, + box.offset, util::min(rtl.x, rtr.x, rbl.x, rbr.x), util::min(rtl.y, rtr.y, rbl.y, rbr.y), util::max(rtl.x, rtr.x, rbl.x, rbr.x), util::max(rtl.y, rtr.y, rbl.y, rbr.y), - box.maxScale); + boxMaxScale); for (auto& blocking : edges) { - minPlacementScale = util::max(minPlacementScale, findPlacementScale(box.anchor, rotatedBox, blocking.anchor, blocking)); + minPlacementScale = util::max(minPlacementScale, findPlacementScale(box.anchor, rotatedBox, boxMaxScale, blocking.anchor, blocking)); if (minPlacementScale >= maxScale) return minPlacementScale; } } @@ -131,7 +134,9 @@ void CollisionTile::insertFeature(CollisionFeature& feature, float minPlacementS if (minPlacementScale < maxScale) { std::vector treeBoxes; for (auto& box : feature.boxes) { - treeBoxes.emplace_back(getTreeBox(util::matrixMultiply(rotationMatrix, box.anchor), box), box, feature.indexedFeature); + CollisionBox adjustedBox = box; + box.maxScale = box.adjustedMaxScale(rotationMatrix, yStretch); + treeBoxes.emplace_back(getTreeBox(util::matrixMultiply(rotationMatrix, box.anchor), box), std::move(adjustedBox), feature.indexedFeature); } if (ignorePlacement) { ignoredTree.insert(treeBoxes.begin(), treeBoxes.end()); @@ -215,7 +220,7 @@ std::vector CollisionTile::queryRenderedSymbols(const Geometr // Check if feature is rendered (collision free) at current scale. auto visibleAtScale = [&] (const CollisionTreeBox& treeBox) -> bool { const CollisionBox& box = std::get<1>(treeBox); - return roundedScale >= box.placementScale && roundedScale <= box.maxScale; + return roundedScale >= box.placementScale && roundedScale <= box.adjustedMaxScale(rotationMatrix, yStretch); }; // Check if query polygon intersects with the feature box at current scale. diff --git a/src/mbgl/text/collision_tile.hpp b/src/mbgl/text/collision_tile.hpp index dbff6a007b..9868266aa2 100644 --- a/src/mbgl/text/collision_tile.hpp +++ b/src/mbgl/text/collision_tile.hpp @@ -58,7 +58,7 @@ public: private: float findPlacementScale( - const Point& anchor, const CollisionBox& box, + const Point& anchor, const CollisionBox& box, const float boxMaxScale, const Point& blockingAnchor, const CollisionBox& blocking); Box getTreeBox(const Point& anchor, const CollisionBox& box, const float scale = 1.0); -- cgit v1.2.1 From eac297185da7c34c69c5265b6cb8c193d5537e61 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Fri, 7 Jul 2017 10:45:34 -0400 Subject: [core] add static asserts for more gl constants and rename BufferUsageType to BufferUsage --- src/mbgl/gl/context.cpp | 49 ++++++++++++++++++++++++++++- src/mbgl/gl/context.hpp | 4 +-- src/mbgl/gl/types.hpp | 2 +- src/mbgl/renderer/buckets/symbol_bucket.cpp | 4 +-- 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index 3508b92a79..86ca9c0607 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -16,6 +16,31 @@ namespace gl { static_assert(underlying_type(ShaderType::Vertex) == GL_VERTEX_SHADER, "OpenGL type mismatch"); static_assert(underlying_type(ShaderType::Fragment) == GL_FRAGMENT_SHADER, "OpenGL type mismatch"); +static_assert(underlying_type(DataType::Byte) == GL_BYTE, "OpenGL type mismatch"); +static_assert(underlying_type(DataType::UnsignedByte) == GL_UNSIGNED_BYTE, "OpenGL type mismatch"); +static_assert(underlying_type(DataType::Short) == GL_SHORT, "OpenGL type mismatch"); +static_assert(underlying_type(DataType::UnsignedShort) == GL_UNSIGNED_SHORT, "OpenGL type mismatch"); +static_assert(underlying_type(DataType::Integer) == GL_INT, "OpenGL type mismatch"); +static_assert(underlying_type(DataType::UnsignedInteger) == GL_UNSIGNED_INT, "OpenGL type mismatch"); +static_assert(underlying_type(DataType::Float) == GL_FLOAT, "OpenGL type mismatch"); + +#if not MBGL_USE_GLES2 +static_assert(underlying_type(RenderbufferType::RGBA) == GL_RGBA8, "OpenGL type mismatch"); +#else +static_assert(underlying_type(RenderbufferType::RGBA) == GL_RGBA8_OES, "OpenGL type mismatch"); +#endif // MBGL_USE_GLES2 +#if not MBGL_USE_GLES2 +static_assert(underlying_type(RenderbufferType::DepthStencil) == GL_DEPTH24_STENCIL8, "OpenGL type mismatch"); +#else +static_assert(underlying_type(RenderbufferType::DepthStencil) == GL_DEPTH24_STENCIL8_OES, "OpenGL type mismatch"); +#endif // MBGL_USE_GLES2 +#if not MBGL_USE_GLES2 +static_assert(underlying_type(RenderbufferType::DepthComponent) == GL_DEPTH_COMPONENT, "OpenGL type mismatch"); +#else +static_assert(underlying_type(RenderbufferType::DepthComponent) == GL_DEPTH_COMPONENT16, "OpenGL type mismatch"); +#endif // MBGL_USE_GLES2 + + static_assert(underlying_type(PrimitiveType::Points) == GL_POINTS, "OpenGL type mismatch"); static_assert(underlying_type(PrimitiveType::Lines) == GL_LINES, "OpenGL type mismatch"); static_assert(underlying_type(PrimitiveType::LineLoop) == GL_LINE_LOOP, "OpenGL type mismatch"); @@ -36,6 +61,28 @@ static_assert(std::is_same, GLenum>::value static_assert(underlying_type(TextureFormat::RGBA) == GL_RGBA, "OpenGL type mismatch"); static_assert(underlying_type(TextureFormat::Alpha) == GL_ALPHA, "OpenGL type mismatch"); +static_assert(underlying_type(UniformDataType::Float) == GL_FLOAT, "OpenGL type mismatch"); +static_assert(underlying_type(UniformDataType::FloatVec2) == GL_FLOAT_VEC2, "OpenGL type mismatch"); +static_assert(underlying_type(UniformDataType::FloatVec3) == GL_FLOAT_VEC3, "OpenGL type mismatch"); +static_assert(underlying_type(UniformDataType::FloatVec4) == GL_FLOAT_VEC4, "OpenGL type mismatch"); +static_assert(underlying_type(UniformDataType::Int) == GL_INT, "OpenGL type mismatch"); +static_assert(underlying_type(UniformDataType::IntVec2) == GL_INT_VEC2, "OpenGL type mismatch"); +static_assert(underlying_type(UniformDataType::IntVec3) == GL_INT_VEC3, "OpenGL type mismatch"); +static_assert(underlying_type(UniformDataType::IntVec4) == GL_INT_VEC4, "OpenGL type mismatch"); +static_assert(underlying_type(UniformDataType::Bool) == GL_BOOL, "OpenGL type mismatch"); +static_assert(underlying_type(UniformDataType::BoolVec2) == GL_BOOL_VEC2, "OpenGL type mismatch"); +static_assert(underlying_type(UniformDataType::BoolVec3) == GL_BOOL_VEC3, "OpenGL type mismatch"); +static_assert(underlying_type(UniformDataType::BoolVec4) == GL_BOOL_VEC4, "OpenGL type mismatch"); +static_assert(underlying_type(UniformDataType::FloatMat2) == GL_FLOAT_MAT2, "OpenGL type mismatch"); +static_assert(underlying_type(UniformDataType::FloatMat3) == GL_FLOAT_MAT3, "OpenGL type mismatch"); +static_assert(underlying_type(UniformDataType::FloatMat4) == GL_FLOAT_MAT4, "OpenGL type mismatch"); +static_assert(underlying_type(UniformDataType::Sampler2D) == GL_SAMPLER_2D, "OpenGL type mismatch"); +static_assert(underlying_type(UniformDataType::SamplerCube) == GL_SAMPLER_CUBE, "OpenGL type mismatch"); + +static_assert(underlying_type(BufferUsage::StreamDraw) == GL_STREAM_DRAW, "OpenGL type mismatch"); +static_assert(underlying_type(BufferUsage::StaticDraw) == GL_STATIC_DRAW, "OpenGL type mismatch"); +static_assert(underlying_type(BufferUsage::DynamicDraw) == GL_DYNAMIC_DRAW, "OpenGL type mismatch"); + static_assert(std::is_same::value, "OpenGL type mismatch"); Context::Context() = default; @@ -164,7 +211,7 @@ void Context::verifyProgramLinkage(ProgramID program_) { throw std::runtime_error("program failed to link"); } -UniqueBuffer Context::createVertexBuffer(const void* data, std::size_t size, const BufferUsageType usage) { +UniqueBuffer Context::createVertexBuffer(const void* data, std::size_t size, const BufferUsage usage) { BufferID id = 0; MBGL_CHECK_ERROR(glGenBuffers(1, &id)); UniqueBuffer result { std::move(id), { this } }; diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index f1f0ac7f8a..2e594618d2 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -65,7 +65,7 @@ public: optional> getBinaryProgram(ProgramID) const; template - VertexBuffer createVertexBuffer(VertexVector&& v, const BufferUsageType usage=BufferUsageType::StaticDraw) { + VertexBuffer createVertexBuffer(VertexVector&& v, const BufferUsage usage=BufferUsage::StaticDraw) { return VertexBuffer { v.vertexSize(), createVertexBuffer(v.data(), v.byteSize(), usage) @@ -245,7 +245,7 @@ private: State pointSize; #endif // MBGL_USE_GLES2 - UniqueBuffer createVertexBuffer(const void* data, std::size_t size, const BufferUsageType usage); + UniqueBuffer createVertexBuffer(const void* data, std::size_t size, const BufferUsage usage); void updateVertexBuffer(UniqueBuffer& buffer, const void* data, std::size_t size); UniqueBuffer createIndexBuffer(const void* data, std::size_t size); UniqueTexture createTexture(Size size, const void* data, TextureFormat, TextureUnit); diff --git a/src/mbgl/gl/types.hpp b/src/mbgl/gl/types.hpp index 8997fcbf31..1fce878c6f 100644 --- a/src/mbgl/gl/types.hpp +++ b/src/mbgl/gl/types.hpp @@ -96,7 +96,7 @@ enum class UniformDataType : uint32_t { SamplerCube = 0x8B60, }; -enum class BufferUsageType : uint32_t { +enum class BufferUsage : uint32_t { StreamDraw = 0x88E0, StaticDraw = 0x88E4, DynamicDraw = 0x88E8, diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp index 194a5d6bd8..1bd73e95dd 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.cpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp @@ -38,13 +38,13 @@ SymbolBucket::SymbolBucket(style::SymbolLayoutProperties::PossiblyEvaluated layo void SymbolBucket::upload(gl::Context& context) { if (hasTextData()) { text.vertexBuffer = context.createVertexBuffer(std::move(text.vertices)); - text.dynamicVertexBuffer = context.createVertexBuffer(std::move(text.dynamicVertices), gl::BufferUsageType::StreamDraw); + text.dynamicVertexBuffer = context.createVertexBuffer(std::move(text.dynamicVertices), gl::BufferUsage::StreamDraw); text.indexBuffer = context.createIndexBuffer(std::move(text.triangles)); } if (hasIconData()) { icon.vertexBuffer = context.createVertexBuffer(std::move(icon.vertices)); - icon.dynamicVertexBuffer = context.createVertexBuffer(std::move(icon.dynamicVertices), gl::BufferUsageType::StreamDraw); + icon.dynamicVertexBuffer = context.createVertexBuffer(std::move(icon.dynamicVertices), gl::BufferUsage::StreamDraw); icon.indexBuffer = context.createIndexBuffer(std::move(icon.triangles)); } -- cgit v1.2.1 From 4f63a39b7c0dc24f8dd1a71783ea474815116467 Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Fri, 7 Jul 2017 12:25:21 -0700 Subject: [test] Bump mapbox-gl-js version to re-enable pitched tests --- mapbox-gl-js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapbox-gl-js b/mapbox-gl-js index 4fa52b9e3a..c2e061bda5 160000 --- a/mapbox-gl-js +++ b/mapbox-gl-js @@ -1 +1 @@ -Subproject commit 4fa52b9e3a0732c9a63f7d4221661a300c15c98f +Subproject commit c2e061bda532ea848ed39550fe3aa4f95847cc90 -- cgit v1.2.1 From d8cad639c66876357a8b0790c5ad68e091963b3e Mon Sep 17 00:00:00 2001 From: Tobrun Date: Wed, 12 Jul 2017 11:20:57 +0200 Subject: [android] - run style instrumentation tests on CI (#9353) --- circle.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index b866556d77..ba4885066e 100644 --- a/circle.yml +++ b/circle.yml @@ -99,6 +99,7 @@ jobs: rm secret.json - run: name: Run instrumentation tests on Firebase + no_output_timeout: 1200 shell: /bin/bash -euo pipefail command: | gcloud firebase test android models list @@ -106,7 +107,7 @@ jobs: --app platform/android/MapboxGLAndroidSDKTestApp/build/outputs/apk/MapboxGLAndroidSDKTestApp-debug.apk \ --test platform/android/MapboxGLAndroidSDKTestApp/build/outputs/apk/MapboxGLAndroidSDKTestApp-debug-androidTest.apk \ --device-ids shamu --os-version-ids 22 --locales en --orientations portrait --timeout 15m \ - --test-targets "class com.mapbox.mapboxsdk.testapp.maps.widgets.LogoTest" 2>&1 | tee firebase.log) || EXIT_CODE=$? + --test-targets "package com.mapbox.mapboxsdk.testapp.style" 2>&1 | tee firebase.log) || EXIT_CODE=$? FIREBASE_TEST_BUCKET=$(sed -n 's|^.*\[https://console.developers.google.com/storage/browser/\([^]]*\).*|gs://\1|p' firebase.log) echo "Downloading from: ${FIREBASE_TEST_BUCKET}" -- cgit v1.2.1 From 3b49ec3a0b4bab40ddb9a2a9789e787089870c93 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Sat, 6 Aug 2016 00:50:34 +0300 Subject: [core] Prefer std:: functions over POSIX s/unlink/std::remove --- src/mbgl/util/io.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mbgl/util/io.cpp b/src/mbgl/util/io.cpp index 9adc3b8988..6a6ed7b250 100644 --- a/src/mbgl/util/io.cpp +++ b/src/mbgl/util/io.cpp @@ -6,8 +6,6 @@ #include #include -#include - namespace mbgl { namespace util { @@ -43,8 +41,8 @@ optional readFile(const std::string &filename) { } void deleteFile(const std::string& filename) { - const int ret = unlink(filename.c_str()); - if (ret == -1) { + const int ret = std::remove(filename.c_str()); + if (ret != 0) { throw IOException(errno, "failed to unlink file"); } } -- cgit v1.2.1 From 0d7d3d895955dcf6f852b8eba8b146f7dddad529 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Sat, 6 Aug 2016 01:15:50 +0300 Subject: [core] Use std::to_string on Windows Clang on Window's can't parse rapidjson's dtoa. --- src/mbgl/util/dtoa.cpp | 14 ++++++++++++++ src/mbgl/util/dtoa.hpp | 1 - 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/mbgl/util/dtoa.cpp b/src/mbgl/util/dtoa.cpp index dd4fba0f89..6ca3e19c3d 100644 --- a/src/mbgl/util/dtoa.cpp +++ b/src/mbgl/util/dtoa.cpp @@ -1,10 +1,16 @@ #include "dtoa.hpp" +// Clang/C2 on Windows 64-bits can't parse rapidjson's dtoa +// and it was causing the compiler to crash. +#if !defined(_WINDOWS) #include +#endif namespace mbgl { namespace util { +#if !defined(_WINDOWS) + namespace { // From https://github.com/miloyip/rapidjson/blob/master/include/rapidjson/internal/dtoa.h @@ -101,5 +107,13 @@ std::string dtoa(double value) { return data; } +#else + +std::string dtoa(double value) { + return std::to_string(value); +} + +#endif + } // namespace util } // namespace mbgl diff --git a/src/mbgl/util/dtoa.hpp b/src/mbgl/util/dtoa.hpp index db7d309452..4cb81a94be 100644 --- a/src/mbgl/util/dtoa.hpp +++ b/src/mbgl/util/dtoa.hpp @@ -5,7 +5,6 @@ namespace mbgl { namespace util { -char* dtoa(double value, char* buffer); std::string dtoa(double value); } // end namespace util -- cgit v1.2.1 From 70e557a6f853f93f8ddab590b95196b2d0584a13 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Sat, 6 Aug 2016 01:34:20 +0300 Subject: [core] Use gmtime_s on Windows gmtime_r is POSIX --- src/mbgl/util/chrono.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/mbgl/util/chrono.cpp b/src/mbgl/util/chrono.cpp index 5c8fd3c0ff..a880093b74 100644 --- a/src/mbgl/util/chrono.cpp +++ b/src/mbgl/util/chrono.cpp @@ -3,6 +3,13 @@ #include #include +#include + +#if defined(_WINDOWS) +#define _gmtime(t, i) gmtime_s(i, t) +#else +#define _gmtime(t, i) gmtime_r(t, i) +#endif namespace mbgl { namespace util { @@ -14,7 +21,7 @@ static const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", std::string rfc1123(Timestamp timestamp) { std::time_t time = std::chrono::system_clock::to_time_t(timestamp); std::tm info; - gmtime_r(&time, &info); + _gmtime(&time, &info); char buffer[30]; snprintf(buffer, 30, "%s, %02d %s %4d %02d:%02d:%02d GMT", week[info.tm_wday], info.tm_mday, months[info.tm_mon], 1900 + info.tm_year, info.tm_hour, info.tm_min, info.tm_sec); @@ -24,7 +31,7 @@ std::string rfc1123(Timestamp timestamp) { std::string iso8601(Timestamp timestamp) { std::time_t time = std::chrono::system_clock::to_time_t(timestamp); std::tm info; - gmtime_r(&time, &info); + _gmtime(&time, &info); char buffer[30]; std::strftime(buffer, sizeof(buffer), "%F %T", &info); return buffer; -- cgit v1.2.1 From 40d66a84b3b90d24519055e7b57d1f253d365621 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Sat, 6 Aug 2016 01:44:39 +0300 Subject: [core] Do not use S_ISDIR Seems like Windows can do `stat()` but not S_ISDIR. --- platform/default/asset_file_source.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platform/default/asset_file_source.cpp b/platform/default/asset_file_source.cpp index 343f3b70ce..54dbb8d0f6 100644 --- a/platform/default/asset_file_source.cpp +++ b/platform/default/asset_file_source.cpp @@ -9,7 +9,6 @@ #include #include -#include namespace mbgl { @@ -35,7 +34,7 @@ public: struct stat buf; int result = stat(path.c_str(), &buf); - if (result == 0 && S_ISDIR(buf.st_mode)) { + if (result == 0 && (S_IFDIR & buf.st_mode)) { response.error = std::make_unique(Response::Error::Reason::NotFound); } else if (result == -1 && errno == ENOENT) { response.error = std::make_unique(Response::Error::Reason::NotFound); -- cgit v1.2.1 From 06719ae42f10d4152780b75173e32fb6f4bb7633 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Wed, 12 Jul 2017 14:09:59 +0300 Subject: [benchmark] Add a benchmark for our dtoa implementation Make sure it is faster than std::to_value(). And it is, by ~30% for the normal use case, and much faster when close to the double limits. util::dtoa also offers a much better precision. --- benchmark/fixtures/api/cache.db | Bin 1298432 -> 1298432 bytes benchmark/util/dtoa.benchmark.cpp | 66 ++++++++++++++++++++++++++++++++++++++ cmake/benchmark-files.cmake | 3 ++ 3 files changed, 69 insertions(+) create mode 100644 benchmark/util/dtoa.benchmark.cpp diff --git a/benchmark/fixtures/api/cache.db b/benchmark/fixtures/api/cache.db index c2ada1fbd5..6a1d60421f 100644 Binary files a/benchmark/fixtures/api/cache.db and b/benchmark/fixtures/api/cache.db differ diff --git a/benchmark/util/dtoa.benchmark.cpp b/benchmark/util/dtoa.benchmark.cpp new file mode 100644 index 0000000000..0009c6dd15 --- /dev/null +++ b/benchmark/util/dtoa.benchmark.cpp @@ -0,0 +1,66 @@ +#include + +#include + +#include +#include + +using namespace mbgl; + +static void Util_dtoa(::benchmark::State& state) { + while (state.KeepRunning()) { + util::dtoa(0.); + util::dtoa(M_E); + util::dtoa(M_LOG2E); + util::dtoa(M_LOG10E); + util::dtoa(M_LN2); + util::dtoa(M_LN10); + util::dtoa(M_PI); + util::dtoa(M_PI_2); + util::dtoa(M_PI_4); + util::dtoa(M_1_PI); + util::dtoa(M_2_PI); + util::dtoa(M_2_SQRTPI); + util::dtoa(M_SQRT2); + util::dtoa(M_SQRT1_2); + } +} + +static void Util_standardDtoa(::benchmark::State& state) { + while (state.KeepRunning()) { + std::to_string(0.); + std::to_string(M_E); + std::to_string(M_LOG2E); + std::to_string(M_LOG10E); + std::to_string(M_LN2); + std::to_string(M_LN10); + std::to_string(M_PI); + std::to_string(M_PI_2); + std::to_string(M_PI_4); + std::to_string(M_1_PI); + std::to_string(M_2_PI); + std::to_string(M_2_SQRTPI); + std::to_string(M_SQRT2); + std::to_string(M_SQRT1_2); + } +} + +static void Util_dtoaLimits(::benchmark::State& state) { + while (state.KeepRunning()) { + util::dtoa(DBL_MIN); + util::dtoa(DBL_MAX); + } +} + +static void Util_standardDtoaLimits(::benchmark::State& state) { + while (state.KeepRunning()) { + std::to_string(DBL_MIN); + std::to_string(DBL_MAX); + } +} + +BENCHMARK(Util_dtoa); +BENCHMARK(Util_standardDtoa); + +BENCHMARK(Util_dtoaLimits); +BENCHMARK(Util_standardDtoaLimits); diff --git a/cmake/benchmark-files.cmake b/cmake/benchmark-files.cmake index 35931a6b52..6fb9a80d57 100644 --- a/cmake/benchmark-files.cmake +++ b/cmake/benchmark-files.cmake @@ -19,4 +19,7 @@ set(MBGL_BENCHMARK_FILES benchmark/src/mbgl/benchmark/benchmark.cpp benchmark/src/mbgl/benchmark/util.cpp benchmark/src/mbgl/benchmark/util.hpp + + # util + benchmark/util/dtoa.benchmark.cpp ) -- cgit v1.2.1 From 32bef80eec204c22a2b37bb6534bc02d24fa68c7 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Wed, 12 Jul 2017 14:16:39 +0300 Subject: [test] Add utest to assert our dtoa implementation precision --- cmake/test-files.cmake | 1 + test/util/dtoa.test.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 test/util/dtoa.test.cpp diff --git a/cmake/test-files.cmake b/cmake/test-files.cmake index 4dec9e403d..cdca1db280 100644 --- a/cmake/test-files.cmake +++ b/cmake/test-files.cmake @@ -120,6 +120,7 @@ set(MBGL_TEST_FILES # util test/util/async_task.test.cpp + test/util/dtoa.test.cpp test/util/geo.test.cpp test/util/http_timeout.test.cpp test/util/image.test.cpp diff --git a/test/util/dtoa.test.cpp b/test/util/dtoa.test.cpp new file mode 100644 index 0000000000..8d2fba1877 --- /dev/null +++ b/test/util/dtoa.test.cpp @@ -0,0 +1,24 @@ +#include + +#include + +#include +#include + +using namespace mbgl; + +TEST(Dtoa, Precision) { + EXPECT_EQ(M_E, std::stod(util::dtoa(M_E))); + EXPECT_EQ(M_LOG2E, std::stod(util::dtoa(M_LOG2E))); + EXPECT_EQ(M_LOG10E, std::stod(util::dtoa(M_LOG10E))); + EXPECT_EQ(M_LN2, std::stod(util::dtoa(M_LN2))); + EXPECT_EQ(M_LN10, std::stod(util::dtoa(M_LN10))); + EXPECT_EQ(M_PI, std::stod(util::dtoa(M_PI))); + EXPECT_EQ(M_PI_2, std::stod(util::dtoa(M_PI_2))); + EXPECT_EQ(M_PI_4, std::stod(util::dtoa(M_PI_4))); + EXPECT_EQ(M_1_PI, std::stod(util::dtoa(M_1_PI))); + EXPECT_EQ(M_2_PI, std::stod(util::dtoa(M_2_PI))); + EXPECT_EQ(M_2_SQRTPI, std::stod(util::dtoa(M_2_SQRTPI))); + EXPECT_EQ(M_SQRT2, std::stod(util::dtoa(M_SQRT2))); + EXPECT_EQ(M_SQRT1_2, std::stod(util::dtoa(M_SQRT1_2))); +} -- cgit v1.2.1 From 3aa807e1dc3c260ea5fb870c119610fc152b9153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Wed, 12 Jul 2017 15:24:12 +0200 Subject: [core] add LLDB summaries for types we use commonly --- scripts/lldb-types | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 scripts/lldb-types diff --git a/scripts/lldb-types b/scripts/lldb-types new file mode 100644 index 0000000000..fd6ae33830 --- /dev/null +++ b/scripts/lldb-types @@ -0,0 +1,15 @@ +type summary add "mbgl::CanonicalTileID" --summary-string "${var.z%u}/${var.x}/${var.y}" +type summary add "mbgl::UnwrappedTileID" --summary-string "${var.canonical}+${var.wrap}" +type summary add "mbgl::OverscaledTileID" --summary-string "${var.canonical}=>${var.overscaledZ%u}" + +type summary add -e -x "^mbgl::Range<.+>$" --summary-string "${var.min%d} ⇒ ${var.max%d}" +type summary add -e -x "^mbgl::Rect<.+>$" --summary-string "Size: ${var.w%d}×${var.h%d} — Offset: ${var.x}/${var.y}" +type summary add "mbgl::Size" --summary-string "${var.width}/${var.height}" +type summary add "mbgl::LatLng" --summary-string "${var.lat}/${var.lon}" + +type summary add "mbgl::Color" --summary-string "${var.r}, ${var.g}, ${var.b}, ${var.a}" + +type summary add -e -x "^mbgl::Point<.+>$" --summary-string "${var.x}/${var.y}" +type summary add -e -x "^mapbox::geometry::point<.+>$" --summary-string "${var.x}/${var.y}" + +type summary add -e -x "^mbgl::optional<.+>$" --python-script "return valobj.GetChildAtIndex(0).GetChildAtIndex(0).GetChildAtIndex(1).GetValue() if valobj.GetChildMemberWithName('__engaged_').unsigned > 0 else ''" -- cgit v1.2.1 From c163402f641c9d9b86d5851c6acfbe11c400f15b Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Fri, 7 Jul 2017 15:02:40 +0300 Subject: [build] Added Linux GCC 4.9 CI bot --- CMakeLists.txt | 8 ++++---- circle.yml | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 694147fc8f..033c289018 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,23 +42,23 @@ endif() set_source_files_properties(src/mbgl/util/version.cpp PROPERTIES COMPILE_DEFINITIONS MBGL_VERSION_REV="${MBGL_VERSION_REV}") -mason_use(geometry VERSION 0.9.0 HEADER_ONLY) +mason_use(geometry VERSION 0.9.2 HEADER_ONLY) mason_use(variant VERSION 1.1.4 HEADER_ONLY) mason_use(any VERSION 8fef1e9 HEADER_ONLY) mason_use(unique_resource VERSION cba309e HEADER_ONLY) mason_use(rapidjson VERSION 1.1.0 HEADER_ONLY) mason_use(boost VERSION 1.62.0 HEADER_ONLY) mason_use(geojsonvt VERSION 6.2.0 HEADER_ONLY) -mason_use(supercluster VERSION 0.2.0-1 HEADER_ONLY) +mason_use(supercluster VERSION 0.2.1 HEADER_ONLY) mason_use(kdbush VERSION 0.1.1-1 HEADER_ONLY) mason_use(earcut VERSION 0.12.3 HEADER_ONLY) -mason_use(protozero VERSION 1.4.2 HEADER_ONLY) +mason_use(protozero VERSION 1.5.2 HEADER_ONLY) mason_use(pixelmatch VERSION 0.10.0 HEADER_ONLY) mason_use(geojson VERSION 0.4.0 HEADER_ONLY) mason_use(polylabel VERSION 1.0.2 HEADER_ONLY) mason_use(wagyu VERSION 0.4.1 HEADER_ONLY) mason_use(shelf-pack VERSION 2.1.0 HEADER_ONLY) -mason_use(cheap-ruler VERSION 2.5.1 HEADER_ONLY) +mason_use(cheap-ruler VERSION 2.5.3 HEADER_ONLY) mason_use(vector-tile VERSION 1.0.0-rc6 HEADER_ONLY) add_definitions(-DRAPIDJSON_HAS_STDSTRING=1) diff --git a/circle.yml b/circle.yml index ba4885066e..6620a44541 100644 --- a/circle.yml +++ b/circle.yml @@ -11,6 +11,7 @@ workflows: - node6-clang39-release - node6-clang39-debug - linux-clang39-debug + - linux-gcc4.9-debug - linux-gcc5-debug-coverage - linux-gcc5-release-qt4 - linux-gcc5-release-qt5 @@ -349,6 +350,47 @@ jobs: - node_modules - /root/.ccache +# ------------------------------------------------------------------------------ + linux-gcc4.9-debug: + docker: + - image: mbgl/ci:r3-linux-gcc-4.9 + working_directory: /src + environment: + LIBSYSCONFCPUS: 6 + JOBS: 2 + BUILDTYPE: Debug + WITH_EGL: 1 + WITH_CXX11ABI: 0 + DISPLAY: :0 + steps: + - checkout + - restore_cache: + key: v1-linux-gcc4.9-debug + paths: + - node_modules + - /root/.ccache + - run: + name: Build linux + command: make linux + - run: + name: Build benchmark + command: make benchmark + - run: + name: Build test + command: make test + - run: + name: Run tests + command: | + source scripts/circle_setup.sh + mapbox_export_mesa_library_path + xvfb-run --server-args="-screen 0 1024x768x24" \ + make run-test + - save_cache: + key: v1-linux-gcc4.9-debug + paths: + - node_modules + - /root/.ccache + # ------------------------------------------------------------------------------ linux-gcc5-debug-coverage: docker: -- cgit v1.2.1 From 2954a2a40d1078c3e3772e86ad97796e5d94a9ca Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Mon, 10 Jul 2017 18:20:26 +0300 Subject: [build] OSX build fix for GCC 4.9 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 033c289018..0acc58004c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,7 +71,7 @@ endif(WITH_COVERAGE) set(CMAKE_CONFIGURATION_TYPES Debug Release) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -ftemplate-depth=1024 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Werror -Wno-variadic-macros -Wno-unknown-pragmas") -if(APPLE) +if(APPLE AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") # -Wno-error=unused-command-line-argument is required due to https://llvm.org/bugs/show_bug.cgi?id=7798 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=unused-command-line-argument") endif() -- cgit v1.2.1 From 8af593f89c4686226171167f101694823e1a14f0 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Wed, 12 Jul 2017 16:44:16 +0300 Subject: [build] Reuse precomputed WITH_CXX11ABI definition in Qt builds --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 3a710a1cc1..789825903a 100644 --- a/Makefile +++ b/Makefile @@ -376,7 +376,7 @@ $(QT_BUILD): $(BUILD_DEPS) -DWITH_QT_DECODERS=${WITH_QT_DECODERS} \ -DWITH_QT_I18N=${WITH_QT_I18N} \ -DWITH_QT_4=${WITH_QT_4} \ - -DWITH_CXX11ABI=$(shell scripts/check-cxx11abi.sh) \ + -DWITH_CXX11ABI=${WITH_CXX11ABI} \ -DWITH_COVERAGE=${WITH_COVERAGE}) ifeq ($(HOST_PLATFORM), macos) @@ -392,7 +392,7 @@ $(MACOS_QT_PROJ_PATH): $(BUILD_DEPS) -DWITH_QT_DECODERS=${WITH_QT_DECODERS} \ -DWITH_QT_I18N=${WITH_QT_I18N} \ -DWITH_QT_4=${WITH_QT_4} \ - -DWITH_CXX11ABI=$(shell scripts/check-cxx11abi.sh) \ + -DWITH_CXX11ABI=${WITH_CXX11ABI} \ -DWITH_COVERAGE=${WITH_COVERAGE}) .PHONY: qtproj -- cgit v1.2.1 From 1aacc88f350d2d54337cdacb1a653785c759586b Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Fri, 7 Jul 2017 17:08:42 +0300 Subject: [core] GCC 4.9 does not allow using another member in a constexpr ctor --- include/mbgl/util/unitbezier.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/mbgl/util/unitbezier.hpp b/include/mbgl/util/unitbezier.hpp index 3a4994917b..6e644e2d1f 100644 --- a/include/mbgl/util/unitbezier.hpp +++ b/include/mbgl/util/unitbezier.hpp @@ -34,11 +34,11 @@ struct UnitBezier { // Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1). constexpr UnitBezier(double p1x, double p1y, double p2x, double p2y) : cx(3.0 * p1x) - , bx(3.0 * (p2x - p1x) - cx) - , ax(1.0 - cx - bx) + , bx(3.0 * (p2x - p1x) - (3.0 * p1x)) + , ax(1.0 - (3.0 * p1x) - (3.0 * (p2x - p1x) - (3.0 * p1x))) , cy(3.0 * p1y) - , by(3.0 * (p2y - p1y) - cy) - , ay(1.0 - cy - by) { + , by(3.0 * (p2y - p1y) - (3.0 * p1y)) + , ay(1.0 - (3.0 * p1y) - (3.0 * (p2y - p1y) - (3.0 * p1y))) { } double sampleCurveX(double t) const { -- cgit v1.2.1 From f1ac757bd28351fd57113a1e16f6c2e00ab193c1 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Tue, 11 Jul 2017 15:11:14 +0300 Subject: [core] GCC 4.9 does not fully support custom variable templates --- include/mbgl/style/conversion/function.hpp | 2 +- include/mbgl/style/function/camera_function.hpp | 2 +- include/mbgl/style/function/composite_function.hpp | 4 ++-- include/mbgl/style/function/source_function.hpp | 2 +- include/mbgl/util/indexed_tuple.hpp | 7 ++----- include/mbgl/util/interpolate.hpp | 6 +++++- src/mbgl/gl/attribute.cpp | 20 +++++++++++--------- src/mbgl/gl/attribute.hpp | 5 +---- 8 files changed, 24 insertions(+), 24 deletions(-) diff --git a/include/mbgl/style/conversion/function.hpp b/include/mbgl/style/conversion/function.hpp index bf5b27a9a6..752b6dd045 100644 --- a/include/mbgl/style/conversion/function.hpp +++ b/include/mbgl/style/conversion/function.hpp @@ -156,7 +156,7 @@ struct StopsConverter> { public: template optional> operator()(const V& value, Error& error) const { - std::string type = util::Interpolatable ? "exponential" : "interval"; + std::string type = util::Interpolatable::value ? "exponential" : "interval"; auto typeValue = objectMember(value, "type"); if (typeValue && toString(*typeValue)) { diff --git a/include/mbgl/style/function/camera_function.hpp b/include/mbgl/style/function/camera_function.hpp index 0fd5bcb078..7fde365b3d 100644 --- a/include/mbgl/style/function/camera_function.hpp +++ b/include/mbgl/style/function/camera_function.hpp @@ -12,7 +12,7 @@ template class CameraFunction { public: using Stops = std::conditional_t< - util::Interpolatable, + util::Interpolatable::value, variant< ExponentialStops, IntervalStops>, diff --git a/include/mbgl/style/function/composite_function.hpp b/include/mbgl/style/function/composite_function.hpp index 43599cd333..7b524b6021 100644 --- a/include/mbgl/style/function/composite_function.hpp +++ b/include/mbgl/style/function/composite_function.hpp @@ -24,7 +24,7 @@ template class CompositeFunction { public: using InnerStops = std::conditional_t< - util::Interpolatable, + util::Interpolatable::value, variant< ExponentialStops, IntervalStops, @@ -34,7 +34,7 @@ public: CategoricalStops>>; using Stops = std::conditional_t< - util::Interpolatable, + util::Interpolatable::value, variant< CompositeExponentialStops, CompositeIntervalStops, diff --git a/include/mbgl/style/function/source_function.hpp b/include/mbgl/style/function/source_function.hpp index 2872c63a64..9c2ad101ec 100644 --- a/include/mbgl/style/function/source_function.hpp +++ b/include/mbgl/style/function/source_function.hpp @@ -16,7 +16,7 @@ template class SourceFunction { public: using Stops = std::conditional_t< - util::Interpolatable, + util::Interpolatable::value, variant< ExponentialStops, IntervalStops, diff --git a/include/mbgl/util/indexed_tuple.hpp b/include/mbgl/util/indexed_tuple.hpp index a414639530..fd0b931d36 100644 --- a/include/mbgl/util/indexed_tuple.hpp +++ b/include/mbgl/util/indexed_tuple.hpp @@ -30,17 +30,14 @@ public: using std::tuple::tuple; - template - static constexpr std::size_t Index = TypeIndex::value; - template auto& get() { - return std::get>(*this); + return std::get::value>(*this); } template const auto& get() const { - return std::get>(*this); + return std::get::value>(*this); } template diff --git a/include/mbgl/util/interpolate.hpp b/include/mbgl/util/interpolate.hpp index a2103f18b2..6738987598 100644 --- a/include/mbgl/util/interpolate.hpp +++ b/include/mbgl/util/interpolate.hpp @@ -95,7 +95,11 @@ struct Interpolator> : Uninterpolated {}; template -constexpr bool Interpolatable = !std::is_base_of>::value; +struct Interpolatable + : std::conditional_t< + !std::is_base_of>::value, + std::true_type, + std::false_type> {}; } // namespace util } // namespace mbgl diff --git a/src/mbgl/gl/attribute.cpp b/src/mbgl/gl/attribute.cpp index 4e6f78e689..4569e3cb32 100644 --- a/src/mbgl/gl/attribute.cpp +++ b/src/mbgl/gl/attribute.cpp @@ -55,14 +55,16 @@ void DisabledAttribute::bind(Context&, AttributeLocation location, std::size_t) MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); } -template DataType DataTypeOf = static_cast(0); -template <> DataType DataTypeOf< int8_t> = DataType::Byte; -template <> DataType DataTypeOf = DataType::UnsignedByte; -template <> DataType DataTypeOf< int16_t> = DataType::Short; -template <> DataType DataTypeOf = DataType::UnsignedShort; -template <> DataType DataTypeOf< int32_t> = DataType::Integer; -template <> DataType DataTypeOf = DataType::UnsignedInteger; -template <> DataType DataTypeOf = DataType::Float; +template +constexpr DataType DataTypeOf() { + return std::is_same::value ? DataType::Byte : + std::is_same::value ? DataType::UnsignedByte : + std::is_same::value ? DataType::Short : + std::is_same::value ? DataType::UnsignedShort : + std::is_same::value ? DataType::Integer : + std::is_same::value ? DataType::UnsignedInteger : + std::is_same::value ? DataType::Float : static_cast(0); +} template void AttributeBinding::bind(Context& context, AttributeLocation location, std::size_t vertexOffset) const { @@ -76,7 +78,7 @@ void AttributeBinding::bind(Context& context, AttributeLocation location, MBGL_CHECK_ERROR(glVertexAttribPointer( location, static_cast(attributeSize), - static_cast(DataTypeOf), + static_cast(DataTypeOf()), static_cast(false), static_cast(vertexSize), reinterpret_cast(attributeOffset + (vertexSize * vertexOffset)))); diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp index f018a1d261..bc02b54bd2 100644 --- a/src/mbgl/gl/attribute.hpp +++ b/src/mbgl/gl/attribute.hpp @@ -240,9 +240,6 @@ public: using Vertex = detail::Vertex; - template - static constexpr std::size_t Index = TypeIndex::value; - static Locations bindLocations(const ProgramID& id) { std::set activeAttributes = getActiveAttributes(id); @@ -266,7 +263,7 @@ public: template static Bindings bindings(const VertexBuffer& buffer) { - return Bindings { As::Type::binding(buffer, Index)... }; + return Bindings { As::Type::binding(buffer, TypeIndex::value)... }; } static void bind(Context& context, -- cgit v1.2.1 From 3afbfa2de74d26f1d9099a85cc1b6ed70251666f Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Tue, 11 Jul 2017 15:16:06 +0300 Subject: [core] GCC 4.9 shadow member warnings --- include/mbgl/util/image.hpp | 6 ++--- platform/default/sqlite3.cpp | 4 ++-- platform/qt/src/qmapboxgl.cpp | 28 +++++++++++----------- .../renderer/possibly_evaluated_property_value.hpp | 2 +- src/mbgl/tile/geometry_tile.cpp | 6 ++--- test/src/mbgl/test/fake_file_source.hpp | 4 ++-- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/include/mbgl/util/image.hpp b/include/mbgl/util/image.hpp index 91bf06d727..cb28f3da8d 100644 --- a/include/mbgl/util/image.hpp +++ b/include/mbgl/util/image.hpp @@ -66,9 +66,9 @@ public: template T clone() const { - T copy(size); - std::copy(data.get(), data.get() + bytes(), copy.data.get()); - return copy; + T copy_(size); + std::copy(data.get(), data.get() + bytes(), copy_.data.get()); + return copy_; } size_t stride() const { return channels * size.width; } diff --git a/platform/default/sqlite3.cpp b/platform/default/sqlite3.cpp index 0707f9255c..269c97716f 100644 --- a/platform/default/sqlite3.cpp +++ b/platform/default/sqlite3.cpp @@ -381,8 +381,8 @@ int64_t Statement::lastInsertRowId() const { uint64_t Statement::changes() const { assert(impl); - auto changes = impl->changes; - return (changes < 0 ? 0 : changes); + auto changes_ = impl->changes; + return (changes_ < 0 ? 0 : changes_); } Transaction::Transaction(Database& db_, Mode mode) diff --git a/platform/qt/src/qmapboxgl.cpp b/platform/qt/src/qmapboxgl.cpp index f094e2a0ec..295d14b5d3 100644 --- a/platform/qt/src/qmapboxgl.cpp +++ b/platform/qt/src/qmapboxgl.cpp @@ -426,13 +426,13 @@ void QMapboxGLSettings::setApiBaseUrl(const QString& url) */ /*! - Constructs a QMapboxGL object with \a settings and sets \a parent as the parent + Constructs a QMapboxGL object with \a settings and sets \a parent_ as the parent object. The \a settings cannot be changed after the object is constructed. The \a size represents the size of the viewport and the \a pixelRatio the initial pixel density of the screen. */ -QMapboxGL::QMapboxGL(QObject *parent, const QMapboxGLSettings &settings, const QSize& size, qreal pixelRatio) - : QObject(parent) +QMapboxGL::QMapboxGL(QObject *parent_, const QMapboxGLSettings &settings, const QSize& size, qreal pixelRatio) + : QObject(parent_) { assert(!size.isEmpty()); @@ -829,7 +829,7 @@ void QMapboxGL::removeAnnotation(QMapbox::AnnotationID id) } /*! - Sets a layout \a property \a value to an existing \a layer. The \a property string can be any + Sets a layout \a property \a value to an existing \a layer. The \a property_ string can be any as defined by the \l {https://www.mapbox.com/mapbox-gl-style-spec/} {Mapbox style specification} for layout properties. @@ -863,7 +863,7 @@ void QMapboxGL::removeAnnotation(QMapbox::AnnotationID id) \li QVariantList \endtable */ -void QMapboxGL::setLayoutProperty(const QString& layer, const QString& property, const QVariant& value) +void QMapboxGL::setLayoutProperty(const QString& layer, const QString& property_, const QVariant& value) { using namespace mbgl::style; @@ -873,14 +873,14 @@ void QMapboxGL::setLayoutProperty(const QString& layer, const QString& property, return; } - if (conversion::setLayoutProperty(*layer_, property.toStdString(), value)) { - qWarning() << "Error setting layout property:" << layer << "-" << property; + if (conversion::setLayoutProperty(*layer_, property_.toStdString(), value)) { + qWarning() << "Error setting layout property:" << layer << "-" << property_; return; } } /*! - Sets a paint \a property \a value to an existing \a layer. The \a property string can be any + Sets a paint \a property_ \a value to an existing \a layer. The \a property string can be any as defined by the \l {https://www.mapbox.com/mapbox-gl-style-spec/} {Mapbox style specification} for paint properties. @@ -929,7 +929,7 @@ void QMapboxGL::setLayoutProperty(const QString& layer, const QString& property, map->setPaintProperty("route","line-dasharray", lineDashArray); \endcode */ -void QMapboxGL::setPaintProperty(const QString& layer, const QString& property, const QVariant& value) +void QMapboxGL::setPaintProperty(const QString& layer, const QString& property_, const QVariant& value) { using namespace mbgl::style; @@ -939,8 +939,8 @@ void QMapboxGL::setPaintProperty(const QString& layer, const QString& property, return; } - if (conversion::setPaintProperty(*layer_, property.toStdString(), value)) { - qWarning() << "Error setting paint property:" << layer << "-" << property; + if (conversion::setPaintProperty(*layer_, property_.toStdString(), value)) { + qWarning() << "Error setting paint property:" << layer << "-" << property_; return; } } @@ -1033,11 +1033,11 @@ void QMapboxGL::addAnnotationIcon(const QString &name, const QImage &icon) } /*! - Returns the amount of meters per pixel from a given \a latitude and \a zoom. + Returns the amount of meters per pixel from a given \a latitude_ and \a zoom_. */ -double QMapboxGL::metersPerPixelAtLatitude(double latitude, double zoom) const +double QMapboxGL::metersPerPixelAtLatitude(double latitude_, double zoom_) const { - return mbgl::Projection::getMetersPerPixelAtLatitude(latitude, zoom); + return mbgl::Projection::getMetersPerPixelAtLatitude(latitude_, zoom_); } /*! diff --git a/src/mbgl/renderer/possibly_evaluated_property_value.hpp b/src/mbgl/renderer/possibly_evaluated_property_value.hpp index 8a5dfbe4ea..e662d5dfb1 100644 --- a/src/mbgl/renderer/possibly_evaluated_property_value.hpp +++ b/src/mbgl/renderer/possibly_evaluated_property_value.hpp @@ -45,7 +45,7 @@ public: template T evaluate(const Feature& feature, float zoom, T defaultValue) const { return this->match( - [&] (const T& constant) { return constant; }, + [&] (const T& constant_) { return constant_; }, [&] (const style::SourceFunction& function) { return function.evaluate(feature, defaultValue); }, diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp index 1ee303b50f..4f1bc9e759 100644 --- a/src/mbgl/tile/geometry_tile.cpp +++ b/src/mbgl/tile/geometry_tile.cpp @@ -174,18 +174,18 @@ void GeometryTile::getImages(ImageDependencies imageDependencies) { } void GeometryTile::upload(gl::Context& context) { - auto upload = [&] (Bucket& bucket) { + auto uploadFn = [&] (Bucket& bucket) { if (bucket.needsUpload()) { bucket.upload(context); } }; for (auto& entry : nonSymbolBuckets) { - upload(*entry.second); + uploadFn(*entry.second); } for (auto& entry : symbolBuckets) { - upload(*entry.second); + uploadFn(*entry.second); } if (glyphAtlasImage) { diff --git a/test/src/mbgl/test/fake_file_source.hpp b/test/src/mbgl/test/fake_file_source.hpp index 3ed3f90a17..baae7f9b7e 100644 --- a/test/src/mbgl/test/fake_file_source.hpp +++ b/test/src/mbgl/test/fake_file_source.hpp @@ -42,8 +42,8 @@ public: } bool respond(Resource::Kind kind, const Response& response) { - auto it = std::find_if(requests.begin(), requests.end(), [&] (FakeFileRequest* request) { - return request->resource.kind == kind; + auto it = std::find_if(requests.begin(), requests.end(), [&] (FakeFileRequest* fakeRequest) { + return fakeRequest->resource.kind == kind; }); if (it != requests.end()) { -- cgit v1.2.1 From d918f8d7c2e9eb4e3514078da6621c159e67069c Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Tue, 11 Jul 2017 17:42:50 +0300 Subject: [core] GCC 4.9 does not provide --- platform/default/utf.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/platform/default/utf.cpp b/platform/default/utf.cpp index ba9678c91f..8fc44a9ed3 100644 --- a/platform/default/utf.cpp +++ b/platform/default/utf.cpp @@ -2,14 +2,24 @@ #include #include + +// GCC 4.9 compatibility +#if !defined(__GNUC__) || __GNUC__ >= 5 #include +#else +#include +#endif namespace mbgl { namespace util { std::u16string utf8_to_utf16::convert(std::string const& utf8) { +#if !defined(__GNUC__) || __GNUC__ >= 5 std::wstring_convert, char16_t> converter; return converter.from_bytes(utf8); +#else + return boost::locale::conv::utf_to_utf(utf8.c_str(), utf8.c_str() + utf8.size()); +#endif } } // namespace util -- cgit v1.2.1 From 6282b28b6fe218390b843a8a71bb5cc2b63dd05c Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Tue, 11 Jul 2017 15:32:51 +0300 Subject: [core] Added MBGL_CONSTEXPR to satisfy GCC 4.9 --- include/mbgl/map/mode.hpp | 11 ++++++----- include/mbgl/util/convert.hpp | 4 +++- include/mbgl/util/util.hpp | 7 +++++++ src/mbgl/gl/gl.cpp | 3 ++- src/mbgl/map/update.hpp | 7 ++++--- src/mbgl/renderer/render_pass.hpp | 7 ++++--- src/mbgl/text/glyph.hpp | 11 ++++++----- 7 files changed, 32 insertions(+), 18 deletions(-) diff --git a/include/mbgl/map/mode.hpp b/include/mbgl/map/mode.hpp index afec5c0a08..05de2df22c 100644 --- a/include/mbgl/map/mode.hpp +++ b/include/mbgl/map/mode.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -51,23 +52,23 @@ enum class MapDebugOptions : EnumType { #endif // MBGL_USE_GLES2 }; -constexpr MapDebugOptions operator|(MapDebugOptions lhs, MapDebugOptions rhs) { +MBGL_CONSTEXPR MapDebugOptions operator|(MapDebugOptions lhs, MapDebugOptions rhs) { return MapDebugOptions(mbgl::underlying_type(lhs) | mbgl::underlying_type(rhs)); } -constexpr MapDebugOptions& operator|=(MapDebugOptions& lhs, MapDebugOptions rhs) { +MBGL_CONSTEXPR MapDebugOptions& operator|=(MapDebugOptions& lhs, MapDebugOptions rhs) { return (lhs = MapDebugOptions(mbgl::underlying_type(lhs) | mbgl::underlying_type(rhs))); } -constexpr bool operator&(MapDebugOptions lhs, MapDebugOptions rhs) { +MBGL_CONSTEXPR bool operator&(MapDebugOptions lhs, MapDebugOptions rhs) { return mbgl::underlying_type(lhs) & mbgl::underlying_type(rhs); } -constexpr MapDebugOptions& operator&=(MapDebugOptions& lhs, MapDebugOptions rhs) { +MBGL_CONSTEXPR MapDebugOptions& operator&=(MapDebugOptions& lhs, MapDebugOptions rhs) { return (lhs = MapDebugOptions(mbgl::underlying_type(lhs) & mbgl::underlying_type(rhs))); } -constexpr MapDebugOptions operator~(MapDebugOptions value) { +MBGL_CONSTEXPR MapDebugOptions operator~(MapDebugOptions value) { return MapDebugOptions(~mbgl::underlying_type(value)); } diff --git a/include/mbgl/util/convert.hpp b/include/mbgl/util/convert.hpp index c2b3d9950d..bedb1a4a08 100644 --- a/include/mbgl/util/convert.hpp +++ b/include/mbgl/util/convert.hpp @@ -1,3 +1,5 @@ +#include + #include #include #include @@ -7,7 +9,7 @@ namespace util { template::value>> -constexpr std::array convert(const std::array&from) { +MBGL_CONSTEXPR std::array convert(const std::array&from) { std::array to {}; std::copy(std::begin(from), std::end(from), std::begin(to)); return to; diff --git a/include/mbgl/util/util.hpp b/include/mbgl/util/util.hpp index c5a7cb3780..7960b40299 100644 --- a/include/mbgl/util/util.hpp +++ b/include/mbgl/util/util.hpp @@ -12,3 +12,10 @@ #define MBGL_VERIFY_THREAD(tid) #endif + +// GCC 4.9 compatibility +#if !defined(__GNUC__) || __GNUC__ >= 5 +#define MBGL_CONSTEXPR constexpr +#else +#define MBGL_CONSTEXPR inline +#endif diff --git a/src/mbgl/gl/gl.cpp b/src/mbgl/gl/gl.cpp index 8999468dbd..bd6d7b192d 100644 --- a/src/mbgl/gl/gl.cpp +++ b/src/mbgl/gl/gl.cpp @@ -1,12 +1,13 @@ #include #include +#include namespace mbgl { namespace gl { namespace { -constexpr const char* stringFromError(GLenum err) { +MBGL_CONSTEXPR const char* stringFromError(GLenum err) { switch (err) { case GL_INVALID_ENUM: return "GL_INVALID_ENUM"; diff --git a/src/mbgl/map/update.hpp b/src/mbgl/map/update.hpp index 82d98284f5..ab8b10c651 100644 --- a/src/mbgl/map/update.hpp +++ b/src/mbgl/map/update.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace mbgl { @@ -11,15 +12,15 @@ enum class Update { AnnotationData = 1 << 7 }; -constexpr Update operator|(Update lhs, Update rhs) { +MBGL_CONSTEXPR Update operator|(Update lhs, Update rhs) { return Update(mbgl::underlying_type(lhs) | mbgl::underlying_type(rhs)); } -constexpr Update& operator|=(Update& lhs, const Update& rhs) { +MBGL_CONSTEXPR Update& operator|=(Update& lhs, const Update& rhs) { return (lhs = lhs | rhs); } -constexpr bool operator& (Update lhs, Update rhs) { +MBGL_CONSTEXPR bool operator& (Update lhs, Update rhs) { return mbgl::underlying_type(lhs) & mbgl::underlying_type(rhs); } diff --git a/src/mbgl/renderer/render_pass.hpp b/src/mbgl/renderer/render_pass.hpp index d273e34ff7..ae2b923ba1 100644 --- a/src/mbgl/renderer/render_pass.hpp +++ b/src/mbgl/renderer/render_pass.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include @@ -12,15 +13,15 @@ enum class RenderPass : uint8_t { Translucent = 1 << 1, }; -constexpr RenderPass operator|(RenderPass a, RenderPass b) { +MBGL_CONSTEXPR RenderPass operator|(RenderPass a, RenderPass b) { return RenderPass(mbgl::underlying_type(a) | mbgl::underlying_type(b)); } -constexpr RenderPass& operator|=(RenderPass& a, RenderPass b) { +MBGL_CONSTEXPR RenderPass& operator|=(RenderPass& a, RenderPass b) { return (a = a | b); } -constexpr RenderPass operator&(RenderPass a, RenderPass b) { +MBGL_CONSTEXPR RenderPass operator&(RenderPass a, RenderPass b) { return RenderPass(mbgl::underlying_type(a) & mbgl::underlying_type(b)); } diff --git a/src/mbgl/text/glyph.hpp b/src/mbgl/text/glyph.hpp index b9eaedd302..19ecdfd17c 100644 --- a/src/mbgl/text/glyph.hpp +++ b/src/mbgl/text/glyph.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -89,23 +90,23 @@ enum class WritingModeType : uint8_t { Vertical = 1 << 1, }; -constexpr WritingModeType operator|(WritingModeType a, WritingModeType b) { +MBGL_CONSTEXPR WritingModeType operator|(WritingModeType a, WritingModeType b) { return WritingModeType(mbgl::underlying_type(a) | mbgl::underlying_type(b)); } -constexpr WritingModeType& operator|=(WritingModeType& a, WritingModeType b) { +MBGL_CONSTEXPR WritingModeType& operator|=(WritingModeType& a, WritingModeType b) { return (a = a | b); } -constexpr bool operator&(WritingModeType lhs, WritingModeType rhs) { +MBGL_CONSTEXPR bool operator&(WritingModeType lhs, WritingModeType rhs) { return mbgl::underlying_type(lhs) & mbgl::underlying_type(rhs); } -constexpr WritingModeType& operator&=(WritingModeType& lhs, WritingModeType rhs) { +MBGL_CONSTEXPR WritingModeType& operator&=(WritingModeType& lhs, WritingModeType rhs) { return (lhs = WritingModeType(mbgl::underlying_type(lhs) & mbgl::underlying_type(rhs))); } -constexpr WritingModeType operator~(WritingModeType value) { +MBGL_CONSTEXPR WritingModeType operator~(WritingModeType value) { return WritingModeType(~mbgl::underlying_type(value)); } -- cgit v1.2.1 From 21031b624ffabf92bf284c830b3d13a3ae045460 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Tue, 11 Jul 2017 16:34:34 +0300 Subject: [core] Added missing header includes --- src/mbgl/programs/binary_program.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mbgl/programs/binary_program.cpp b/src/mbgl/programs/binary_program.cpp index 09b9acc514..57f2cc0d2c 100644 --- a/src/mbgl/programs/binary_program.cpp +++ b/src/mbgl/programs/binary_program.cpp @@ -3,6 +3,7 @@ #include #include #include +#include template static std::pair parseBinding(protozero::pbf_reader&& pbf) { -- cgit v1.2.1 From 2fae373fc9da1a5ed61b5114d8c982073734826d Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Tue, 11 Jul 2017 19:15:10 +0300 Subject: [core] GCC 4.9 is unable to deduce ctors when using bracket init --- include/mbgl/annotation/annotation.hpp | 34 ++++++++++++++++++++++++------ include/mbgl/map/query.hpp | 10 +++++++++ include/mbgl/style/transition_options.hpp | 5 +++++ include/mbgl/util/tileset.hpp | 13 ++++++++++-- platform/darwin/src/MGLMultiPoint.mm | 2 +- src/mbgl/gl/texture.hpp | 20 ++++++++++++++---- src/mbgl/renderer/tile_parameters.hpp | 27 +++++++++++++++++++++--- src/mbgl/renderer/update_parameters.hpp | 35 ++++++++++++++++++++++++++++++- src/mbgl/tile/geometry_tile.hpp | 24 +++++++++++++++++++-- test/algorithm/generate_clip_ids.test.cpp | 9 +++++++- test/style/source.test.cpp | 3 ++- test/tile/annotation_tile.test.cpp | 3 ++- test/tile/geojson_tile.test.cpp | 3 ++- test/tile/raster_tile.test.cpp | 3 ++- test/tile/vector_tile.test.cpp | 3 ++- 15 files changed, 169 insertions(+), 25 deletions(-) diff --git a/include/mbgl/annotation/annotation.hpp b/include/mbgl/annotation/annotation.hpp index 96e06ca222..bbe479b5ba 100644 --- a/include/mbgl/annotation/annotation.hpp +++ b/include/mbgl/annotation/annotation.hpp @@ -17,6 +17,10 @@ using AnnotationIDs = std::vector; class SymbolAnnotation { public: + SymbolAnnotation(Point geometry_, std::string icon_ = {}) + : geometry(std::move(geometry_)), + icon(std::move(icon_)) {} + Point geometry; std::string icon; }; @@ -29,18 +33,36 @@ using ShapeAnnotationGeometry = variant< class LineAnnotation { public: + LineAnnotation(ShapeAnnotationGeometry geometry_, + style::DataDrivenPropertyValue opacity_ = 1.0f, + style::DataDrivenPropertyValue width_ = 1.0f, + style::DataDrivenPropertyValue color_ = Color::black()) + : geometry(std::move(geometry_)), + opacity(std::move(opacity_)), + width(std::move(width_)), + color(std::move(color_)) {} + ShapeAnnotationGeometry geometry; - style::DataDrivenPropertyValue opacity { 1.0f }; - style::DataDrivenPropertyValue width { 1.0f }; - style::DataDrivenPropertyValue color { Color::black() }; + style::DataDrivenPropertyValue opacity; + style::DataDrivenPropertyValue width; + style::DataDrivenPropertyValue color; }; class FillAnnotation { public: + FillAnnotation(ShapeAnnotationGeometry geometry_, + style::DataDrivenPropertyValue opacity_ = 1.0f, + style::DataDrivenPropertyValue color_ = Color::black(), + style::DataDrivenPropertyValue outlineColor_ = {}) + : geometry(std::move(geometry_)), + opacity(std::move(opacity_)), + color(std::move(color_)), + outlineColor(std::move(outlineColor_)) {} + ShapeAnnotationGeometry geometry; - style::DataDrivenPropertyValue opacity { 1.0f }; - style::DataDrivenPropertyValue color { Color::black() }; - style::DataDrivenPropertyValue outlineColor {}; + style::DataDrivenPropertyValue opacity; + style::DataDrivenPropertyValue color; + style::DataDrivenPropertyValue outlineColor; }; using Annotation = variant< diff --git a/include/mbgl/map/query.hpp b/include/mbgl/map/query.hpp index e114fa2ebd..b9d5f21a44 100644 --- a/include/mbgl/map/query.hpp +++ b/include/mbgl/map/query.hpp @@ -13,6 +13,11 @@ namespace mbgl { */ class RenderedQueryOptions { public: + RenderedQueryOptions(optional> layerIDs_ = optional>(), + optional filter_ = optional()) + : layerIDs(std::move(layerIDs_)), + filter(std::move(filter_)) {} + /** layerIDs to include in the query */ optional> layerIDs; @@ -24,6 +29,11 @@ public: */ class SourceQueryOptions { public: + SourceQueryOptions(optional> sourceLayers_ = optional> (), + optional filter_ = optional()) + : sourceLayers(std::move(sourceLayers_)), + filter(std::move(filter_)) {} + // Required for VectorSource, ignored for GeoJSONSource optional> sourceLayers; diff --git a/include/mbgl/style/transition_options.hpp b/include/mbgl/style/transition_options.hpp index 1583667025..6dad17aeb4 100644 --- a/include/mbgl/style/transition_options.hpp +++ b/include/mbgl/style/transition_options.hpp @@ -11,6 +11,11 @@ public: optional duration = {}; optional delay = {}; + TransitionOptions(optional duration_ = optional(), + optional delay_ = optional()) + : duration(std::move(duration_)), + delay(std::move(delay_)) {} + TransitionOptions reverseMerge(const TransitionOptions& defaults) const { return { duration ? duration : defaults.duration, diff --git a/include/mbgl/util/tileset.hpp b/include/mbgl/util/tileset.hpp index 1256e9fe96..2fa19d3f53 100644 --- a/include/mbgl/util/tileset.hpp +++ b/include/mbgl/util/tileset.hpp @@ -13,9 +13,18 @@ public: enum class Scheme : bool { XYZ, TMS }; std::vector tiles; - Range zoomRange { 0, 22 }; + Range zoomRange; std::string attribution; - Scheme scheme = Scheme::XYZ; + Scheme scheme; + + Tileset(std::vector tiles_ = std::vector(), + Range zoomRange_ = { 0, 22 }, + std::string attribution_ = {}, + Scheme scheme_ = Scheme::XYZ) + : tiles(std::move(tiles_)), + zoomRange(std::move(zoomRange_)), + attribution(std::move(attribution_)), + scheme(scheme_) {} // TileJSON also includes center, zoom, and bounds, but they are not used by mbgl. diff --git a/platform/darwin/src/MGLMultiPoint.mm b/platform/darwin/src/MGLMultiPoint.mm index ef46bbb0fe..240dad9614 100644 --- a/platform/darwin/src/MGLMultiPoint.mm +++ b/platform/darwin/src/MGLMultiPoint.mm @@ -182,7 +182,7 @@ - (mbgl::Annotation)annotationObjectWithDelegate:(__unused id )delegate { NSAssert(NO, @"Cannot add an annotation from an instance of %@", NSStringFromClass([self class])); - return mbgl::SymbolAnnotation({mbgl::Point()}); + return mbgl::SymbolAnnotation(mbgl::Point()); } - (NSString *)description diff --git a/src/mbgl/gl/texture.hpp b/src/mbgl/gl/texture.hpp index 5330689ac2..625e69233a 100644 --- a/src/mbgl/gl/texture.hpp +++ b/src/mbgl/gl/texture.hpp @@ -8,12 +8,24 @@ namespace gl { class Texture { public: + Texture(Size size_, UniqueTexture texture_, + TextureFilter filter_ = TextureFilter::Nearest, + TextureMipMap mipmap_ = TextureMipMap::No, + TextureWrap wrapX_ = TextureWrap::Clamp, + TextureWrap wrapY_ = TextureWrap::Clamp) + : size(std::move(size_)), + texture(std::move(texture_)), + filter(filter_), + mipmap(mipmap_), + wrapX(wrapX_), + wrapY(wrapY_) {} + Size size; UniqueTexture texture; - TextureFilter filter = TextureFilter::Nearest; - TextureMipMap mipmap = TextureMipMap::No; - TextureWrap wrapX = TextureWrap::Clamp; - TextureWrap wrapY = TextureWrap::Clamp; + TextureFilter filter; + TextureMipMap mipmap; + TextureWrap wrapX; + TextureWrap wrapY; }; } // namespace gl diff --git a/src/mbgl/renderer/tile_parameters.hpp b/src/mbgl/renderer/tile_parameters.hpp index 9769ae6897..333f796331 100644 --- a/src/mbgl/renderer/tile_parameters.hpp +++ b/src/mbgl/renderer/tile_parameters.hpp @@ -13,8 +13,29 @@ class GlyphManager; class TileParameters { public: - float pixelRatio; - MapDebugOptions debugOptions; + TileParameters(const float pixelRatio_, + const MapDebugOptions debugOptions_, + const TransformState& transformState_, + Scheduler& workerScheduler_, + FileSource& fileSource_, + const MapMode mode_, + AnnotationManager& annotationManager_, + ImageManager& imageManager_, + GlyphManager& glyphManager_, + const uint8_t prefetchZoomDelta_) + : pixelRatio(pixelRatio_), + debugOptions(debugOptions_), + transformState(std::move(transformState_)), + workerScheduler(workerScheduler_), + fileSource(fileSource_), + mode(mode_), + annotationManager(annotationManager_), + imageManager(imageManager_), + glyphManager(glyphManager_), + prefetchZoomDelta(prefetchZoomDelta_) {} + + const float pixelRatio; + const MapDebugOptions debugOptions; const TransformState& transformState; Scheduler& workerScheduler; FileSource& fileSource; @@ -22,7 +43,7 @@ public: AnnotationManager& annotationManager; ImageManager& imageManager; GlyphManager& glyphManager; - const uint8_t prefetchZoomDelta = 0; + const uint8_t prefetchZoomDelta; }; } // namespace mbgl diff --git a/src/mbgl/renderer/update_parameters.hpp b/src/mbgl/renderer/update_parameters.hpp index 8ebcd11e21..04b59699b3 100644 --- a/src/mbgl/renderer/update_parameters.hpp +++ b/src/mbgl/renderer/update_parameters.hpp @@ -16,6 +16,39 @@ class AnnotationManager; class UpdateParameters { public: + UpdateParameters(const MapMode mode_, + const float pixelRatio_, + const MapDebugOptions debugOptions_, + const TimePoint timePoint_, + const TransformState TransformState_, + const std::string glyphURL_, + const bool spriteLoaded_, + const style::TransitionOptions transitionOptions_, + const Immutable light_, + const Immutable>> images_, + const Immutable>> sources_, + const Immutable>> layers_, + Scheduler& scheduler_, + FileSource& fileSource_, + AnnotationManager& annotationManager_, + const uint8_t prefetchZoomDelta_) + : mode(mode_), + pixelRatio(pixelRatio_), + debugOptions(debugOptions_), + timePoint(std::move(timePoint_)), + transformState(std::move(TransformState_)), + glyphURL(std::move(glyphURL_)), + spriteLoaded(spriteLoaded_), + transitionOptions(std::move(transitionOptions_)), + light(std::move(light_)), + images(std::move(images_)), + sources(std::move(sources_)), + layers(std::move(layers_)), + scheduler(scheduler_), + fileSource(fileSource_), + annotationManager(annotationManager_), + prefetchZoomDelta(prefetchZoomDelta_) {} + const MapMode mode; const float pixelRatio; const MapDebugOptions debugOptions; @@ -34,7 +67,7 @@ public: FileSource& fileSource; AnnotationManager& annotationManager; - const uint8_t prefetchZoomDelta = 0; + const uint8_t prefetchZoomDelta; }; } // namespace mbgl diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp index 943296e01b..c45762742b 100644 --- a/src/mbgl/tile/geometry_tile.hpp +++ b/src/mbgl/tile/geometry_tile.hpp @@ -5,9 +5,11 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -17,8 +19,6 @@ namespace mbgl { class GeometryTileData; -class FeatureIndex; -class CollisionTile; class RenderStyle; class RenderLayer; class SourceQueryOptions; @@ -71,6 +71,15 @@ public: std::unique_ptr featureIndex; std::unique_ptr tileData; uint64_t correlationID; + + LayoutResult(std::unordered_map> nonSymbolBuckets_, + std::unique_ptr featureIndex_, + std::unique_ptr tileData_, + uint64_t correlationID_) + : nonSymbolBuckets(std::move(nonSymbolBuckets_)), + featureIndex(std::move(featureIndex_)), + tileData(std::move(tileData_)), + correlationID(correlationID_) {} }; void onLayout(LayoutResult); @@ -81,6 +90,17 @@ public: optional glyphAtlasImage; optional iconAtlasImage; uint64_t correlationID; + + PlacementResult(std::unordered_map> symbolBuckets_, + std::unique_ptr collisionTile_, + optional glyphAtlasImage_, + optional iconAtlasImage_, + uint64_t correlationID_) + : symbolBuckets(std::move(symbolBuckets_)), + collisionTile(std::move(collisionTile_)), + glyphAtlasImage(std::move(glyphAtlasImage_)), + iconAtlasImage(std::move(iconAtlasImage_)), + correlationID(correlationID_) {} }; void onPlacement(PlacementResult); diff --git a/test/algorithm/generate_clip_ids.test.cpp b/test/algorithm/generate_clip_ids.test.cpp index 46a577b994..1ebdccb99e 100644 --- a/test/algorithm/generate_clip_ids.test.cpp +++ b/test/algorithm/generate_clip_ids.test.cpp @@ -7,7 +7,14 @@ using namespace mbgl; struct Renderable { UnwrappedTileID id; ClipID clip; - bool used = true; + bool used; + + Renderable(UnwrappedTileID id_, + ClipID clip_, + bool used_ = true) + : id(std::move(id_)), + clip(std::move(clip_)), + used(used_) {} bool operator==(const Renderable& rhs) const { return id == rhs.id && clip == rhs.clip; diff --git a/test/style/source.test.cpp b/test/style/source.test.cpp index eaa3c72877..004ba18c5b 100644 --- a/test/style/source.test.cpp +++ b/test/style/source.test.cpp @@ -60,7 +60,8 @@ public: MapMode::Continuous, annotationManager, imageManager, - glyphManager + glyphManager, + 0 }; SourceTest() { diff --git a/test/tile/annotation_tile.test.cpp b/test/tile/annotation_tile.test.cpp index 6d00a3236a..a1bfc23492 100644 --- a/test/tile/annotation_tile.test.cpp +++ b/test/tile/annotation_tile.test.cpp @@ -43,7 +43,8 @@ public: MapMode::Continuous, annotationManager, imageManager, - glyphManager + glyphManager, + 0 }; }; diff --git a/test/tile/geojson_tile.test.cpp b/test/tile/geojson_tile.test.cpp index 2aa85c3860..52f7a20f00 100644 --- a/test/tile/geojson_tile.test.cpp +++ b/test/tile/geojson_tile.test.cpp @@ -38,7 +38,8 @@ public: MapMode::Continuous, annotationManager, imageManager, - glyphManager + glyphManager, + 0 }; }; diff --git a/test/tile/raster_tile.test.cpp b/test/tile/raster_tile.test.cpp index a0666c2146..025208c331 100644 --- a/test/tile/raster_tile.test.cpp +++ b/test/tile/raster_tile.test.cpp @@ -34,7 +34,8 @@ public: MapMode::Continuous, annotationManager, imageManager, - glyphManager + glyphManager, + 0 }; }; diff --git a/test/tile/vector_tile.test.cpp b/test/tile/vector_tile.test.cpp index f24733dc9b..18152cd2c1 100644 --- a/test/tile/vector_tile.test.cpp +++ b/test/tile/vector_tile.test.cpp @@ -40,7 +40,8 @@ public: MapMode::Continuous, annotationManager, imageManager, - glyphManager + glyphManager, + 0 }; }; -- cgit v1.2.1 From 4014aa6721e53318e4ac92814776b3e01b4589cb Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Tue, 11 Jul 2017 19:19:04 +0300 Subject: [core] GCC 4.9 bracket initialization issues --- include/mbgl/map/map.hpp | 2 +- include/mbgl/style/transition_options.hpp | 4 +- include/mbgl/util/convert.hpp | 2 +- platform/qt/app/mapwindow.cpp | 22 +++++-- src/mbgl/annotation/fill_annotation_impl.cpp | 2 +- src/mbgl/annotation/line_annotation_impl.cpp | 2 +- src/mbgl/gl/uniform.hpp | 4 +- src/mbgl/map/map.cpp | 2 +- src/mbgl/renderer/sources/render_image_source.cpp | 4 +- src/mbgl/renderer/sources/render_raster_source.cpp | 4 +- test/gl/bucket.test.cpp | 16 +++-- test/src/mbgl/test/stub_geometry_tile_feature.hpp | 4 +- test/style/function/source_function.test.cpp | 9 ++- test/tile/annotation_tile.test.cpp | 6 +- test/tile/vector_tile.test.cpp | 2 +- test/util/merge_lines.test.cpp | 73 ++++++++++++---------- 16 files changed, 93 insertions(+), 65 deletions(-) diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index 158e9d733d..d82a260362 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -41,7 +41,7 @@ public: GLContextMode contextMode = GLContextMode::Unique, ConstrainMode constrainMode = ConstrainMode::HeightOnly, ViewportMode viewportMode = ViewportMode::Default, - const optional& programCacheDir = {}); + optional programCacheDir = optional()); ~Map(); // Register a callback that will get called (on the render thread) when all resources have diff --git a/include/mbgl/style/transition_options.hpp b/include/mbgl/style/transition_options.hpp index 6dad17aeb4..0ac7c02c6b 100644 --- a/include/mbgl/style/transition_options.hpp +++ b/include/mbgl/style/transition_options.hpp @@ -8,8 +8,8 @@ namespace style { class TransitionOptions { public: - optional duration = {}; - optional delay = {}; + optional duration; + optional delay; TransitionOptions(optional duration_ = optional(), optional delay_ = optional()) diff --git a/include/mbgl/util/convert.hpp b/include/mbgl/util/convert.hpp index bedb1a4a08..02ec7feef9 100644 --- a/include/mbgl/util/convert.hpp +++ b/include/mbgl/util/convert.hpp @@ -10,7 +10,7 @@ namespace util { template::value>> MBGL_CONSTEXPR std::array convert(const std::array&from) { - std::array to {}; + std::array to {{}}; std::copy(std::begin(from), std::end(from), std::begin(to)); return to; } diff --git a/platform/qt/app/mapwindow.cpp b/platform/qt/app/mapwindow.cpp index 03ca052ec4..c4efbfa318 100644 --- a/platform/qt/app/mapwindow.cpp +++ b/platform/qt/app/mapwindow.cpp @@ -254,8 +254,13 @@ void MapWindow::keyPressEvent(QKeyEvent *ev) if (m_lineAnnotationId.isNull()) { QMapbox::Coordinate topLeft = m_map->coordinateForPixel({ 0, 0 }); QMapbox::Coordinate bottomRight = m_map->coordinateForPixel({ qreal(size().width()), qreal(size().height()) }); - QMapbox::CoordinatesCollections geometry { { { topLeft, bottomRight } } }; - QMapbox::LineAnnotation line { { QMapbox::ShapeAnnotationGeometry::LineStringType, geometry }, 0.5f, 1.0f, Qt::red }; + QMapbox::CoordinatesCollections lineGeometry { { { topLeft, bottomRight } } }; + QMapbox::ShapeAnnotationGeometry annotationGeometry { QMapbox::ShapeAnnotationGeometry::LineStringType, lineGeometry }; + QMapbox::LineAnnotation line; + line.geometry = annotationGeometry; + line.opacity = 0.5f; + line.width = 1.0f; + line.color = Qt::red; m_lineAnnotationId = m_map->addAnnotation(QVariant::fromValue(line)); } else { m_map->removeAnnotation(m_lineAnnotationId.toUInt()); @@ -269,8 +274,13 @@ void MapWindow::keyPressEvent(QKeyEvent *ev) QMapbox::Coordinate topRight = m_map->coordinateForPixel({ 0, qreal(size().height()) }); QMapbox::Coordinate bottomLeft = m_map->coordinateForPixel({ qreal(size().width()), 0 }); QMapbox::Coordinate bottomRight = m_map->coordinateForPixel({ qreal(size().width()), qreal(size().height()) }); - QMapbox::CoordinatesCollections geometry { { { bottomLeft, bottomRight, topRight, topLeft, bottomLeft } } }; - QMapbox::FillAnnotation fill { { QMapbox::ShapeAnnotationGeometry::PolygonType, geometry }, 0.5f, Qt::green, QVariant::fromValue(QColor(Qt::black)) }; + QMapbox::CoordinatesCollections fillGeometry { { { bottomLeft, bottomRight, topRight, topLeft, bottomLeft } } }; + QMapbox::ShapeAnnotationGeometry annotationGeometry { QMapbox::ShapeAnnotationGeometry::PolygonType, fillGeometry }; + QMapbox::FillAnnotation fill; + fill.geometry = annotationGeometry; + fill.opacity = 0.5f; + fill.color = Qt::green; + fill.outlineColor = QVariant::fromValue(QColor(Qt::black)); m_fillAnnotationId = m_map->addAnnotation(QVariant::fromValue(fill)); } else { m_map->removeAnnotation(m_fillAnnotationId.toUInt()); @@ -283,8 +293,8 @@ void MapWindow::keyPressEvent(QKeyEvent *ev) m_map->removeLayer("circleLayer"); m_map->removeSource("circleSource"); } else { - QMapbox::CoordinatesCollections geometry { { { m_map->coordinate() } } }; - QMapbox::Feature feature { QMapbox::Feature::PointType, geometry, {}, {} }; + QMapbox::CoordinatesCollections point { { { m_map->coordinate() } } }; + QMapbox::Feature feature { QMapbox::Feature::PointType, point, {}, {} }; QVariantMap circleSource; circleSource["type"] = "geojson"; diff --git a/src/mbgl/annotation/fill_annotation_impl.cpp b/src/mbgl/annotation/fill_annotation_impl.cpp index 5dc36edab0..9c73aeb796 100644 --- a/src/mbgl/annotation/fill_annotation_impl.cpp +++ b/src/mbgl/annotation/fill_annotation_impl.cpp @@ -9,7 +9,7 @@ using namespace style; FillAnnotationImpl::FillAnnotationImpl(AnnotationID id_, FillAnnotation annotation_, uint8_t maxZoom_) : ShapeAnnotationImpl(id_, maxZoom_), - annotation({ ShapeAnnotationGeometry::visit(annotation_.geometry, CloseShapeAnnotation{}), annotation_.opacity, annotation_.color, annotation_.outlineColor }) { + annotation(ShapeAnnotationGeometry::visit(annotation_.geometry, CloseShapeAnnotation{}), annotation_.opacity, annotation_.color, annotation_.outlineColor) { } void FillAnnotationImpl::updateStyle(Style::Impl& style) const { diff --git a/src/mbgl/annotation/line_annotation_impl.cpp b/src/mbgl/annotation/line_annotation_impl.cpp index 8954ecfa58..d35b956888 100644 --- a/src/mbgl/annotation/line_annotation_impl.cpp +++ b/src/mbgl/annotation/line_annotation_impl.cpp @@ -9,7 +9,7 @@ using namespace style; LineAnnotationImpl::LineAnnotationImpl(AnnotationID id_, LineAnnotation annotation_, uint8_t maxZoom_) : ShapeAnnotationImpl(id_, maxZoom_), - annotation({ ShapeAnnotationGeometry::visit(annotation_.geometry, CloseShapeAnnotation{}), annotation_.opacity, annotation_.width, annotation_.color }) { + annotation(ShapeAnnotationGeometry::visit(annotation_.geometry, CloseShapeAnnotation{}), annotation_.opacity, annotation_.width, annotation_.color) { } void LineAnnotationImpl::updateStyle(Style::Impl& style) const { diff --git a/src/mbgl/gl/uniform.hpp b/src/mbgl/gl/uniform.hpp index 829192bcca..4ed2419764 100644 --- a/src/mbgl/gl/uniform.hpp +++ b/src/mbgl/gl/uniform.hpp @@ -48,6 +48,8 @@ public: class State { public: + State(UniformLocation location_) : location(std::move(location_)) {} + void operator=(const Value& value) { if (location >= 0 && (!current || *current != value.t)) { current = value.t; @@ -106,7 +108,7 @@ public: template static State loadNamedLocations(const Program& program) { - return State{ { program.uniformLocation(Us::name()) }... }; + return State(typename Us::State(program.uniformLocation(Us::name()))...); } static NamedLocations getNamedLocations(const State& state) { diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 565d39c515..26795f7814 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -111,7 +111,7 @@ Map::Map(Backend& backend, GLContextMode contextMode, ConstrainMode constrainMode, ViewportMode viewportMode, - const optional& programCacheDir) + optional programCacheDir) : impl(std::make_unique(*this, backend, pixelRatio, diff --git a/src/mbgl/renderer/sources/render_image_source.cpp b/src/mbgl/renderer/sources/render_image_source.cpp index f5068b9d7f..6a3cb33fec 100644 --- a/src/mbgl/renderer/sources/render_image_source.cpp +++ b/src/mbgl/renderer/sources/render_image_source.cpp @@ -60,11 +60,11 @@ RenderImageSource::queryRenderedFeatures(const ScreenLineString&, const TransformState&, const RenderStyle&, const RenderedQueryOptions&) const { - return {}; + return std::unordered_map>(); } std::vector RenderImageSource::querySourceFeatures(const SourceQueryOptions&) const { - return {}; + return std::vector(); } void RenderImageSource::update(Immutable baseImpl_, diff --git a/src/mbgl/renderer/sources/render_raster_source.cpp b/src/mbgl/renderer/sources/render_raster_source.cpp index 2006e31628..6bf9caa1b4 100644 --- a/src/mbgl/renderer/sources/render_raster_source.cpp +++ b/src/mbgl/renderer/sources/render_raster_source.cpp @@ -73,11 +73,11 @@ RenderRasterSource::queryRenderedFeatures(const ScreenLineString&, const TransformState&, const RenderStyle&, const RenderedQueryOptions&) const { - return {}; + return std::unordered_map>(); } std::vector RenderRasterSource::querySourceFeatures(const SourceQueryOptions&) const { - return {}; + return std::vector(); } void RenderRasterSource::onLowMemory() { diff --git a/test/gl/bucket.test.cpp b/test/gl/bucket.test.cpp index fdff0e990a..24bec0bd22 100644 --- a/test/gl/bucket.test.cpp +++ b/test/gl/bucket.test.cpp @@ -14,6 +14,12 @@ using namespace mbgl; +namespace { + +PropertyMap properties; + +} // namespace + TEST(Buckets, CircleBucket) { gl::Context context; CircleBucket bucket { { {0, 0, 0}, MapMode::Still, 1.0 }, {} }; @@ -21,7 +27,7 @@ TEST(Buckets, CircleBucket) { ASSERT_FALSE(bucket.needsUpload()); GeometryCollection point { { { 0, 0 } } }; - bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Point, point, {} }, point); + bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Point, point, properties }, point); ASSERT_TRUE(bucket.hasData()); ASSERT_TRUE(bucket.needsUpload()); @@ -37,7 +43,7 @@ TEST(Buckets, FillBucket) { ASSERT_FALSE(bucket.needsUpload()); GeometryCollection polygon { { { 0, 0 }, { 0, 1 }, { 1, 1 } } }; - bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Polygon, polygon, {} }, polygon); + bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Polygon, polygon, properties }, polygon); ASSERT_TRUE(bucket.hasData()); ASSERT_TRUE(bucket.needsUpload()); @@ -53,11 +59,11 @@ TEST(Buckets, LineBucket) { // Ignore invalid feature type. GeometryCollection point { { { 0, 0 } } }; - bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Point, point, {} }, point); + bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Point, point, properties }, point); ASSERT_FALSE(bucket.hasData()); GeometryCollection line { { { 0, 0 }, { 1, 1 } } }; - bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::LineString, line, {} }, line); + bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::LineString, line, properties }, line); ASSERT_TRUE(bucket.hasData()); ASSERT_TRUE(bucket.needsUpload()); @@ -80,7 +86,7 @@ TEST(Buckets, SymbolBucket) { // SymbolBucket::addFeature() is a no-op. GeometryCollection point { { { 0, 0 } } }; - bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Point, point, {} }, point); + bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Point, point, properties }, point); ASSERT_FALSE(bucket.hasData()); ASSERT_FALSE(bucket.needsUpload()); diff --git a/test/src/mbgl/test/stub_geometry_tile_feature.hpp b/test/src/mbgl/test/stub_geometry_tile_feature.hpp index 775d783ead..0164ab133c 100644 --- a/test/src/mbgl/test/stub_geometry_tile_feature.hpp +++ b/test/src/mbgl/test/stub_geometry_tile_feature.hpp @@ -17,9 +17,9 @@ public: } PropertyMap properties; - optional id = {}; + optional id; FeatureType type = FeatureType::Point; - GeometryCollection geometry = {}; + GeometryCollection geometry; FeatureType getType() const override { return type; diff --git a/test/style/function/source_function.test.cpp b/test/style/function/source_function.test.cpp index 260620c8d0..46ad961002 100644 --- a/test/style/function/source_function.test.cpp +++ b/test/style/function/source_function.test.cpp @@ -76,11 +76,14 @@ TEST(SourceFunction, Categorical) { EXPECT_EQ(0.0f, SourceFunction("property", CategoricalStops({{ int64_t(1), 1.0f }})) .evaluate(oneString, 0.0f)); - EXPECT_EQ(0.0f, SourceFunction("property", CategoricalStops({{ "1"s, 1.0f }})) + CategoricalStops::Stops stops; + stops["1"s] = 1.0f; + + EXPECT_EQ(0.0f, SourceFunction("property", CategoricalStops(stops)) .evaluate(oneInteger, 0.0f)); - EXPECT_EQ(0.0f, SourceFunction("property", CategoricalStops({{ "1"s, 1.0f }})) + EXPECT_EQ(0.0f, SourceFunction("property", CategoricalStops(stops)) .evaluate(oneDouble, 0.0f)); - EXPECT_EQ(1.0f, SourceFunction("property", CategoricalStops({{ "1"s, 1.0f }})) + EXPECT_EQ(1.0f, SourceFunction("property", CategoricalStops(stops)) .evaluate(oneString, 0.0f)); EXPECT_EQ(1.0f, SourceFunction("property", CategoricalStops({{ true, 1.0f }})) diff --git a/test/tile/annotation_tile.test.cpp b/test/tile/annotation_tile.test.cpp index a1bfc23492..813b813220 100644 --- a/test/tile/annotation_tile.test.cpp +++ b/test/tile/annotation_tile.test.cpp @@ -58,7 +58,7 @@ TEST(AnnotationTile, Issue8289) { // Simulate layout and placement of a symbol layer. tile.onLayout(GeometryTile::LayoutResult { - {}, + std::unordered_map>(), std::make_unique(), std::move(data), 0 @@ -72,7 +72,7 @@ TEST(AnnotationTile, Issue8289) { collisionTile->placeFeature(feature, false, false); tile.onPlacement(GeometryTile::PlacementResult { - {}, + std::unordered_map>(), std::move(collisionTile), {}, {}, @@ -81,7 +81,7 @@ TEST(AnnotationTile, Issue8289) { // Simulate a second layout with empty data. tile.onLayout(GeometryTile::LayoutResult { - {}, + std::unordered_map>(), std::make_unique(), std::make_unique(), 0 diff --git a/test/tile/vector_tile.test.cpp b/test/tile/vector_tile.test.cpp index 18152cd2c1..d7ad3c999d 100644 --- a/test/tile/vector_tile.test.cpp +++ b/test/tile/vector_tile.test.cpp @@ -89,7 +89,7 @@ TEST(VectorTile, Issue7615) { // Subsequent onLayout should not cause the existing symbol bucket to be discarded. tile.onLayout(GeometryTile::LayoutResult { - {}, + std::unordered_map>(), nullptr, nullptr, 0 diff --git a/test/util/merge_lines.test.cpp b/test/util/merge_lines.test.cpp index ff80157354..d3a2ebae03 100644 --- a/test/util/merge_lines.test.cpp +++ b/test/util/merge_lines.test.cpp @@ -10,15 +10,22 @@ const std::u16string bbb = u"b"; using namespace mbgl; +namespace { + +PropertyMap properties; +LineString emptyLine; + +} + class SymbolFeatureStub : public SymbolFeature { public: SymbolFeatureStub(optional id_, FeatureType type_, GeometryCollection geometry_, - std::unordered_map properties_, optional text_, - optional icon_, std::size_t index_) : - SymbolFeature(std::make_unique(id_, type_, geometry_, properties_)) + PropertyMap properties_, optional text_, + optional icon_, std::size_t index_) : + SymbolFeature(std::make_unique(std::move(id_), type_, std::move(geometry_), std::move(properties_))) { - text = text_; - icon = icon_; + text = std::move(text_); + icon = std::move(icon_); index = index_; } }; @@ -26,20 +33,20 @@ public: TEST(MergeLines, SameText) { // merges lines with the same text std::vector input1; - input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}}}, {}, aaa, {}, 0)); - input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, {}, bbb, {}, 0)); - input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{8, 0}, {9, 0}}}, {}, aaa, {}, 0)); - input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, {}, aaa, {}, 0)); - input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{6, 0}, {7, 0}, {8, 0}}}, {}, aaa, {}, 0)); - input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{5, 0}, {6, 0}}}, {}, aaa, {}, 0)); + input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}}}, properties, aaa, {}, 0)); + input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, properties, bbb, {}, 0)); + input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{8, 0}, {9, 0}}}, properties, aaa, {}, 0)); + input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, properties, aaa, {}, 0)); + input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{6, 0}, {7, 0}, {8, 0}}}, properties, aaa, {}, 0)); + input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{5, 0}, {6, 0}}}, properties, aaa, {}, 0)); const std::vector expected1 = { - { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}}}, {} }, - { {}, FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, {} }, - { {}, FeatureType::LineString, {{{5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}}}, {} }, - { {}, FeatureType::LineString, {{}}, {} }, - { {}, FeatureType::LineString, {{}}, {} }, - { {}, FeatureType::LineString, {{}}, {} } + { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}}}, properties }, + { {}, FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, properties }, + { {}, FeatureType::LineString, {{{5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}}}, properties }, + { {}, FeatureType::LineString, { emptyLine }, properties }, + { {}, FeatureType::LineString, { emptyLine }, properties }, + { {}, FeatureType::LineString, { emptyLine }, properties } }; mbgl::util::mergeLines(input1); @@ -52,14 +59,14 @@ TEST(MergeLines, SameText) { TEST(MergeLines, BothEnds) { // mergeLines handles merge from both ends std::vector input2; - input2.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}}}, {}, aaa, {}, 0 }); - input2.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, {}, aaa, {}, 0 }); - input2.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, {}, aaa, {}, 0 }); + input2.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}}}, properties, aaa, {}, 0 }); + input2.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, properties, aaa, {}, 0 }); + input2.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, properties, aaa, {}, 0 }); const std::vector expected2 = { - { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}}}, {} }, - { {}, FeatureType::LineString, {{}}, {} }, - { {}, FeatureType::LineString, {{}}, {} } + { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}}}, properties }, + { {}, FeatureType::LineString, { emptyLine }, properties }, + { {}, FeatureType::LineString, { emptyLine }, properties } }; mbgl::util::mergeLines(input2); @@ -72,14 +79,14 @@ TEST(MergeLines, BothEnds) { TEST(MergeLines, CircularLines) { // mergeLines handles circular lines std::vector input3; - input3.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}}}, {}, aaa, {}, 0 }); - input3.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, {}, aaa, {}, 0 }); - input3.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{4, 0}, {0, 0}}}, {}, aaa, {}, 0 }); + input3.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}}}, properties, aaa, {}, 0 }); + input3.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, properties, aaa, {}, 0 }); + input3.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{4, 0}, {0, 0}}}, properties, aaa, {}, 0 }); const std::vector expected3 = { - { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {0, 0}}}, {} }, - { {}, FeatureType::LineString, {{}}, {} }, - { {}, FeatureType::LineString, {{}}, {} } + { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {0, 0}}}, properties }, + { {}, FeatureType::LineString, { emptyLine }, properties }, + { {}, FeatureType::LineString, { emptyLine }, properties } }; mbgl::util::mergeLines(input3); @@ -91,9 +98,9 @@ TEST(MergeLines, CircularLines) { TEST(MergeLines, EmptyOuterGeometry) { std::vector input; - input.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {}, {}, aaa, {}, 0 }); + input.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {}, properties, aaa, {}, 0 }); - const std::vector expected = { { {}, FeatureType::LineString, {}, {} } }; + const std::vector expected = { { {}, FeatureType::LineString, {}, properties } }; mbgl::util::mergeLines(input); @@ -102,9 +109,9 @@ TEST(MergeLines, EmptyOuterGeometry) { TEST(MergeLines, EmptyInnerGeometry) { std::vector input; - input.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{}}, {}, aaa, {}, 0 }); + input.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {}, properties, aaa, {}, 0 }); - const std::vector expected = { { {}, FeatureType::LineString, {{}}, {} } }; + const std::vector expected = { { {}, FeatureType::LineString, {}, properties } }; mbgl::util::mergeLines(input); -- cgit v1.2.1 From e99e1678488246bf850864fdaba1fc1de2fe4480 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Wed, 12 Jul 2017 16:40:56 +0300 Subject: [Qt] Do not return a valid mbgl::Annotation if conversion fails --- platform/qt/src/qmapboxgl.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/platform/qt/src/qmapboxgl.cpp b/platform/qt/src/qmapboxgl.cpp index 295d14b5d3..eafc06c028 100644 --- a/platform/qt/src/qmapboxgl.cpp +++ b/platform/qt/src/qmapboxgl.cpp @@ -755,7 +755,7 @@ void QMapboxGL::setTransitionOptions(qint64 duration, qint64 delay) { d_ptr->mapObj->getStyle().setTransitionOptions(mbgl::style::TransitionOptions{ convert(duration), convert(delay) }); } -mbgl::Annotation asMapboxGLAnnotation(const QMapbox::Annotation & annotation) { +mbgl::optional asMapboxGLAnnotation(const QMapbox::Annotation & annotation) { auto asMapboxGLGeometry = [](const QMapbox::ShapeAnnotationGeometry &geometry) { mbgl::ShapeAnnotationGeometry result; switch (geometry.type) { @@ -778,19 +778,19 @@ mbgl::Annotation asMapboxGLAnnotation(const QMapbox::Annotation & annotation) { if (annotation.canConvert()) { QMapbox::SymbolAnnotation symbolAnnotation = annotation.value(); QMapbox::Coordinate& pair = symbolAnnotation.geometry; - return mbgl::SymbolAnnotation { mbgl::Point { pair.second, pair.first }, symbolAnnotation.icon.toStdString() }; + return { mbgl::SymbolAnnotation { mbgl::Point { pair.second, pair.first }, symbolAnnotation.icon.toStdString() } }; } else if (annotation.canConvert()) { QMapbox::LineAnnotation lineAnnotation = annotation.value(); auto color = mbgl::Color::parse(lineAnnotation.color.name().toStdString()); - return mbgl::LineAnnotation { asMapboxGLGeometry(lineAnnotation.geometry), lineAnnotation.opacity, lineAnnotation.width, { *color } }; + return { mbgl::LineAnnotation { asMapboxGLGeometry(lineAnnotation.geometry), lineAnnotation.opacity, lineAnnotation.width, { *color } } }; } else if (annotation.canConvert()) { QMapbox::FillAnnotation fillAnnotation = annotation.value(); auto color = mbgl::Color::parse(fillAnnotation.color.name().toStdString()); if (fillAnnotation.outlineColor.canConvert()) { auto outlineColor = mbgl::Color::parse(fillAnnotation.outlineColor.value().name().toStdString()); - return mbgl::FillAnnotation { asMapboxGLGeometry(fillAnnotation.geometry), fillAnnotation.opacity, { *color }, { *outlineColor } }; + return { mbgl::FillAnnotation { asMapboxGLGeometry(fillAnnotation.geometry), fillAnnotation.opacity, { *color }, { *outlineColor } } }; } else { - return mbgl::FillAnnotation { asMapboxGLGeometry(fillAnnotation.geometry), fillAnnotation.opacity, { *color }, {} }; + return { mbgl::FillAnnotation { asMapboxGLGeometry(fillAnnotation.geometry), fillAnnotation.opacity, { *color }, {} } }; } } @@ -807,7 +807,7 @@ mbgl::Annotation asMapboxGLAnnotation(const QMapbox::Annotation & annotation) { */ QMapbox::AnnotationID QMapboxGL::addAnnotation(const QMapbox::Annotation &annotation) { - return d_ptr->mapObj->addAnnotation(asMapboxGLAnnotation(annotation)); + return d_ptr->mapObj->addAnnotation(*asMapboxGLAnnotation(annotation)); } /*! @@ -817,7 +817,7 @@ QMapbox::AnnotationID QMapboxGL::addAnnotation(const QMapbox::Annotation &annota */ void QMapboxGL::updateAnnotation(QMapbox::AnnotationID id, const QMapbox::Annotation &annotation) { - d_ptr->mapObj->updateAnnotation(id, asMapboxGLAnnotation(annotation)); + d_ptr->mapObj->updateAnnotation(id, *asMapboxGLAnnotation(annotation)); } /*! -- cgit v1.2.1 From 8ef9fcdf3ee9d1266771878205568944aedc7aa6 Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Mon, 10 Jul 2017 15:41:17 -0700 Subject: [core] Base label "keep-upright" orientation on start and end of label Fixes issue #9457. --- src/mbgl/layout/symbol_projection.cpp | 94 ++++++++++++++++++++++++++++------- 1 file changed, 76 insertions(+), 18 deletions(-) diff --git a/src/mbgl/layout/symbol_projection.cpp b/src/mbgl/layout/symbol_projection.cpp index 99555f7997..8ccd6a0410 100644 --- a/src/mbgl/layout/symbol_projection.cpp +++ b/src/mbgl/layout/symbol_projection.cpp @@ -144,6 +144,12 @@ namespace mbgl { Point point; float angle; }; + + enum PlacementResult { + OK, + NotEnoughRoom, + NeedsFlipping + }; optional placeGlyphAlongLine(const float offsetX, const float lineOffsetX, const float lineOffsetY, const bool flip, Point anchorPoint, const uint16_t anchorSegment, const GeometryCoordinates& line, const mat4& labelPlaneMatrix) { @@ -198,8 +204,14 @@ namespace mbgl { return {{ p, segmentAngle }}; } - void placeGlyphsAlongLine(const PlacedSymbol& symbol, const float fontSize, const bool flip, const mat4& labelPlaneMatrix, - gl::VertexVector& dynamicVertexArray) { + PlacementResult placeGlyphsAlongLine(const PlacedSymbol& symbol, + const float fontSize, + const bool flip, + const bool keepUpright, + const mat4& posMatrix, + const mat4& labelPlaneMatrix, + const mat4& glCoordMatrix, + gl::VertexVector& dynamicVertexArray) { const float fontScale = fontSize / 24.0; const float lineOffsetX = symbol.lineOffset[0] * fontSize; const float lineOffsetY = symbol.lineOffset[1] * fontSize; @@ -207,19 +219,60 @@ namespace mbgl { const Point anchorPoint = project(symbol.anchorPoint, labelPlaneMatrix); std::vector placedGlyphs; - for (auto glyphOffsetX : symbol.glyphOffsets) { - auto placedGlyph = placeGlyphAlongLine(glyphOffsetX * fontScale, lineOffsetX, lineOffsetY, flip, anchorPoint, symbol.segment, symbol.line, labelPlaneMatrix); - if (placedGlyph) { + if (symbol.glyphOffsets.size() > 1) { + + const float firstGlyphOffset = symbol.glyphOffsets.front(); + const float lastGlyphOffset = symbol.glyphOffsets.back(); + + optional firstPlacedGlyph = placeGlyphAlongLine(fontScale * firstGlyphOffset, lineOffsetX, lineOffsetY, flip, anchorPoint, symbol.segment, symbol.line, labelPlaneMatrix); + if (!firstPlacedGlyph) + return PlacementResult::NotEnoughRoom; + + optional lastPlacedGlyph = placeGlyphAlongLine(fontScale * lastGlyphOffset, lineOffsetX, lineOffsetY, flip, anchorPoint, symbol.segment, symbol.line, labelPlaneMatrix); + if (!lastPlacedGlyph) + return PlacementResult::NotEnoughRoom; + + const Point firstPoint = project(firstPlacedGlyph->point, glCoordMatrix); + const Point lastPoint = project(lastPlacedGlyph->point, glCoordMatrix); + + if (keepUpright && !flip && + (symbol.useVerticalMode ? firstPoint.y < lastPoint.y : firstPoint.x > lastPoint.x)) { + return PlacementResult::NeedsFlipping; + } + + placedGlyphs.push_back(*firstPlacedGlyph); + for (size_t glyphIndex = 1; glyphIndex < symbol.glyphOffsets.size() - 1; glyphIndex++) { + const float glyphOffsetX = symbol.glyphOffsets[glyphIndex]; + // Since first and last glyph fit on the line, we're sure that the rest of the glyphs can be placed + auto placedGlyph = placeGlyphAlongLine(glyphOffsetX * fontScale, lineOffsetX, lineOffsetY, flip, anchorPoint, symbol.segment, symbol.line, labelPlaneMatrix); placedGlyphs.push_back(*placedGlyph); - } else { - hideGlyphs(symbol.glyphOffsets.size(), dynamicVertexArray); - return; } + placedGlyphs.push_back(*lastPlacedGlyph); + } else { + // Only a single glyph to place + // So, determine whether to flip based on projected angle of the line segment it's on + if (keepUpright && !flip) { + const Point a = project(convertPoint(symbol.line.at(symbol.segment)), posMatrix); + const Point b = project(convertPoint(symbol.line.at(symbol.segment + 1)), posMatrix); + if (symbol.useVerticalMode ? b.y > a.y : b.x < a.x) { + return PlacementResult::NeedsFlipping; + } + } + assert(symbol.glyphOffsets.size() == 1); // We are relying on SymbolInstance.hasText filtering out symbols without any glyphs at all + const float glyphOffsetX = symbol.glyphOffsets.front(); + optional singleGlyph = placeGlyphAlongLine(fontScale * glyphOffsetX, lineOffsetX, lineOffsetY, flip, anchorPoint, symbol.segment, + symbol.line, labelPlaneMatrix); + if (!singleGlyph) + return PlacementResult::NotEnoughRoom; + + placedGlyphs.push_back(*singleGlyph); } for (auto& placedGlyph : placedGlyphs) { addDynamicAttributes(placedGlyph.point, placedGlyph.angle, symbol.placementZoom, dynamicVertexArray); } + + return PlacementResult::OK; } void reprojectLineLabels(gl::VertexVector& dynamicVertexArray, const std::vector& placedSymbols, @@ -229,9 +282,15 @@ namespace mbgl { const ZoomEvaluatedSize partiallyEvaluatedSize = sizeBinder.evaluateForZoom(state.getZoom()); const std::array clippingBuffer = {{ 256.0 / state.getSize().width * 2.0 + 1.0, 256.0 / state.getSize().height * 2.0 + 1.0 }}; + + const bool pitchWithMap = values.pitchAlignment == style::AlignmentType::Map; + const bool rotateWithMap = values.rotationAlignment == style::AlignmentType::Map; + const float pixelsToTileUnits = tile.id.pixelsToTileUnits(1, state.getZoom()); - const mat4 labelPlaneMatrix = getLabelPlaneMatrix(posMatrix, values.pitchAlignment == style::AlignmentType::Map, - values.rotationAlignment == style::AlignmentType::Map, state, tile.id.pixelsToTileUnits(1, state.getZoom())); + const mat4 labelPlaneMatrix = getLabelPlaneMatrix(posMatrix, pitchWithMap, + rotateWithMap, state, pixelsToTileUnits); + + const mat4 glCoordMatrix = getGlCoordMatrix(posMatrix, pitchWithMap, rotateWithMap, state, pixelsToTileUnits); dynamicVertexArray.clear(); @@ -245,13 +304,6 @@ namespace mbgl { continue; } - bool flip = false; - if (values.keepUpright) { - const Point a = project(convertPoint(placedSymbol.line.at(placedSymbol.segment)), posMatrix); - const Point b = project(convertPoint(placedSymbol.line.at(placedSymbol.segment + 1)), posMatrix); - flip = placedSymbol.useVerticalMode ? b.y > a.y : b.x < a.x; - } - const float cameraToAnchorDistance = anchorPos[3]; const float perspectiveRatio = 1 + 0.5 * ((cameraToAnchorDistance / state.getCameraToCenterDistance()) - 1.0); @@ -260,7 +312,13 @@ namespace mbgl { fontSize * perspectiveRatio : fontSize / perspectiveRatio; - placeGlyphsAlongLine(placedSymbol, pitchScaledFontSize, flip, labelPlaneMatrix, dynamicVertexArray); + PlacementResult placeUnflipped = placeGlyphsAlongLine(placedSymbol, pitchScaledFontSize, false /*unflipped*/, values.keepUpright, posMatrix, labelPlaneMatrix, glCoordMatrix, dynamicVertexArray); + + if (placeUnflipped == PlacementResult::NotEnoughRoom || + (placeUnflipped == PlacementResult::NeedsFlipping && + placeGlyphsAlongLine(placedSymbol, pitchScaledFontSize, true /*flipped*/, values.keepUpright, posMatrix, labelPlaneMatrix, glCoordMatrix, dynamicVertexArray) == PlacementResult::NotEnoughRoom)) { + hideGlyphs(placedSymbol.glyphOffsets.size(), dynamicVertexArray); + } } } } // end namespace mbgl -- cgit v1.2.1 From af10e2d3be5f24c1887622c63332a3cf67bc19d5 Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Tue, 11 Jul 2017 11:28:41 -0700 Subject: [test] Re-enable keep-upright test for pitched views. --- mapbox-gl-js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapbox-gl-js b/mapbox-gl-js index c2e061bda5..2839cb13bc 160000 --- a/mapbox-gl-js +++ b/mapbox-gl-js @@ -1 +1 @@ -Subproject commit c2e061bda532ea848ed39550fe3aa4f95847cc90 +Subproject commit 2839cb13bc05779404222f179dfe80f1a23f1718 -- cgit v1.2.1 From e8657becc56c2aee5b070357092da028e752d461 Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Tue, 11 Jul 2017 11:22:39 -0700 Subject: [core] Update shaders. Implements 'icon-pitch-alignment' (issue #9345) Fixes issue #9456 (map-aligned point label regression) --- .../style/conversion/make_property_setters.hpp | 1 + include/mbgl/style/layers/symbol_layer.hpp | 4 + include/mbgl/util/size.hpp | 4 + .../mapbox/mapboxsdk/style/layers/Property.java | 26 +++ .../mapboxsdk/style/layers/PropertyFactory.java | 23 +++ .../mapbox/mapboxsdk/style/layers/SymbolLayer.java | 12 ++ .../com/mapbox/mapboxsdk/style/light/Light.java | 20 +-- .../mapboxsdk/testapp/style/CircleLayerTest.java | 54 +++--- .../mapboxsdk/testapp/style/LineLayerTest.java | 181 ++++++++++++--------- .../mapboxsdk/testapp/style/SymbolLayerTest.java | 48 ++++++ platform/android/src/style/layers/symbol_layer.cpp | 7 + platform/android/src/style/layers/symbol_layer.hpp | 2 + platform/darwin/src/MGLSymbolStyleLayer.h | 52 ++++++ platform/darwin/src/MGLSymbolStyleLayer.mm | 33 ++++ platform/darwin/test/MGLSymbolStyleLayerTests.mm | 43 +++++ src/mbgl/layout/symbol_layout.cpp | 5 +- src/mbgl/programs/symbol_program.cpp | 7 + src/mbgl/programs/symbol_program.hpp | 10 +- src/mbgl/renderer/layers/render_symbol_layer.cpp | 2 +- src/mbgl/shaders/symbol_icon.cpp | 17 +- src/mbgl/shaders/symbol_sdf.cpp | 19 ++- src/mbgl/style/layers/symbol_layer.cpp | 16 ++ src/mbgl/style/layers/symbol_layer_properties.hpp | 6 + 23 files changed, 466 insertions(+), 126 deletions(-) diff --git a/include/mbgl/style/conversion/make_property_setters.hpp b/include/mbgl/style/conversion/make_property_setters.hpp index 1c26aeb5e4..f29d5f5b6f 100644 --- a/include/mbgl/style/conversion/make_property_setters.hpp +++ b/include/mbgl/style/conversion/make_property_setters.hpp @@ -45,6 +45,7 @@ auto makeLayoutPropertySetters() { result["icon-padding"] = &setProperty, &SymbolLayer::setIconPadding>; result["icon-keep-upright"] = &setProperty, &SymbolLayer::setIconKeepUpright>; result["icon-offset"] = &setProperty>, &SymbolLayer::setIconOffset>; + result["icon-pitch-alignment"] = &setProperty, &SymbolLayer::setIconPitchAlignment>; result["text-pitch-alignment"] = &setProperty, &SymbolLayer::setTextPitchAlignment>; result["text-rotation-alignment"] = &setProperty, &SymbolLayer::setTextRotationAlignment>; result["text-field"] = &setProperty, &SymbolLayer::setTextField>; diff --git a/include/mbgl/style/layers/symbol_layer.hpp b/include/mbgl/style/layers/symbol_layer.hpp index 8158f267c9..f4d0322dc7 100644 --- a/include/mbgl/style/layers/symbol_layer.hpp +++ b/include/mbgl/style/layers/symbol_layer.hpp @@ -98,6 +98,10 @@ public: DataDrivenPropertyValue> getIconOffset() const; void setIconOffset(DataDrivenPropertyValue>); + static PropertyValue getDefaultIconPitchAlignment(); + PropertyValue getIconPitchAlignment() const; + void setIconPitchAlignment(PropertyValue); + static PropertyValue getDefaultTextPitchAlignment(); PropertyValue getTextPitchAlignment() const; void setTextPitchAlignment(PropertyValue); diff --git a/include/mbgl/util/size.hpp b/include/mbgl/util/size.hpp index 45c303969c..12c0ad056b 100644 --- a/include/mbgl/util/size.hpp +++ b/include/mbgl/util/size.hpp @@ -15,6 +15,10 @@ public: constexpr uint32_t area() const { return width * height; } + + constexpr float aspectRatio() const { + return static_cast(width) / static_cast(height); + } constexpr bool isEmpty() const { return width == 0 || height == 0; 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 d3d0e060dc..be24b65d27 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 @@ -160,6 +160,32 @@ public final class Property { @Retention(RetentionPolicy.SOURCE) public @interface ICON_TEXT_FIT {} + // ICON_PITCH_ALIGNMENT: Orientation of icon when map is pitched. + + /** + * The icon is aligned to the plane of the map. + */ + public static final String ICON_PITCH_ALIGNMENT_MAP = "map"; + /** + * The icon is aligned to the plane of the viewport. + */ + public static final String ICON_PITCH_ALIGNMENT_VIEWPORT = "viewport"; + /** + * Automatically matches the value of {@link ICON_ROTATION_ALIGNMENT}. + */ + public static final String ICON_PITCH_ALIGNMENT_AUTO = "auto"; + + /** + * Orientation of icon when map is pitched. + */ + @StringDef({ + ICON_PITCH_ALIGNMENT_MAP, + ICON_PITCH_ALIGNMENT_VIEWPORT, + ICON_PITCH_ALIGNMENT_AUTO, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ICON_PITCH_ALIGNMENT {} + // TEXT_PITCH_ALIGNMENT: Orientation of text when map is pitched. /** 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 c12d6b7133..1c68878772 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 @@ -1881,6 +1881,29 @@ public class PropertyFactory { return new LayoutPropertyValue<>("icon-offset", function); } + /** + * Orientation of icon when map is pitched. + * + * @param value a String value + * @return property wrapper around String + */ + public static PropertyValue iconPitchAlignment(@Property.ICON_PITCH_ALIGNMENT String value) { + return new LayoutPropertyValue<>("icon-pitch-alignment", value); + } + + + + /** + * Orientation of icon when map is pitched. + * + * @param the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String + * @return property wrapper around a String function + */ + public static PropertyValue> iconPitchAlignment(CameraFunction function) { + return new LayoutPropertyValue<>("icon-pitch-alignment", function); + } + /** * Orientation of text when map is pitched. * 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 290e162da8..fe81dcb638 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 @@ -251,6 +251,16 @@ public class SymbolLayer extends Layer { return (PropertyValue) new PropertyValue("icon-offset", nativeGetIconOffset()); } + /** + * Get the IconPitchAlignment property + * + * @return property wrapper value around String + */ + @SuppressWarnings("unchecked") + public PropertyValue getIconPitchAlignment() { + return (PropertyValue) new PropertyValue("icon-pitch-alignment", nativeGetIconPitchAlignment()); + } + /** * Get the TextPitchAlignment property * @@ -891,6 +901,8 @@ public class SymbolLayer extends Layer { private native Object nativeGetIconOffset(); + private native Object nativeGetIconPitchAlignment(); + private native Object nativeGetTextPitchAlignment(); private native Object nativeGetTextRotationAlignment(); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Light.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Light.java index cb6465a6b1..8f23e7d01e 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Light.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/light/Light.java @@ -43,8 +43,7 @@ public class Light { * * @return anchor as String */ - @Property.ANCHOR - public String getAnchor() { + @Property.ANCHOR public String getAnchor() { return nativeGetAnchor(); } @@ -107,7 +106,7 @@ public class Light { * * @return color as String */ - public String getColor() { + public String getColor() { return nativeGetColor(); } @@ -143,7 +142,7 @@ public class Light { * * @return intensity as Float */ - public float getIntensity() { + public float getIntensity() { return nativeGetIntensity(); } @@ -166,30 +165,17 @@ public class Light { } private native void nativeSetAnchor(String anchor); - private native String nativeGetAnchor(); - private native void nativeSetPosition(Position position); - private native Position nativeGetPosition(); - private native TransitionOptions nativeGetPositionTransition(); - private native void nativeSetPositionTransition(long duration, long delay); - private native void nativeSetColor(String color); - private native String nativeGetColor(); - private native TransitionOptions nativeGetColorTransition(); - private native void nativeSetColorTransition(long duration, long delay); - private native void nativeSetIntensity(float intensity); - private native float nativeGetIntensity(); - private native TransitionOptions nativeGetIntensityTransition(); - private native void nativeSetIntensityTransition(long duration, long delay); } \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java index 84f4c16801..559e446307 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java @@ -1052,11 +1052,16 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-pitch-alignment"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set and Get - layer.setProperties(circlePitchAlignment(CIRCLE_PITCH_ALIGNMENT_MAP)); - assertEquals((String) layer.getCirclePitchAlignment().getValue(), (String) CIRCLE_PITCH_ALIGNMENT_MAP); + // Set and Get + layer.setProperties(circlePitchAlignment(CIRCLE_PITCH_ALIGNMENT_MAP)); + assertEquals((String) layer.getCirclePitchAlignment().getValue(), (String) CIRCLE_PITCH_ALIGNMENT_MAP); + } + }); } @Test @@ -1064,25 +1069,30 @@ public class CircleLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("circle-pitch-alignment"); - assertNotNull(layer); - - // Set - layer.setProperties( - circlePitchAlignment( - zoom( - interval( - stop(2, circlePitchAlignment(CIRCLE_PITCH_ALIGNMENT_MAP)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + circlePitchAlignment( + zoom( + interval( + stop(2, circlePitchAlignment(CIRCLE_PITCH_ALIGNMENT_MAP)) + ) + ) ) - ) - ) - ); - - // Verify - assertNotNull(layer.getCirclePitchAlignment()); - assertNotNull(layer.getCirclePitchAlignment().getFunction()); - assertEquals(CameraFunction.class, layer.getCirclePitchAlignment().getFunction().getClass()); - assertEquals(IntervalStops.class, layer.getCirclePitchAlignment().getFunction().getStops().getClass()); - assertEquals(1, ((IntervalStops) layer.getCirclePitchAlignment().getFunction().getStops()).size()); + ); + + // Verify + assertNotNull(layer.getCirclePitchAlignment()); + assertNotNull(layer.getCirclePitchAlignment().getFunction()); + assertEquals(CameraFunction.class, layer.getCirclePitchAlignment().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getCirclePitchAlignment().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getCirclePitchAlignment().getFunction().getStops()).size()); + } + }); } @Test diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java index 234bc583d7..7bdf47aff4 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java @@ -865,19 +865,24 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-width"); - assertNotNull(layer); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); - // Set - layer.setProperties( - lineWidth(property("FeaturePropertyA", Stops.identity())) - ); + // Set + layer.setProperties( + lineWidth(property("FeaturePropertyA", Stops.identity())) + ); - // Verify - assertNotNull(layer.getLineWidth()); - assertNotNull(layer.getLineWidth().getFunction()); - assertEquals(SourceFunction.class, layer.getLineWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineWidth().getFunction()).getProperty()); - assertEquals(IdentityStops.class, layer.getLineWidth().getFunction().getStops().getClass()); + // Verify + assertNotNull(layer.getLineWidth()); + assertNotNull(layer.getLineWidth().getFunction()); + assertEquals(SourceFunction.class, layer.getLineWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineWidth().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getLineWidth().getFunction().getStops().getClass()); + } + }); } @Test @@ -885,26 +890,31 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineWidth( - property( - "FeaturePropertyA", - exponential( - stop(0.3f, lineWidth(0.3f)) - ).withBase(0.5f) - ) - ) - ); - - // Verify - assertNotNull(layer.getLineWidth()); - assertNotNull(layer.getLineWidth().getFunction()); - assertEquals(SourceFunction.class, layer.getLineWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineWidth().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getLineWidth().getFunction().getStops().getClass()); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineWidth( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, lineWidth(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getLineWidth()); + assertNotNull(layer.getLineWidth().getFunction()); + assertEquals(SourceFunction.class, layer.getLineWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineWidth().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getLineWidth().getFunction().getStops().getClass()); + } + }); } @Test @@ -912,29 +922,35 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineWidth( - property( - "FeaturePropertyA", - categorical( - stop(1.0f, lineWidth(0.3f)) + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineWidth( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, lineWidth(0.3f)) + ) + ).withDefaultValue(lineWidth(0.3f)) ) - ).withDefaultValue(lineWidth(0.3f)) - ) - ); + ); + + // Verify + assertNotNull(layer.getLineWidth()); + assertNotNull(layer.getLineWidth().getFunction()); + assertEquals(SourceFunction.class, layer.getLineWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineWidth().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getLineWidth().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getLineWidth().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getLineWidth().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getLineWidth().getFunction()).getDefaultValue().getValue()); + } + }); - // Verify - assertNotNull(layer.getLineWidth()); - assertNotNull(layer.getLineWidth().getFunction()); - assertEquals(SourceFunction.class, layer.getLineWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineWidth().getFunction()).getProperty()); - assertEquals(CategoricalStops.class, layer.getLineWidth().getFunction().getStops().getClass()); - assertNotNull(((SourceFunction) layer.getLineWidth().getFunction()).getDefaultValue()); - assertNotNull(((SourceFunction) layer.getLineWidth().getFunction()).getDefaultValue().getValue()); - assertEquals(0.3f, ((SourceFunction) layer.getLineWidth().getFunction()).getDefaultValue().getValue()); } @Test @@ -942,34 +958,39 @@ public class LineLayerTest extends BaseActivityTest { validateTestSetup(); setupLayer(); Timber.i("line-width"); - assertNotNull(layer); - - // Set - layer.setProperties( - lineWidth( - composite( - "FeaturePropertyA", - exponential( - stop(0, 0.3f, lineWidth(0.9f)) - ).withBase(0.5f) - ).withDefaultValue(lineWidth(0.3f)) - ) - ); - - // Verify - assertNotNull(layer.getLineWidth()); - assertNotNull(layer.getLineWidth().getFunction()); - assertEquals(CompositeFunction.class, layer.getLineWidth().getFunction().getClass()); - assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getLineWidth().getFunction()).getProperty()); - assertEquals(ExponentialStops.class, layer.getLineWidth().getFunction().getStops().getClass()); - assertEquals(1, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).size()); - - ExponentialStops, Float> stops = - (ExponentialStops, Float>) layer.getLineWidth().getFunction().getStops(); - Stop, Float> stop = stops.iterator().next(); - assertEquals(0f, stop.in.zoom, 0.001); - assertEquals(0.3f, stop.in.value, 0.001f); - assertEquals(0.9f, stop.out, 0.001f); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineWidth( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, lineWidth(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(lineWidth(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getLineWidth()); + assertNotNull(layer.getLineWidth().getFunction()); + assertEquals(CompositeFunction.class, layer.getLineWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getLineWidth().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getLineWidth().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getLineWidth().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getLineWidth().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); } @Test 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 b0854f4a47..fc8c4320a5 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 @@ -1213,6 +1213,54 @@ public class SymbolLayerTest extends BaseActivityTest { }); } + @Test + public void testIconPitchAlignmentAsConstant() { + validateTestSetup(); + setupLayer(); + Timber.i("icon-pitch-alignment"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(iconPitchAlignment(ICON_PITCH_ALIGNMENT_MAP)); + assertEquals((String) layer.getIconPitchAlignment().getValue(), (String) ICON_PITCH_ALIGNMENT_MAP); + } + }); + } + + @Test + public void testIconPitchAlignmentAsCameraFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("icon-pitch-alignment"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + iconPitchAlignment( + zoom( + interval( + stop(2, iconPitchAlignment(ICON_PITCH_ALIGNMENT_MAP)) + ) + ) + ) + ); + + // Verify + assertNotNull(layer.getIconPitchAlignment()); + assertNotNull(layer.getIconPitchAlignment().getFunction()); + assertEquals(CameraFunction.class, layer.getIconPitchAlignment().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getIconPitchAlignment().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getIconPitchAlignment().getFunction().getStops()).size()); + } + }); + } + @Test public void testTextPitchAlignmentAsConstant() { validateTestSetup(); diff --git a/platform/android/src/style/layers/symbol_layer.cpp b/platform/android/src/style/layers/symbol_layer.cpp index 3a560a5deb..b6cf51ec7e 100644 --- a/platform/android/src/style/layers/symbol_layer.cpp +++ b/platform/android/src/style/layers/symbol_layer.cpp @@ -125,6 +125,12 @@ namespace android { return jni::Object(*converted); } + jni::Object SymbolLayer::getIconPitchAlignment(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconPitchAlignment()); + return jni::Object(*converted); + } + jni::Object SymbolLayer::getTextPitchAlignment(jni::JNIEnv& env) { using namespace mbgl::android::conversion; Result converted = convert(env, layer.as()->SymbolLayer::getTextPitchAlignment()); @@ -514,6 +520,7 @@ namespace android { METHOD(&SymbolLayer::getIconPadding, "nativeGetIconPadding"), METHOD(&SymbolLayer::getIconKeepUpright, "nativeGetIconKeepUpright"), METHOD(&SymbolLayer::getIconOffset, "nativeGetIconOffset"), + METHOD(&SymbolLayer::getIconPitchAlignment, "nativeGetIconPitchAlignment"), METHOD(&SymbolLayer::getTextPitchAlignment, "nativeGetTextPitchAlignment"), METHOD(&SymbolLayer::getTextRotationAlignment, "nativeGetTextRotationAlignment"), METHOD(&SymbolLayer::getTextField, "nativeGetTextField"), diff --git a/platform/android/src/style/layers/symbol_layer.hpp b/platform/android/src/style/layers/symbol_layer.hpp index 8366051c6e..6d3da13ae9 100644 --- a/platform/android/src/style/layers/symbol_layer.hpp +++ b/platform/android/src/style/layers/symbol_layer.hpp @@ -59,6 +59,8 @@ public: jni::Object getIconOffset(jni::JNIEnv&); + jni::Object getIconPitchAlignment(jni::JNIEnv&); + jni::Object getTextPitchAlignment(jni::JNIEnv&); jni::Object getTextRotationAlignment(jni::JNIEnv&); diff --git a/platform/darwin/src/MGLSymbolStyleLayer.h b/platform/darwin/src/MGLSymbolStyleLayer.h index 5df995aa01..f8df073efe 100644 --- a/platform/darwin/src/MGLSymbolStyleLayer.h +++ b/platform/darwin/src/MGLSymbolStyleLayer.h @@ -7,6 +7,27 @@ NS_ASSUME_NONNULL_BEGIN +/** + Orientation of icon when map is pitched. + + Values of this type are used in the `MGLSymbolStyleLayer.iconPitchAlignment` + property. + */ +typedef NS_ENUM(NSUInteger, MGLIconPitchAlignment) { + /** + The icon is aligned to the plane of the map. + */ + MGLIconPitchAlignmentMap, + /** + The icon is aligned to the plane of the viewport. + */ + MGLIconPitchAlignmentViewport, + /** + Automatically matches the value of `iconRotationAlignment`. + */ + MGLIconPitchAlignmentAuto, +}; + /** In combination with `symbolPlacement`, determines the rotation behavior of icons. @@ -476,6 +497,24 @@ MGL_EXPORT */ @property (nonatomic, null_resettable) MGLStyleValue *iconPadding; +/** + Orientation of icon when map is pitched. + + The default value of this property is an `MGLStyleValue` object containing an + `NSValue` object containing `MGLIconPitchAlignmentAuto`. Set this property to + `nil` to reset it to the default value. + + This property is only applied to the style if `iconImageName` is non-`nil`. + Otherwise, it is ignored. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of + `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue *iconPitchAlignment; + /** Rotates the icon clockwise. @@ -1924,6 +1963,19 @@ MGL_EXPORT #pragma mark Working with Symbol Style Layer Attribute Values +/** + Creates a new value object containing the given `MGLIconPitchAlignment` enumeration. + + @param iconPitchAlignment The value for the new object. + @return A new value object that contains the enumeration value. + */ ++ (instancetype)valueWithMGLIconPitchAlignment:(MGLIconPitchAlignment)iconPitchAlignment; + +/** + The `MGLIconPitchAlignment` enumeration representation of the value. + */ +@property (readonly) MGLIconPitchAlignment MGLIconPitchAlignmentValue; + /** Creates a new value object containing the given `MGLIconRotationAlignment` enumeration. diff --git a/platform/darwin/src/MGLSymbolStyleLayer.mm b/platform/darwin/src/MGLSymbolStyleLayer.mm index 5a8f8c6084..dd43ebd73c 100644 --- a/platform/darwin/src/MGLSymbolStyleLayer.mm +++ b/platform/darwin/src/MGLSymbolStyleLayer.mm @@ -13,6 +13,12 @@ namespace mbgl { + MBGL_DEFINE_ENUM(MGLIconPitchAlignment, { + { MGLIconPitchAlignmentMap, "map" }, + { MGLIconPitchAlignmentViewport, "viewport" }, + { MGLIconPitchAlignmentAuto, "auto" }, + }); + MBGL_DEFINE_ENUM(MGLIconRotationAlignment, { { MGLIconRotationAlignmentMap, "map" }, { MGLIconRotationAlignmentViewport, "viewport" }, @@ -259,6 +265,23 @@ namespace mbgl { return MGLStyleValueTransformer().toStyleValue(propertyValue); } +- (void)setIconPitchAlignment:(MGLStyleValue *)iconPitchAlignment { + MGLAssertStyleLayerIsValid(); + + auto mbglValue = MGLStyleValueTransformer().toEnumPropertyValue(iconPitchAlignment); + self.rawLayer->setIconPitchAlignment(mbglValue); +} + +- (MGLStyleValue *)iconPitchAlignment { + MGLAssertStyleLayerIsValid(); + + auto propertyValue = self.rawLayer->getIconPitchAlignment(); + if (propertyValue.isUndefined()) { + return MGLStyleValueTransformer().toEnumStyleValue(self.rawLayer->getDefaultIconPitchAlignment()); + } + return MGLStyleValueTransformer().toEnumStyleValue(propertyValue); +} + - (void)setIconRotation:(MGLStyleValue *)iconRotation { MGLAssertStyleLayerIsValid(); @@ -1321,6 +1344,16 @@ namespace mbgl { @implementation NSValue (MGLSymbolStyleLayerAdditions) ++ (NSValue *)valueWithMGLIconPitchAlignment:(MGLIconPitchAlignment)iconPitchAlignment { + return [NSValue value:&iconPitchAlignment withObjCType:@encode(MGLIconPitchAlignment)]; +} + +- (MGLIconPitchAlignment)MGLIconPitchAlignmentValue { + MGLIconPitchAlignment iconPitchAlignment; + [self getValue:&iconPitchAlignment]; + return iconPitchAlignment; +} + + (NSValue *)valueWithMGLIconRotationAlignment:(MGLIconRotationAlignment)iconRotationAlignment { return [NSValue value:&iconRotationAlignment withObjCType:@encode(MGLIconRotationAlignment)]; } diff --git a/platform/darwin/test/MGLSymbolStyleLayerTests.mm b/platform/darwin/test/MGLSymbolStyleLayerTests.mm index 367ebf363c..5e969e27ca 100644 --- a/platform/darwin/test/MGLSymbolStyleLayerTests.mm +++ b/platform/darwin/test/MGLSymbolStyleLayerTests.mm @@ -301,6 +301,45 @@ XCTAssertThrowsSpecificNamed(layer.iconPadding = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); } + // icon-pitch-alignment + { + XCTAssertTrue(rawLayer->getIconPitchAlignment().isUndefined(), + @"icon-pitch-alignment should be unset initially."); + MGLStyleValue *defaultStyleValue = layer.iconPitchAlignment; + + MGLStyleValue *constantStyleValue = [MGLStyleValue valueWithRawValue:[NSValue valueWithMGLIconPitchAlignment:MGLIconPitchAlignmentAuto]]; + layer.iconPitchAlignment = constantStyleValue; + mbgl::style::PropertyValue propertyValue = { mbgl::style::AlignmentType::Auto }; + XCTAssertEqual(rawLayer->getIconPitchAlignment(), propertyValue, + @"Setting iconPitchAlignment to a constant value should update icon-pitch-alignment."); + XCTAssertEqualObjects(layer.iconPitchAlignment, constantStyleValue, + @"iconPitchAlignment should round-trip constant values."); + + MGLStyleValue * functionStyleValue = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.iconPitchAlignment = functionStyleValue; + + mbgl::style::IntervalStops intervalStops = { {{18, mbgl::style::AlignmentType::Auto}} }; + propertyValue = mbgl::style::CameraFunction { intervalStops }; + + XCTAssertEqual(rawLayer->getIconPitchAlignment(), propertyValue, + @"Setting iconPitchAlignment to a camera function should update icon-pitch-alignment."); + XCTAssertEqualObjects(layer.iconPitchAlignment, functionStyleValue, + @"iconPitchAlignment should round-trip camera functions."); + + + + layer.iconPitchAlignment = nil; + XCTAssertTrue(rawLayer->getIconPitchAlignment().isUndefined(), + @"Unsetting iconPitchAlignment should return icon-pitch-alignment to the default value."); + XCTAssertEqualObjects(layer.iconPitchAlignment, defaultStyleValue, + @"iconPitchAlignment should return the default value after being unset."); + + functionStyleValue = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.iconPitchAlignment = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + functionStyleValue = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.iconPitchAlignment = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + } + // icon-rotate { XCTAssertTrue(rawLayer->getIconRotate().isUndefined(), @@ -2321,6 +2360,7 @@ [self testPropertyName:@"icon-offset" isBoolean:NO]; [self testPropertyName:@"is-icon-optional" isBoolean:YES]; [self testPropertyName:@"icon-padding" isBoolean:NO]; + [self testPropertyName:@"icon-pitch-alignment" isBoolean:NO]; [self testPropertyName:@"icon-rotation" isBoolean:NO]; [self testPropertyName:@"icon-rotation-alignment" isBoolean:NO]; [self testPropertyName:@"icon-scale" isBoolean:NO]; @@ -2366,6 +2406,9 @@ } - (void)testValueAdditions { + XCTAssertEqual([NSValue valueWithMGLIconPitchAlignment:MGLIconPitchAlignmentMap].MGLIconPitchAlignmentValue, MGLIconPitchAlignmentMap); + XCTAssertEqual([NSValue valueWithMGLIconPitchAlignment:MGLIconPitchAlignmentViewport].MGLIconPitchAlignmentValue, MGLIconPitchAlignmentViewport); + XCTAssertEqual([NSValue valueWithMGLIconPitchAlignment:MGLIconPitchAlignmentAuto].MGLIconPitchAlignmentValue, MGLIconPitchAlignmentAuto); XCTAssertEqual([NSValue valueWithMGLIconRotationAlignment:MGLIconRotationAlignmentMap].MGLIconRotationAlignmentValue, MGLIconRotationAlignmentMap); XCTAssertEqual([NSValue valueWithMGLIconRotationAlignment:MGLIconRotationAlignmentViewport].MGLIconRotationAlignmentValue, MGLIconRotationAlignmentViewport); XCTAssertEqual([NSValue valueWithMGLIconRotationAlignment:MGLIconRotationAlignmentAuto].MGLIconRotationAlignmentValue, MGLIconRotationAlignmentAuto); diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index e308da618f..956ba770dd 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -75,10 +75,13 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, } } - // If unspecified `text-pitch-alignment` inherits `text-rotation-alignment` + // If unspecified `*-pitch-alignment` inherits `*-rotation-alignment` if (layout.get() == AlignmentType::Auto) { layout.get() = layout.get(); } + if (layout.get() == AlignmentType::Auto) { + layout.get() = layout.get(); + } const bool hasText = has(layout) && !layout.get().empty(); const bool hasIcon = has(layout); diff --git a/src/mbgl/programs/symbol_program.cpp b/src/mbgl/programs/symbol_program.cpp index 8790adcc63..58174ff8a7 100644 --- a/src/mbgl/programs/symbol_program.cpp +++ b/src/mbgl/programs/symbol_program.cpp @@ -52,6 +52,11 @@ Values makeValues(const bool isText, const float pixelsToTileUnits = tile.id.pixelsToTileUnits(1.0, state.getZoom()); const bool pitchWithMap = values.pitchAlignment == style::AlignmentType::Map; const bool rotateWithMap = values.rotationAlignment == style::AlignmentType::Map; + + // Line label rotation happens in `updateLineLabels` + // Pitched point labels are automatically rotated by the labelPlaneMatrix projection + // Unpitched point labels need to have their rotation applied after projection + const bool rotateInShader = rotateWithMap && !pitchWithMap && !alongLine; mat4 labelPlaneMatrix; if (alongLine) { @@ -84,6 +89,8 @@ Values makeValues(const bool isText, uniforms::u_pitch::Value{ state.getPitch() }, uniforms::u_pitch_with_map::Value{ pitchWithMap }, uniforms::u_max_camera_distance::Value{ values.maxCameraDistance }, + uniforms::u_rotate_symbol::Value{ rotateInShader }, + uniforms::u_aspect_ratio::Value{ state.getSize().aspectRatio() }, std::forward(args)... }; } diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index 79a961ad21..c74837b121 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -41,6 +41,8 @@ MBGL_DEFINE_UNIFORM_SCALAR(bool, u_is_size_feature_constant); MBGL_DEFINE_UNIFORM_SCALAR(float, u_size_t); MBGL_DEFINE_UNIFORM_SCALAR(float, u_size); MBGL_DEFINE_UNIFORM_SCALAR(float, u_max_camera_distance); +MBGL_DEFINE_UNIFORM_SCALAR(bool, u_rotate_symbol); +MBGL_DEFINE_UNIFORM_SCALAR(float, u_aspect_ratio); } // namespace uniforms struct SymbolLayoutAttributes : gl::Attributes< @@ -348,7 +350,9 @@ class SymbolIconProgram : public SymbolProgram< uniforms::u_camera_to_center_distance, uniforms::u_pitch, uniforms::u_pitch_with_map, - uniforms::u_max_camera_distance>, + uniforms::u_max_camera_distance, + uniforms::u_rotate_symbol, + uniforms::u_aspect_ratio>, style::IconPaintProperties> { public: @@ -387,6 +391,8 @@ class SymbolSDFProgram : public SymbolProgram< uniforms::u_pitch, uniforms::u_pitch_with_map, uniforms::u_max_camera_distance, + uniforms::u_rotate_symbol, + uniforms::u_aspect_ratio, uniforms::u_gamma_scale, uniforms::u_is_halo>, PaintProperties> @@ -409,6 +415,8 @@ public: uniforms::u_pitch, uniforms::u_pitch_with_map, uniforms::u_max_camera_distance, + uniforms::u_rotate_symbol, + uniforms::u_aspect_ratio, uniforms::u_gamma_scale, uniforms::u_is_halo>, PaintProperties>; diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index 2fe6dd971e..2af7b2f7ca 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -82,7 +82,7 @@ style::TextPaintProperties::PossiblyEvaluated RenderSymbolLayer::textPaintProper style::SymbolPropertyValues RenderSymbolLayer::iconPropertyValues(const style::SymbolLayoutProperties::PossiblyEvaluated& layout_) const { return style::SymbolPropertyValues { - layout_.get(), // icon-pitch-alignment is not yet implemented; inherit the rotation alignment + layout_.get(), layout_.get(), layout_.get(), evaluated.get(), diff --git a/src/mbgl/shaders/symbol_icon.cpp b/src/mbgl/shaders/symbol_icon.cpp index cb00cdad05..c0e3a0ac01 100644 --- a/src/mbgl/shaders/symbol_icon.cpp +++ b/src/mbgl/shaders/symbol_icon.cpp @@ -19,6 +19,8 @@ uniform highp float u_size_t; // used to interpolate between zoom stops when siz uniform highp float u_size; // used when size is both zoom and feature constant uniform highp float u_camera_to_center_distance; uniform highp float u_pitch; +uniform bool u_rotate_symbol; +uniform highp float u_aspect_ratio; uniform highp float u_collision_y_stretch; @@ -83,8 +85,19 @@ void main() { float fontScale = u_is_text ? size / 24.0 : size; - highp float angle_sin = sin(segment_angle); - highp float angle_cos = cos(segment_angle); + highp float symbol_rotation = 0.0; + if (u_rotate_symbol) { + // See comments in symbol_sdf.vertex + vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), 0, 1); + + vec2 a = projectedPoint.xy / projectedPoint.w; + vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w; + + symbol_rotation = atan((b.y - a.y) / u_aspect_ratio, b.x - a.x); + } + + highp float angle_sin = sin(segment_angle + symbol_rotation); + highp float angle_cos = cos(segment_angle + symbol_rotation); mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, 0.0, 1.0); diff --git a/src/mbgl/shaders/symbol_sdf.cpp b/src/mbgl/shaders/symbol_sdf.cpp index b4158bacc5..2050886957 100644 --- a/src/mbgl/shaders/symbol_sdf.cpp +++ b/src/mbgl/shaders/symbol_sdf.cpp @@ -73,6 +73,8 @@ uniform mat4 u_gl_coord_matrix; uniform bool u_is_text; uniform bool u_pitch_with_map; uniform highp float u_pitch; +uniform bool u_rotate_symbol; +uniform highp float u_aspect_ratio; uniform highp float u_camera_to_center_distance; uniform highp float u_collision_y_stretch; @@ -151,8 +153,21 @@ void main() { float fontScale = u_is_text ? size / 24.0 : size; - highp float angle_sin = sin(segment_angle); - highp float angle_cos = cos(segment_angle); + highp float symbol_rotation = 0.0; + if (u_rotate_symbol) { + // Point labels with 'rotation-alignment: map' are horizontal with respect to tile units + // To figure out that angle in projected space, we draw a short horizontal line in tile + // space, project it, and measure its angle in projected space. + vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), 0, 1); + + vec2 a = projectedPoint.xy / projectedPoint.w; + vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w; + + symbol_rotation = atan((b.y - a.y) / u_aspect_ratio, b.x - a.x); + } + + highp float angle_sin = sin(segment_angle + symbol_rotation); + highp float angle_cos = cos(segment_angle + symbol_rotation); mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, 0.0, 1.0); diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp index 182b4b0a48..c102c64a94 100644 --- a/src/mbgl/style/layers/symbol_layer.cpp +++ b/src/mbgl/style/layers/symbol_layer.cpp @@ -332,6 +332,22 @@ void SymbolLayer::setIconOffset(DataDrivenPropertyValue> va baseImpl = std::move(impl_); observer->onLayerChanged(*this); } +PropertyValue SymbolLayer::getDefaultIconPitchAlignment() { + return IconPitchAlignment::defaultValue(); +} + +PropertyValue SymbolLayer::getIconPitchAlignment() const { + return impl().layout.get(); +} + +void SymbolLayer::setIconPitchAlignment(PropertyValue value) { + if (value == getIconPitchAlignment()) + return; + auto impl_ = mutableImpl(); + impl_->layout.get() = value; + baseImpl = std::move(impl_); + observer->onLayerChanged(*this); +} PropertyValue SymbolLayer::getDefaultTextPitchAlignment() { return TextPitchAlignment::defaultValue(); } diff --git a/src/mbgl/style/layers/symbol_layer_properties.hpp b/src/mbgl/style/layers/symbol_layer_properties.hpp index f7ceaecdaa..4b2bff01b8 100644 --- a/src/mbgl/style/layers/symbol_layer_properties.hpp +++ b/src/mbgl/style/layers/symbol_layer_properties.hpp @@ -87,6 +87,11 @@ struct IconOffset : DataDrivenLayoutProperty> { static std::array defaultValue() { return {{ 0, 0 }}; } }; +struct IconPitchAlignment : LayoutProperty { + static constexpr const char * key = "icon-pitch-alignment"; + static AlignmentType defaultValue() { return AlignmentType::Auto; } +}; + struct TextPitchAlignment : LayoutProperty { static constexpr const char * key = "text-pitch-alignment"; static AlignmentType defaultValue() { return AlignmentType::Auto; } @@ -254,6 +259,7 @@ class SymbolLayoutProperties : public Properties< IconPadding, IconKeepUpright, IconOffset, + IconPitchAlignment, TextPitchAlignment, TextRotationAlignment, TextField, -- cgit v1.2.1 From 7abbe32325c5e345002858231681f369937574be Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Wed, 12 Jul 2017 13:39:01 -0700 Subject: [test] Pull in re-enabled tests from mapbox-gl-js. --- mapbox-gl-js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapbox-gl-js b/mapbox-gl-js index 2839cb13bc..d6b4d98bb9 160000 --- a/mapbox-gl-js +++ b/mapbox-gl-js @@ -1 +1 @@ -Subproject commit 2839cb13bc05779404222f179dfe80f1a23f1718 +Subproject commit d6b4d98bb94932fcb1a279eb876a71e40f4780da -- cgit v1.2.1 From fbbc8f2d7ae461c1004a1bc69ff8451f4ca35fc1 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 12 Jul 2017 13:40:32 -0700 Subject: [tests] Local ignores.json file for ignored integration tests --- mapbox-gl-js | 2 +- platform/node/test/ignores.json | 61 +++++++++++++++++++++++++++++++++++++++ platform/node/test/query.test.js | 9 +++--- platform/node/test/render.test.js | 9 +++--- 4 files changed, 72 insertions(+), 9 deletions(-) create mode 100644 platform/node/test/ignores.json diff --git a/mapbox-gl-js b/mapbox-gl-js index d6b4d98bb9..83c7fc2ee7 160000 --- a/mapbox-gl-js +++ b/mapbox-gl-js @@ -1 +1 @@ -Subproject commit d6b4d98bb94932fcb1a279eb876a71e40f4780da +Subproject commit 83c7fc2ee78522de9905c4a49cd9c4665caa22a5 diff --git a/platform/node/test/ignores.json b/platform/node/test/ignores.json new file mode 100644 index 0000000000..ae8a1d1039 --- /dev/null +++ b/platform/node/test/ignores.json @@ -0,0 +1,61 @@ +{ + "query-tests/geometry/multilinestring": "needs investigation", + "query-tests/geometry/multipolygon": "needs investigation", + "query-tests/geometry/polygon": "needs investigation", + "query-tests/regressions/mapbox-gl-js#3534": "https://github.com/mapbox/mapbox-gl-native/issues/8193", + "query-tests/regressions/mapbox-gl-js#4417": "https://github.com/mapbox/mapbox-gl-native/issues/8007", + "query-tests/symbol-features-in/pitched-screen": "https://github.com/mapbox/mapbox-gl-native/issues/6817", + "query-tests/symbol-features-in/tilted-inside": "https://github.com/mapbox/mapbox-gl-native/issues/5056", + "query-tests/symbol-features-in/tilted-outside": "https://github.com/mapbox/mapbox-gl-native/issues/9435", + "query-tests/world-wrapping/box": "skip - needs issue", + "query-tests/world-wrapping/point": "skip - needs issue", + "render-tests/circle-pitch-alignment/map-scale-map": "https://github.com/mapbox/mapbox-gl-native/issues/9349", + "render-tests/circle-pitch-alignment/map-scale-viewport": "https://github.com/mapbox/mapbox-gl-native/issues/9349", + "render-tests/circle-pitch-alignment/viewport-scale-map": "https://github.com/mapbox/mapbox-gl-native/issues/9349", + "render-tests/circle-pitch-alignment/viewport-scale-viewport": "https://github.com/mapbox/mapbox-gl-native/issues/9349", + "render-tests/debug/collision-overscaled": "https://github.com/mapbox/mapbox-gl-native/issues/3841", + "render-tests/debug/collision-pitched-wrapped": "https://github.com/mapbox/mapbox-gl-native/issues/3841", + "render-tests/debug/collision-pitched": "https://github.com/mapbox/mapbox-gl-native/issues/3841", + "render-tests/debug/collision": "https://github.com/mapbox/mapbox-gl-native/issues/3841", + "render-tests/debug/tile-overscaled": "https://github.com/mapbox/mapbox-gl-native/issues/3841", + "render-tests/debug/tile": "https://github.com/mapbox/mapbox-gl-native/issues/3841", + "render-tests/extent/1024-circle": "needs investigation", + "render-tests/extent/1024-symbol": "needs investigation", + "render-tests/fill-extrusion-pattern/@2x": "https://github.com/mapbox/mapbox-gl-js/issues/3327", + "render-tests/fill-extrusion-pattern/function-2": "https://github.com/mapbox/mapbox-gl-js/issues/3327", + "render-tests/fill-extrusion-pattern/function": "https://github.com/mapbox/mapbox-gl-js/issues/3327", + "render-tests/fill-extrusion-pattern/literal": "https://github.com/mapbox/mapbox-gl-js/issues/3327", + "render-tests/fill-extrusion-pattern/missing": "https://github.com/mapbox/mapbox-gl-js/issues/3327", + "render-tests/fill-extrusion-pattern/opacity": "https://github.com/mapbox/mapbox-gl-js/issues/3327", + "render-tests/fill-outline-color/fill": "https://github.com/mapbox/mapbox-gl-native/pull/8760", + "render-tests/fill-outline-color/function": "https://github.com/mapbox/mapbox-gl-native/issues/6927", + "render-tests/fill-outline-color/literal": "https://github.com/mapbox/mapbox-gl-native/issues/6927", + "render-tests/fill-outline-color/multiply": "https://github.com/mapbox/mapbox-gl-native/issues/6927", + "render-tests/fill-outline-color/opacity": "https://github.com/mapbox/mapbox-gl-native/issues/6927", + "render-tests/fill-outline-color/zoom-and-property-function": "https://github.com/mapbox/mapbox-gl-native/issues/6927", + "render-tests/geojson/inline-linestring-fill": "current behavior is arbitrary", + "render-tests/geojson/inline-polygon-symbol": "behavior needs reconciliation with gl-js", + "render-tests/icon-size/composite-function-high-base-plain": "https://github.com/mapbox/mapbox-gl-native/issues/8654", + "render-tests/icon-size/composite-function-high-base-sdf": "https://github.com/mapbox/mapbox-gl-native/issues/8654", + "render-tests/icon-text-fit/both-padding": "https://github.com/mapbox/mapbox-gl-native/issues/5602", + "render-tests/icon-text-fit/both": "https://github.com/mapbox/mapbox-gl-native/issues/5602", + "render-tests/icon-text-fit/height": "https://github.com/mapbox/mapbox-gl-native/issues/5602", + "render-tests/icon-text-fit/width-padding": "https://github.com/mapbox/mapbox-gl-native/issues/5602", + "render-tests/icon-text-fit/width": "https://github.com/mapbox/mapbox-gl-native/issues/5602", + "render-tests/line-width/property-function": "https://github.com/mapbox/mapbox-gl-js/issues/3682#issuecomment-264348200", + "render-tests/regressions/mapbox-gl-js#2305": "https://github.com/mapbox/mapbox-gl-native/issues/6927", + "render-tests/regressions/mapbox-gl-js#3010": "skip - needs issue", + "render-tests/regressions/mapbox-gl-js#3548": "skip - needs issue", + "render-tests/regressions/mapbox-gl-js#3682": "https://github.com/mapbox/mapbox-gl-js/issues/3682", + "render-tests/regressions/mapbox-gl-js#4550": "skip - https://github.com/mapbox/mapbox-gl-native/issues/1350", + "render-tests/regressions/mapbox-gl-js#4551": "skip - https://github.com/mapbox/mapbox-gl-native/issues/1350", + "render-tests/regressions/mapbox-gl-js#4573": "skip - https://github.com/mapbox/mapbox-gl-native/issues/1350", + "render-tests/regressions/mapbox-gl-native#7357": "https://github.com/mapbox/mapbox-gl-native/issues/7357", + "render-tests/runtime-styling/paint-property-fill-flat-to-extrude": "skip - https://github.com/mapbox/mapbox-gl-native/issues/6745", + "render-tests/runtime-styling/set-style-paint-property-fill-flat-to-extrude": "skip - needs issue", + "render-tests/runtime-styling/source-add-geojson-inline": "skip - needs issue", + "render-tests/symbol-placement/line": "needs issue", + "render-tests/text-keep-upright/line-placement-true-offset": "https://github.com/mapbox/mapbox-gl-native/issues/9271", + "render-tests/text-size/composite-function-high-base": "https://github.com/mapbox/mapbox-gl-native/issues/8654", + "render-tests/video/default": "skip - needs issue" +} \ No newline at end of file diff --git a/platform/node/test/query.test.js b/platform/node/test/query.test.js index 8125f1c7cd..02602d3f5a 100644 --- a/platform/node/test/query.test.js +++ b/platform/node/test/query.test.js @@ -1,12 +1,13 @@ 'use strict'; -var suite = require('../../../mapbox-gl-js/test/integration').query; -var suiteImplementation = require('./suite_implementation'); +const suite = require('../../../mapbox-gl-js/test/integration').query; +const suiteImplementation = require('./suite_implementation'); +const ignores = require('./ignores.json'); -var tests; +let tests; if (process.argv[1] === __filename && process.argv.length > 2) { tests = process.argv.slice(2); } -suite.run('native', {tests: tests}, suiteImplementation); +suite.run('native', {tests: tests, ignores: ignores}, suiteImplementation); diff --git a/platform/node/test/render.test.js b/platform/node/test/render.test.js index e2e13534c9..c8a214e919 100644 --- a/platform/node/test/render.test.js +++ b/platform/node/test/render.test.js @@ -1,12 +1,13 @@ 'use strict'; -var suite = require('../../../mapbox-gl-js/test/integration').render; -var suiteImplementation = require('./suite_implementation'); +const suite = require('../../../mapbox-gl-js/test/integration').render; +const suiteImplementation = require('./suite_implementation'); +const ignores = require('./ignores.json'); -var tests; +let tests; if (process.argv[1] === __filename && process.argv.length > 2) { tests = process.argv.slice(2); } -suite.run('native', {tests: tests}, suiteImplementation); +suite.run('native', {tests: tests, ignores: ignores}, suiteImplementation); -- cgit v1.2.1 From 8fb212dbb3f43c51f75747629db5c39f44b0c28a Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 5 Jul 2017 14:45:34 -0700 Subject: [core] Include what you use --- src/mbgl/gl/program.hpp | 2 +- src/mbgl/renderer/render_style.cpp | 1 + src/mbgl/renderer/sources/render_image_source.cpp | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp index 583d53e4ec..ce2b5a335b 100644 --- a/src/mbgl/gl/program.hpp +++ b/src/mbgl/gl/program.hpp @@ -9,11 +9,11 @@ #include #include +#include #include #include #include - #include namespace mbgl { diff --git a/src/mbgl/renderer/render_style.cpp b/src/mbgl/renderer/render_style.cpp index 25dbba76f6..47639a57e7 100644 --- a/src/mbgl/renderer/render_style.cpp +++ b/src/mbgl/renderer/render_style.cpp @@ -28,6 +28,7 @@ #include #include #include +#include namespace mbgl { diff --git a/src/mbgl/renderer/sources/render_image_source.cpp b/src/mbgl/renderer/sources/render_image_source.cpp index 6a3cb33fec..f1860b6b62 100644 --- a/src/mbgl/renderer/sources/render_image_source.cpp +++ b/src/mbgl/renderer/sources/render_image_source.cpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace mbgl { -- cgit v1.2.1 From fedfaa2f6e582e87b190f5d423302f9f95d147d9 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 3 Jul 2017 14:05:12 -0700 Subject: [core] Inline getActiveAttributes details --- src/mbgl/gl/attribute.cpp | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/src/mbgl/gl/attribute.cpp b/src/mbgl/gl/attribute.cpp index 4569e3cb32..5583cfd916 100644 --- a/src/mbgl/gl/attribute.cpp +++ b/src/mbgl/gl/attribute.cpp @@ -13,39 +13,25 @@ AttributeLocation bindAttributeLocation(ProgramID id, AttributeLocation location return location; } -int32_t getActiveAttributeCount(ProgramID id) { - GLint numAttributes; - MBGL_CHECK_ERROR(glGetProgramiv(id, GL_ACTIVE_ATTRIBUTES, &numAttributes)); - return numAttributes; -} +std::set getActiveAttributes(ProgramID id) { + std::set activeAttributes; -int32_t getMaxAttributeNameLength(ProgramID id) { - GLint nameLength; - MBGL_CHECK_ERROR(glGetProgramiv(id, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &nameLength)); - return nameLength; -} + GLint attributeCount; + MBGL_CHECK_ERROR(glGetProgramiv(id, GL_ACTIVE_ATTRIBUTES, &attributeCount)); + + GLint maxAttributeLength; + MBGL_CHECK_ERROR(glGetProgramiv(id, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttributeLength)); -std::string getAttributeName(ProgramID id, int32_t maxLength, AttributeLocation location) { std::string attributeName; - attributeName.resize(maxLength); + attributeName.resize(maxAttributeLength); + GLsizei actualLength; GLint size; GLenum type; - MBGL_CHECK_ERROR(glGetActiveAttrib(id, static_cast(location), - static_cast(maxLength), &actualLength, &size, &type, - const_cast(attributeName.data()))); - attributeName.resize(actualLength); - return attributeName; -} - -std::set getActiveAttributes(ProgramID id) { - std::set activeAttributes; - - GLint attributeCount = getActiveAttributeCount(id); - GLint maxAttributeLength = getMaxAttributeNameLength(id); for (int32_t i = 0; i < attributeCount; i++) { - activeAttributes.emplace(getAttributeName(id, maxAttributeLength, i)); + MBGL_CHECK_ERROR(glGetActiveAttrib(id, i, maxAttributeLength, &actualLength, &size, &type, &attributeName[0])); + activeAttributes.emplace(std::string(attributeName, 0, actualLength)); } return activeAttributes; -- cgit v1.2.1 From c61041b44cd9181641db2351f4657cc356300226 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 3 Jul 2017 14:05:12 -0700 Subject: [core] Rework attribute binding (again) These changes are necessary for programs whose set of active attributes is not fixed at compile time by a template parameter pack, but rather varies based on the generated shader text at runtime. In such cases, the attribute location of a given named attribute may vary between instances of the same Program. Previously, attribute bindings were implicitly associated with a location based on template parameter order, and -1 was used to indicate an inactive attribute. This left us unable to disable the appropriate attribute when it went from active to inactive. Now, the state tracker for bindings explicitly associates locations and state, and an empty optional is used to indicate an inactive attribute. In addition, a gl::VertexArray class is now exposed, allowing more flexibility in the relationship between Programs, Segments, and attribute bindings. In this commit, that relationship does not change, but the subsequent commit adjusts it to match gl-js, reduce rebinds, and work around buggy VAO implementations. VertexArray uses a pimpl idiom in order to support implementations that lack the VAO extension. In that case, all VertexArrays share global binding state, reflecting the platform reality in the absence of VAOs, while still providing a uniform API. --- cmake/core-files.cmake | 8 +- src/mbgl/gl/attribute.cpp | 63 +-------- src/mbgl/gl/attribute.hpp | 150 +++++++++++---------- src/mbgl/gl/context.cpp | 31 +++-- src/mbgl/gl/context.hpp | 12 +- src/mbgl/gl/object.cpp | 4 +- src/mbgl/gl/program.hpp | 26 ++-- src/mbgl/gl/segment.cpp | 7 - src/mbgl/gl/segment.hpp | 73 ---------- src/mbgl/gl/types.hpp | 2 +- src/mbgl/gl/uniform.hpp | 2 +- src/mbgl/gl/value.cpp | 18 +++ src/mbgl/gl/value.hpp | 7 + src/mbgl/gl/vertex_array.cpp | 18 +++ src/mbgl/gl/vertex_array.hpp | 58 ++++++++ src/mbgl/programs/binary_program.cpp | 4 +- src/mbgl/programs/binary_program.hpp | 4 +- src/mbgl/programs/program.hpp | 42 +++--- src/mbgl/programs/segment.cpp | 7 + src/mbgl/programs/segment.hpp | 40 ++++++ src/mbgl/programs/symbol_program.hpp | 46 ++++--- src/mbgl/renderer/buckets/circle_bucket.hpp | 4 +- src/mbgl/renderer/buckets/debug_bucket.hpp | 2 +- src/mbgl/renderer/buckets/fill_bucket.hpp | 6 +- .../renderer/buckets/fill_extrusion_bucket.hpp | 4 +- src/mbgl/renderer/buckets/line_bucket.hpp | 4 +- src/mbgl/renderer/buckets/raster_bucket.hpp | 2 +- src/mbgl/renderer/buckets/symbol_bucket.hpp | 8 +- src/mbgl/renderer/layers/render_custom_layer.cpp | 2 +- src/mbgl/renderer/paint_property_binder.hpp | 15 ++- src/mbgl/renderer/painter.cpp | 2 +- src/mbgl/renderer/painter.hpp | 8 +- test/programs/binary_program.test.cpp | 16 +-- 33 files changed, 376 insertions(+), 319 deletions(-) delete mode 100644 src/mbgl/gl/segment.cpp delete mode 100644 src/mbgl/gl/segment.hpp create mode 100644 src/mbgl/gl/vertex_array.cpp create mode 100644 src/mbgl/gl/vertex_array.hpp create mode 100644 src/mbgl/programs/segment.cpp create mode 100644 src/mbgl/programs/segment.hpp diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index d912392e15..4ebb2a878d 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -73,8 +73,6 @@ set(MBGL_CORE_FILES src/mbgl/gl/program.hpp src/mbgl/gl/program_binary_extension.hpp src/mbgl/gl/renderbuffer.hpp - src/mbgl/gl/segment.cpp - src/mbgl/gl/segment.hpp src/mbgl/gl/state.hpp src/mbgl/gl/stencil_mode.cpp src/mbgl/gl/stencil_mode.hpp @@ -84,6 +82,8 @@ set(MBGL_CORE_FILES src/mbgl/gl/uniform.hpp src/mbgl/gl/value.cpp src/mbgl/gl/value.hpp + src/mbgl/gl/vertex_array.cpp + src/mbgl/gl/vertex_array.hpp src/mbgl/gl/vertex_array_extension.hpp src/mbgl/gl/vertex_buffer.hpp @@ -154,6 +154,8 @@ set(MBGL_CORE_FILES src/mbgl/programs/programs.hpp src/mbgl/programs/raster_program.cpp src/mbgl/programs/raster_program.hpp + src/mbgl/programs/segment.cpp + src/mbgl/programs/segment.hpp src/mbgl/programs/symbol_program.cpp src/mbgl/programs/symbol_program.hpp src/mbgl/programs/uniforms.hpp @@ -611,8 +613,8 @@ set(MBGL_CORE_FILES src/mbgl/util/stopwatch.cpp src/mbgl/util/stopwatch.hpp src/mbgl/util/string.cpp - src/mbgl/util/thread_local.hpp src/mbgl/util/thread.hpp + src/mbgl/util/thread_local.hpp src/mbgl/util/throttler.cpp src/mbgl/util/throttler.hpp src/mbgl/util/tile_coordinate.hpp diff --git a/src/mbgl/gl/attribute.cpp b/src/mbgl/gl/attribute.cpp index 5583cfd916..bb5b2ddc34 100644 --- a/src/mbgl/gl/attribute.cpp +++ b/src/mbgl/gl/attribute.cpp @@ -1,16 +1,14 @@ #include -#include #include -#include - namespace mbgl { namespace gl { -AttributeLocation bindAttributeLocation(ProgramID id, AttributeLocation location, const char* name) { - assert(location < 8); +void bindAttributeLocation(ProgramID id, AttributeLocation location, const char* name) { + if (location >= MAX_ATTRIBUTES) { + throw gl::Error("too many vertex attributes"); + } MBGL_CHECK_ERROR(glBindAttribLocation(id, location, name)); - return location; } std::set getActiveAttributes(ProgramID id) { @@ -37,58 +35,5 @@ std::set getActiveAttributes(ProgramID id) { return activeAttributes; } -void DisabledAttribute::bind(Context&, AttributeLocation location, std::size_t) const { - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); -} - -template -constexpr DataType DataTypeOf() { - return std::is_same::value ? DataType::Byte : - std::is_same::value ? DataType::UnsignedByte : - std::is_same::value ? DataType::Short : - std::is_same::value ? DataType::UnsignedShort : - std::is_same::value ? DataType::Integer : - std::is_same::value ? DataType::UnsignedInteger : - std::is_same::value ? DataType::Float : static_cast(0); -} - -template -void AttributeBinding::bind(Context& context, AttributeLocation location, std::size_t vertexOffset) const { - // FillProgram will attempt to bind at location -1 because it includes - // a fill-outline-color paint property but does not use it or have an - // a_outline_color shader attribute - in this case, we have nothing to bind. - if (location == -1) return; - - context.vertexBuffer = vertexBuffer; - MBGL_CHECK_ERROR(glEnableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttribPointer( - location, - static_cast(attributeSize), - static_cast(DataTypeOf()), - static_cast(false), - static_cast(vertexSize), - reinterpret_cast(attributeOffset + (vertexSize * vertexOffset)))); -} - -template class AttributeBinding; -template class AttributeBinding; -template class AttributeBinding; -template class AttributeBinding; - -template class AttributeBinding; -template class AttributeBinding; -template class AttributeBinding; -template class AttributeBinding; - -template class AttributeBinding; -template class AttributeBinding; -template class AttributeBinding; -template class AttributeBinding; - -template class AttributeBinding; -template class AttributeBinding; -template class AttributeBinding; -template class AttributeBinding; - } // namespace gl } // namespace mbgl diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp index bc02b54bd2..1f60c8c980 100644 --- a/src/mbgl/gl/attribute.hpp +++ b/src/mbgl/gl/attribute.hpp @@ -1,59 +1,51 @@ #pragma once #include -#include +#include #include #include -#include +#include #include #include #include #include +#include +#include namespace mbgl { namespace gl { -class DisabledAttribute { -public: - void bind(Context&, AttributeLocation, std::size_t vertexOffset) const; +static constexpr std::size_t MAX_ATTRIBUTES = 8; - friend bool operator==(const DisabledAttribute&, - const DisabledAttribute&) { - return true; - } -}; +template struct DataTypeOf; +template <> struct DataTypeOf< int8_t> : std::integral_constant {}; +template <> struct DataTypeOf : std::integral_constant {}; +template <> struct DataTypeOf< int16_t> : std::integral_constant {}; +template <> struct DataTypeOf : std::integral_constant {}; +template <> struct DataTypeOf< int32_t> : std::integral_constant {}; +template <> struct DataTypeOf : std::integral_constant {}; +template <> struct DataTypeOf : std::integral_constant {}; -template class AttributeBinding { public: - AttributeBinding(BufferID vertexBuffer_, - std::size_t vertexSize_, - std::size_t attributeOffset_, - std::size_t attributeSize_ = N) - : vertexBuffer(vertexBuffer_), - vertexSize(vertexSize_), - attributeOffset(attributeOffset_), - attributeSize(attributeSize_) - {} - - void bind(Context&, AttributeLocation, std::size_t vertexOffset) const; + DataType attributeType; + std::size_t attributeSize; + std::size_t attributeOffset; + + BufferID vertexBuffer; + std::size_t vertexSize; + std::size_t vertexOffset; friend bool operator==(const AttributeBinding& lhs, const AttributeBinding& rhs) { - return lhs.vertexBuffer == rhs.vertexBuffer - && lhs.vertexSize == rhs.vertexSize - && lhs.attributeOffset == rhs.attributeOffset - && lhs.attributeSize == rhs.attributeSize; + return std::tie(lhs.attributeType, lhs.attributeSize, lhs.attributeOffset, lhs.vertexBuffer, lhs.vertexSize, lhs.vertexOffset) + == std::tie(rhs.attributeType, rhs.attributeSize, rhs.attributeOffset, rhs.vertexBuffer, rhs.vertexSize, rhs.vertexOffset); } - -private: - BufferID vertexBuffer; - std::size_t vertexSize; - std::size_t attributeOffset; - std::size_t attributeSize; }; +using AttributeBindingArray = std::array, MAX_ATTRIBUTES>; + /* gl::Attribute manages the binding of a vertex buffer to a GL program attribute. - T is the underlying primitive type (exposed as Attribute::ValueType) @@ -67,10 +59,7 @@ public: using Value = std::array; using Location = AttributeLocation; - - using Binding = variant< - DisabledAttribute, - AttributeBinding>; + using Binding = AttributeBinding; /* Create a binding for this attribute. The `attributeSize` parameter may be used to @@ -82,28 +71,24 @@ public: std::size_t attributeIndex, std::size_t attributeSize = N) { static_assert(std::is_standard_layout::value, "vertex type must use standard layout"); - return AttributeBinding { + return AttributeBinding { + DataTypeOf::value, + attributeSize, + Vertex::attributeOffsets[attributeIndex], buffer.buffer, sizeof(Vertex), - Vertex::attributeOffsets[attributeIndex], - attributeSize + 0, }; } - static void bind(Context& context, - const Location& location, - Binding& oldBinding, - const Binding& newBinding, - std::size_t vertexOffset) { - if (oldBinding == newBinding) { - return; + static optional offsetBinding(const optional& binding, std::size_t vertexOffset) { + if (binding) { + AttributeBinding result = *binding; + result.vertexOffset = vertexOffset; + return result; + } else { + return binding; } - - Binding::visit(newBinding, [&] (const auto& binding) { - binding.bind(context, location, vertexOffset); - }); - - oldBinding = newBinding; } }; @@ -223,7 +208,7 @@ const std::size_t Vertex::attributeOffsets[5] = { } // namespace detail -AttributeLocation bindAttributeLocation(ProgramID, AttributeLocation, const char * name); +void bindAttributeLocation(ProgramID, AttributeLocation, const char * name); std::set getActiveAttributes(ProgramID); template @@ -232,10 +217,10 @@ public: using Types = TypeList; using Locations = IndexedTuple< TypeList, - TypeList>; + TypeList...>>; using Bindings = IndexedTuple< TypeList, - TypeList>; + TypeList...>>; using NamedLocations = std::vector>; using Vertex = detail::Vertex; @@ -243,13 +228,17 @@ public: static Locations bindLocations(const ProgramID& id) { std::set activeAttributes = getActiveAttributes(id); - AttributeLocation location = -1; - auto bindAndIncrement = [&](const char* name) { - location++; - return bindAttributeLocation(id, location, name); + AttributeLocation location = 0; + auto maybeBindLocation = [&](const char* name) -> optional { + if (activeAttributes.count(name)) { + bindAttributeLocation(id, location, name); + return location++; + } else { + return {}; + } }; - return Locations{ (activeAttributes.count(As::name()) ? bindAndIncrement(As::name()) - : -1)... }; + + return Locations { maybeBindLocation(As::name())... }; } template @@ -258,7 +247,17 @@ public: } static NamedLocations getNamedLocations(const Locations& locations) { - return NamedLocations{ { As::name(), locations.template get() }... }; + NamedLocations result; + + auto maybeAddLocation = [&] (const std::string& name, const optional& location) { + if (location) { + result.emplace_back(name, *location); + } + }; + + util::ignore({ (maybeAddLocation(As::name(), locations.template get()), 0)... }); + + return result; } template @@ -266,16 +265,23 @@ public: return Bindings { As::Type::binding(buffer, TypeIndex::value)... }; } - static void bind(Context& context, - const Locations& locations, - Bindings& oldBindings, - const Bindings& newBindings, - std::size_t vertexOffset) { - util::ignore({ (As::Type::bind(context, - locations.template get(), - oldBindings.template get(), - newBindings.template get(), - vertexOffset), 0)... }); + static Bindings offsetBindings(const Bindings& bindings, std::size_t vertexOffset) { + return Bindings { As::Type::offsetBinding(bindings.template get(), vertexOffset)... }; + } + + static AttributeBindingArray toBindingArray(const Locations& locations, const Bindings& bindings) { + AttributeBindingArray result; + + auto maybeAddBinding = [&] (const optional& location, + const optional& binding) { + if (location) { + result.at(*location) = binding; + } + }; + + util::ignore({ (maybeAddBinding(locations.template get(), bindings.template get()), 0)... }); + + return result; } }; diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index 86ca9c0607..f7d210d52e 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -229,8 +229,8 @@ UniqueBuffer Context::createIndexBuffer(const void* data, std::size_t size) { BufferID id = 0; MBGL_CHECK_ERROR(glGenBuffers(1, &id)); UniqueBuffer result { std::move(id), { this } }; - vertexArrayObject = 0; - elementBuffer = result; + bindVertexArray = 0; + globalVertexArrayState.indexBuffer = result; MBGL_CHECK_ERROR(glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW)); return result; } @@ -281,11 +281,16 @@ optional> Context::getBinaryProgram( } #endif -UniqueVertexArray Context::createVertexArray() { - assert(supportsVertexArrays()); - VertexArrayID id = 0; - MBGL_CHECK_ERROR(vertexArray->genVertexArrays(1, &id)); - return UniqueVertexArray(std::move(id), { this }); +VertexArray Context::createVertexArray() { + if (supportsVertexArrays()) { + VertexArrayID id = 0; + MBGL_CHECK_ERROR(vertexArray->genVertexArrays(1, &id)); + return { std::make_unique(UniqueVertexArray(std::move(id), { this }), *this) }; + } else { + // On GL implementations which do not support vertex arrays, attribute bindings are global state. + // So return a VertexArray which shares our global state tracking and whose deleter is a no-op. + return { UniqueVertexArrayState(&globalVertexArrayState, [] (VertexArrayState*) {}) }; + } } UniqueFramebuffer Context::createFramebuffer() { @@ -553,8 +558,8 @@ void Context::setDirtyState() { tex.setDirty(); } vertexBuffer.setDirty(); - elementBuffer.setDirty(); - vertexArrayObject.setDirty(); + bindVertexArray.setDirty(); + globalVertexArrayState.setDirty(); } void Context::clear(optional color, @@ -673,8 +678,8 @@ void Context::performCleanup() { for (const auto id : abandonedBuffers) { if (vertexBuffer == id) { vertexBuffer.setDirty(); - } else if (elementBuffer == id) { - elementBuffer.setDirty(); + } else if (globalVertexArrayState.indexBuffer == id) { + globalVertexArrayState.indexBuffer.setDirty(); } } MBGL_CHECK_ERROR(glDeleteBuffers(int(abandonedBuffers.size()), abandonedBuffers.data())); @@ -694,8 +699,8 @@ void Context::performCleanup() { if (!abandonedVertexArrays.empty()) { assert(supportsVertexArrays()); for (const auto id : abandonedVertexArrays) { - if (vertexArrayObject == id) { - vertexArrayObject.setDirty(); + if (bindVertexArray == id) { + bindVertexArray.setDirty(); } } MBGL_CHECK_ERROR(vertexArray->deleteVertexArrays(int(abandonedVertexArrays.size()), diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index 2e594618d2..0dd67d2ed7 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -53,9 +54,7 @@ public: void verifyProgramLinkage(ProgramID); void linkProgram(ProgramID); UniqueTexture createTexture(); - - bool supportsVertexArrays() const; - UniqueVertexArray createVertexArray(); + VertexArray createVertexArray(); #if MBGL_HAS_BINARY_PROGRAMS bool supportsProgramBinaries() const; @@ -207,10 +206,11 @@ public: State viewport; State scissorTest; std::array, 2> texture; - State vertexArrayObject { *this }; State program; State vertexBuffer; - State elementBuffer; + + State bindVertexArray { *this }; + VertexArrayState globalVertexArrayState { UniqueVertexArray(0, { this }), *this }; State pixelStorePack; State pixelStoreUnpack; @@ -257,6 +257,8 @@ private: void drawPixels(Size size, const void* data, TextureFormat); #endif // MBGL_USE_GLES2 + bool supportsVertexArrays() const; + friend detail::ProgramDeleter; friend detail::ShaderDeleter; friend detail::BufferDeleter; diff --git a/src/mbgl/gl/object.cpp b/src/mbgl/gl/object.cpp index e2d476e0c0..2c5f1bca1f 100644 --- a/src/mbgl/gl/object.cpp +++ b/src/mbgl/gl/object.cpp @@ -33,7 +33,9 @@ void TextureDeleter::operator()(TextureID id) const { void VertexArrayDeleter::operator()(VertexArrayID id) const { assert(context); - context->abandonedVertexArrays.push_back(id); + if (id != 0) { + context->abandonedVertexArrays.push_back(id); + } } void FramebufferDeleter::operator()(FramebufferID id) const { diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp index ce2b5a335b..9d8b0a5b04 100644 --- a/src/mbgl/gl/program.hpp +++ b/src/mbgl/gl/program.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -116,10 +117,12 @@ public: DepthMode depthMode, StencilMode stencilMode, ColorMode colorMode, - UniformValues&& uniformValues, - AttributeBindings&& attributeBindings, + const UniformValues& uniformValues, + VertexArray& vertexArray, + const AttributeBindings& attributeBindings, const IndexBuffer& indexBuffer, - const SegmentVector& segments) { + std::size_t indexOffset, + std::size_t indexLength) { static_assert(std::is_same::value, "incompatible draw mode"); context.setDrawMode(drawMode); @@ -129,18 +132,15 @@ public: context.program = program; - Uniforms::bind(uniformsState, std::move(uniformValues)); + Uniforms::bind(uniformsState, uniformValues); - for (const auto& segment : segments) { - segment.bind(context, - indexBuffer.buffer, - attributeLocations, - attributeBindings); + vertexArray.bind(context, + indexBuffer.buffer, + Attributes::toBindingArray(attributeLocations, attributeBindings)); - context.draw(drawMode.primitiveType, - segment.indexOffset, - segment.indexLength); - } + context.draw(drawMode.primitiveType, + indexOffset, + indexLength); } private: diff --git a/src/mbgl/gl/segment.cpp b/src/mbgl/gl/segment.cpp deleted file mode 100644 index aabdc83cd4..0000000000 --- a/src/mbgl/gl/segment.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include - -namespace mbgl { -namespace gl { - -} // namespace gl -} // namespace mbgl diff --git a/src/mbgl/gl/segment.hpp b/src/mbgl/gl/segment.hpp deleted file mode 100644 index fe0658bf8e..0000000000 --- a/src/mbgl/gl/segment.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include -#include - -namespace mbgl { -namespace gl { - -template -class Segment { -public: - Segment(std::size_t vertexOffset_, - std::size_t indexOffset_, - std::size_t vertexLength_ = 0, - std::size_t indexLength_ = 0) - : vertexOffset(vertexOffset_), - indexOffset(indexOffset_), - vertexLength(vertexLength_), - indexLength(indexLength_) {} - - const std::size_t vertexOffset; - const std::size_t indexOffset; - - std::size_t vertexLength; - std::size_t indexLength; - - void bind(Context& context, - BufferID indexBuffer_, - const typename Attributes::Locations& attributeLocations, - const typename Attributes::Bindings& attributeBindings_) const { - if (context.supportsVertexArrays()) { - if (!vao) { - vao = context.createVertexArray(); - context.vertexBuffer.setDirty(); - } - context.vertexArrayObject = *vao; - if (indexBuffer != indexBuffer_) { - indexBuffer = indexBuffer_; - context.elementBuffer.setDirty(); - context.elementBuffer = indexBuffer_; - } - } else { - // No VAO support. Force attributes to be rebound. - context.elementBuffer = indexBuffer_; - attributeBindings = {}; - } - - Attributes::bind(context, - attributeLocations, - attributeBindings, - attributeBindings_, - vertexOffset); - } - -private: - mutable optional vao; - mutable optional indexBuffer; - mutable typename Attributes::Bindings attributeBindings; -}; - -template -class SegmentVector : public std::vector> { -public: - SegmentVector() = default; -}; - -} // namespace gl -} // namespace mbgl diff --git a/src/mbgl/gl/types.hpp b/src/mbgl/gl/types.hpp index 1fce878c6f..058bc226b8 100644 --- a/src/mbgl/gl/types.hpp +++ b/src/mbgl/gl/types.hpp @@ -15,7 +15,7 @@ using VertexArrayID = uint32_t; using FramebufferID = uint32_t; using RenderbufferID = uint32_t; -using AttributeLocation = int32_t; +using AttributeLocation = uint32_t; using UniformLocation = int32_t; using TextureUnit = uint8_t; diff --git a/src/mbgl/gl/uniform.hpp b/src/mbgl/gl/uniform.hpp index 4ed2419764..5a78068fc8 100644 --- a/src/mbgl/gl/uniform.hpp +++ b/src/mbgl/gl/uniform.hpp @@ -115,7 +115,7 @@ public: return NamedLocations{ { Us::name(), state.template get().location }... }; } - static void bind(State& state, Values&& values) { + static void bind(State& state, const Values& values) { util::ignore({ (state.template get() = values.template get(), 0)... }); } }; diff --git a/src/mbgl/gl/value.cpp b/src/mbgl/gl/value.cpp index 2b825fb2bd..89014fe6bc 100644 --- a/src/mbgl/gl/value.cpp +++ b/src/mbgl/gl/value.cpp @@ -365,6 +365,24 @@ BindVertexArray::Type BindVertexArray::Get(const Context& context) { return binding; } +const optional VertexAttribute::Default {}; + +void VertexAttribute::Set(const optional& binding, Context& context, AttributeLocation location) { + if (binding) { + context.vertexBuffer = binding->vertexBuffer; + MBGL_CHECK_ERROR(glEnableVertexAttribArray(location)); + MBGL_CHECK_ERROR(glVertexAttribPointer( + location, + static_cast(binding->attributeSize), + static_cast(binding->attributeType), + static_cast(false), + static_cast(binding->vertexSize), + reinterpret_cast(binding->attributeOffset + (binding->vertexSize * binding->vertexOffset)))); + } else { + MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); + } +} + const constexpr PixelStorePack::Type PixelStorePack::Default; void PixelStorePack::Set(const Type& value) { diff --git a/src/mbgl/gl/value.hpp b/src/mbgl/gl/value.hpp index d4c7b5cdc3..19e9af194f 100644 --- a/src/mbgl/gl/value.hpp +++ b/src/mbgl/gl/value.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -239,6 +240,12 @@ struct BindVertexArray { static Type Get(const Context&); }; +struct VertexAttribute { + using Type = optional; + static const Type Default; + static void Set(const Type&, Context&, AttributeLocation); +}; + struct PixelStorePack { using Type = PixelStorageType; static const constexpr Type Default = { 4 }; diff --git a/src/mbgl/gl/vertex_array.cpp b/src/mbgl/gl/vertex_array.cpp new file mode 100644 index 0000000000..68a500ac45 --- /dev/null +++ b/src/mbgl/gl/vertex_array.cpp @@ -0,0 +1,18 @@ +#include +#include +#include + +namespace mbgl { +namespace gl { + +void VertexArray::bind(Context& context, BufferID indexBuffer, const AttributeBindingArray& bindings) { + context.bindVertexArray = state->vertexArray; + state->indexBuffer = indexBuffer; + + for (AttributeLocation location = 0; location < MAX_ATTRIBUTES; ++location) { + state->bindings[location] = bindings[location]; + } +} + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/gl/vertex_array.hpp b/src/mbgl/gl/vertex_array.hpp new file mode 100644 index 0000000000..9ccf48d9bd --- /dev/null +++ b/src/mbgl/gl/vertex_array.hpp @@ -0,0 +1,58 @@ +#pragma once + +#include +#include +#include +#include + +#include +#include + +namespace mbgl { +namespace gl { + +class Context; + +class VertexArrayState { +public: + VertexArrayState(UniqueVertexArray vertexArray_, Context& context) + : vertexArray(std::move(vertexArray_)), + bindings(makeBindings(context, std::make_index_sequence())) { + } + + void setDirty() { + indexBuffer.setDirty(); + for (auto& binding : bindings) { + binding.setDirty(); + } + } + + UniqueVertexArray vertexArray; + State indexBuffer; + + using AttributeState = State; + std::array bindings; + +private: + template + std::array makeBindings(Context& context, std::index_sequence) { + return {{ AttributeState { context, I }... }}; + } +}; + +using UniqueVertexArrayState = std::unique_ptr>; + +class VertexArray { +public: + VertexArray(UniqueVertexArrayState state_) + : state(std::move(state_)) { + } + + void bind(Context&, BufferID indexBuffer, const AttributeBindingArray&); + +private: + UniqueVertexArrayState state; +}; + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/programs/binary_program.cpp b/src/mbgl/programs/binary_program.cpp index 57f2cc0d2c..da629194b4 100644 --- a/src/mbgl/programs/binary_program.cpp +++ b/src/mbgl/programs/binary_program.cpp @@ -98,7 +98,7 @@ std::string BinaryProgram::serialize() const { return data; } -gl::AttributeLocation BinaryProgram::attributeLocation(const std::string& name) const { +optional BinaryProgram::attributeLocation(const std::string& name) const { for (const auto& pair : attributes) { if (pair.first == name) { return pair.second; @@ -113,7 +113,7 @@ gl::UniformLocation BinaryProgram::uniformLocation(const std::string& name) cons return pair.second; } } - return {}; + return -1; } } // namespace mbgl diff --git a/src/mbgl/programs/binary_program.hpp b/src/mbgl/programs/binary_program.hpp index b77cf1a510..8690f3fd6f 100644 --- a/src/mbgl/programs/binary_program.hpp +++ b/src/mbgl/programs/binary_program.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -29,7 +30,8 @@ public: const std::string& identifier() const { return binaryIdentifier; } - gl::AttributeLocation attributeLocation(const std::string& name) const; + + optional attributeLocation(const std::string& name) const; gl::UniformLocation uniformLocation(const std::string& name) const; private: diff --git a/src/mbgl/programs/program.hpp b/src/mbgl/programs/program.hpp index 3a38f30a86..0199752b06 100644 --- a/src/mbgl/programs/program.hpp +++ b/src/mbgl/programs/program.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -51,26 +52,37 @@ public: gl::DepthMode depthMode, gl::StencilMode stencilMode, gl::ColorMode colorMode, - UniformValues&& uniformValues, + const UniformValues& uniformValues, const gl::VertexBuffer& layoutVertexBuffer, const gl::IndexBuffer& indexBuffer, - const gl::SegmentVector& segments, + const SegmentVector& segments, const PaintPropertyBinders& paintPropertyBinders, const typename PaintProperties::PossiblyEvaluated& currentProperties, float currentZoom) { - program.draw( - context, - std::move(drawMode), - std::move(depthMode), - std::move(stencilMode), - std::move(colorMode), - uniformValues - .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)), - LayoutAttributes::bindings(layoutVertexBuffer) - .concat(paintPropertyBinders.attributeBindings(currentProperties)), - indexBuffer, - segments - ); + typename AllUniforms::Values allUniformValues = uniformValues + .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)); + + typename Attributes::Bindings allAttributeBindings = LayoutAttributes::bindings(layoutVertexBuffer) + .concat(paintPropertyBinders.attributeBindings(currentProperties)); + + for (auto& segment : segments) { + if (!segment.vertexArray) { + segment.vertexArray = context.createVertexArray(); + } + + program.draw( + context, + std::move(drawMode), + std::move(depthMode), + std::move(stencilMode), + std::move(colorMode), + allUniformValues, + *segment.vertexArray, + Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset), + indexBuffer, + segment.indexOffset, + segment.indexLength); + } } }; diff --git a/src/mbgl/programs/segment.cpp b/src/mbgl/programs/segment.cpp new file mode 100644 index 0000000000..bb09843e21 --- /dev/null +++ b/src/mbgl/programs/segment.cpp @@ -0,0 +1,7 @@ +#include + +namespace mbgl { +namespace gl { + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/programs/segment.hpp b/src/mbgl/programs/segment.hpp new file mode 100644 index 0000000000..d8cc9679d7 --- /dev/null +++ b/src/mbgl/programs/segment.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include + +namespace mbgl { + +template +class Segment { +public: + Segment(std::size_t vertexOffset_, + std::size_t indexOffset_, + std::size_t vertexLength_ = 0, + std::size_t indexLength_ = 0) + : vertexOffset(vertexOffset_), + indexOffset(indexOffset_), + vertexLength(vertexLength_), + indexLength(indexLength_) {} + + const std::size_t vertexOffset; + const std::size_t indexOffset; + + std::size_t vertexLength; + std::size_t indexLength; + + mutable optional vertexArray; +}; + +template +class SegmentVector : public std::vector> { +public: + SegmentVector() = default; +}; + +} // namespace mbgl diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index c74837b121..8c59cfd5a2 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -306,30 +307,41 @@ public: gl::DepthMode depthMode, gl::StencilMode stencilMode, gl::ColorMode colorMode, - UniformValues&& uniformValues, + const UniformValues& uniformValues, const gl::VertexBuffer& layoutVertexBuffer, const gl::VertexBuffer& dynamicLayoutVertexBuffer, const SymbolSizeBinder& symbolSizeBinder, const gl::IndexBuffer& indexBuffer, - const gl::SegmentVector& segments, + const SegmentVector& segments, const PaintPropertyBinders& paintPropertyBinders, const typename PaintProperties::PossiblyEvaluated& currentProperties, float currentZoom) { - program.draw( - context, - std::move(drawMode), - std::move(depthMode), - std::move(stencilMode), - std::move(colorMode), - uniformValues - .concat(symbolSizeBinder.uniformValues(currentZoom)) - .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)), - LayoutAttributes::bindings(layoutVertexBuffer) - .concat(SymbolDynamicLayoutAttributes::bindings(dynamicLayoutVertexBuffer)) - .concat(paintPropertyBinders.attributeBindings(currentProperties)), - indexBuffer, - segments - ); + typename AllUniforms::Values allUniformValues = uniformValues + .concat(symbolSizeBinder.uniformValues(currentZoom)) + .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)); + + typename Attributes::Bindings allAttributeBindings = LayoutAttributes::bindings(layoutVertexBuffer) + .concat(SymbolDynamicLayoutAttributes::bindings(dynamicLayoutVertexBuffer)) + .concat(paintPropertyBinders.attributeBindings(currentProperties)); + + for (auto& segment : segments) { + if (!segment.vertexArray) { + segment.vertexArray = context.createVertexArray(); + } + + program.draw( + context, + std::move(drawMode), + std::move(depthMode), + std::move(stencilMode), + std::move(colorMode), + allUniformValues, + *segment.vertexArray, + Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset), + indexBuffer, + segment.indexOffset, + segment.indexLength); + } } }; diff --git a/src/mbgl/renderer/buckets/circle_bucket.hpp b/src/mbgl/renderer/buckets/circle_bucket.hpp index b048fd7675..0f27e2a7e3 100644 --- a/src/mbgl/renderer/buckets/circle_bucket.hpp +++ b/src/mbgl/renderer/buckets/circle_bucket.hpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include @@ -29,7 +29,7 @@ public: gl::VertexVector vertices; gl::IndexVector triangles; - gl::SegmentVector segments; + SegmentVector segments; optional> vertexBuffer; optional> indexBuffer; diff --git a/src/mbgl/renderer/buckets/debug_bucket.hpp b/src/mbgl/renderer/buckets/debug_bucket.hpp index 756e58a6de..fc3128e944 100644 --- a/src/mbgl/renderer/buckets/debug_bucket.hpp +++ b/src/mbgl/renderer/buckets/debug_bucket.hpp @@ -33,7 +33,7 @@ public: const optional expires; const MapDebugOptions debugMode; - gl::SegmentVector segments; + SegmentVector segments; optional> vertexBuffer; optional> indexBuffer; }; diff --git a/src/mbgl/renderer/buckets/fill_bucket.hpp b/src/mbgl/renderer/buckets/fill_bucket.hpp index 421d8b332b..d3cd92d451 100644 --- a/src/mbgl/renderer/buckets/fill_bucket.hpp +++ b/src/mbgl/renderer/buckets/fill_bucket.hpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include @@ -30,8 +30,8 @@ public: gl::VertexVector vertices; gl::IndexVector lines; gl::IndexVector triangles; - gl::SegmentVector lineSegments; - gl::SegmentVector triangleSegments; + SegmentVector lineSegments; + SegmentVector triangleSegments; optional> vertexBuffer; optional> lineIndexBuffer; diff --git a/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp b/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp index c54805d743..d1e695c5a3 100644 --- a/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp +++ b/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include @@ -27,7 +27,7 @@ public: gl::VertexVector vertices; gl::IndexVector triangles; - gl::SegmentVector triangleSegments; + SegmentVector triangleSegments; optional> vertexBuffer; optional> indexBuffer; diff --git a/src/mbgl/renderer/buckets/line_bucket.hpp b/src/mbgl/renderer/buckets/line_bucket.hpp index 34d8935953..c0a0614d33 100644 --- a/src/mbgl/renderer/buckets/line_bucket.hpp +++ b/src/mbgl/renderer/buckets/line_bucket.hpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include @@ -34,7 +34,7 @@ public: gl::VertexVector vertices; gl::IndexVector triangles; - gl::SegmentVector segments; + SegmentVector segments; optional> vertexBuffer; optional> indexBuffer; diff --git a/src/mbgl/renderer/buckets/raster_bucket.hpp b/src/mbgl/renderer/buckets/raster_bucket.hpp index b5cf7997d5..44b9111b81 100644 --- a/src/mbgl/renderer/buckets/raster_bucket.hpp +++ b/src/mbgl/renderer/buckets/raster_bucket.hpp @@ -31,7 +31,7 @@ public: // Raster Tile Sources use the default buffers from Painter gl::VertexVector vertices; gl::IndexVector indices; - gl::SegmentVector segments; + SegmentVector segments; optional> vertexBuffer; optional> indexBuffer; diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp index ffa22e9021..424c9d0f74 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.hpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include #include @@ -63,7 +63,7 @@ public: gl::VertexVector vertices; gl::VertexVector dynamicVertices; gl::IndexVector triangles; - gl::SegmentVector segments; + SegmentVector segments; std::vector placedSymbols; optional> vertexBuffer; @@ -77,7 +77,7 @@ public: gl::VertexVector vertices; gl::VertexVector dynamicVertices; gl::IndexVector triangles; - gl::SegmentVector segments; + SegmentVector segments; std::vector placedSymbols; PremultipliedImage atlasImage; @@ -89,7 +89,7 @@ public: struct CollisionBoxBuffer { gl::VertexVector vertices; gl::IndexVector lines; - gl::SegmentVector segments; + SegmentVector segments; optional> vertexBuffer; optional> dynamicVertexBuffer; diff --git a/src/mbgl/renderer/layers/render_custom_layer.cpp b/src/mbgl/renderer/layers/render_custom_layer.cpp index 4d6084075d..81b8ac301b 100644 --- a/src/mbgl/renderer/layers/render_custom_layer.cpp +++ b/src/mbgl/renderer/layers/render_custom_layer.cpp @@ -48,7 +48,7 @@ void RenderCustomLayer::render(Painter& painter, PaintParameters& paintParameter const TransformState& state = painter.state; // Reset GL state to a known state so the CustomLayer always has a clean slate. - context.vertexArrayObject = 0; + context.bindVertexArray = 0; context.setDepthMode(painter.depthModeForSublayer(0, gl::DepthMode::ReadOnly)); context.setStencilMode(gl::StencilMode::disabled()); context.setColorMode(painter.colorModeForRenderPass()); diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp index f78147fc87..652948c8df 100644 --- a/src/mbgl/renderer/paint_property_binder.hpp +++ b/src/mbgl/renderer/paint_property_binder.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -81,7 +82,7 @@ public: virtual void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) = 0; virtual void upload(gl::Context& context) = 0; - virtual AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const = 0; + virtual optional attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const = 0; virtual float interpolationFactor(float currentZoom) const = 0; virtual T uniformValue(const PossiblyEvaluatedPropertyValue& currentValue) const = 0; @@ -103,8 +104,8 @@ public: void populateVertexVector(const GeometryTileFeature&, std::size_t) override {} void upload(gl::Context&) override {} - AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue&) const override { - return gl::DisabledAttribute(); + optional attributeBinding(const PossiblyEvaluatedPropertyValue&) const override { + return {}; } float interpolationFactor(float) const override { @@ -147,9 +148,9 @@ public: vertexBuffer = context.createVertexBuffer(std::move(vertexVector)); } - AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const override { + optional attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const override { if (currentValue.isConstant()) { - return gl::DisabledAttribute(); + return {}; } else { return Attribute::binding(*vertexBuffer, 0, BaseAttribute::Dimensions); } @@ -208,9 +209,9 @@ public: vertexBuffer = context.createVertexBuffer(std::move(vertexVector)); } - AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const override { + optional attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const override { if (currentValue.isConstant()) { - return gl::DisabledAttribute(); + return {}; } else { return Attribute::binding(*vertexBuffer, 0); } diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index a3decdb603..35d03e7cb4 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -262,7 +262,7 @@ void Painter::render(RenderStyle& style, const FrameData& frame_, View& view) { context.activeTexture = 0; context.texture[0] = 0; - context.vertexArrayObject = 0; + context.bindVertexArray = 0; } } diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp index 7e966adefa..0b6ee3497e 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -172,10 +172,10 @@ public: gl::IndexBuffer quadTriangleIndexBuffer; gl::IndexBuffer tileBorderIndexBuffer; - gl::SegmentVector tileTriangleSegments; - gl::SegmentVector tileBorderSegments; - gl::SegmentVector rasterSegments; - gl::SegmentVector extrusionTextureSegments; + SegmentVector tileTriangleSegments; + SegmentVector tileBorderSegments; + SegmentVector rasterSegments; + SegmentVector extrusionTextureSegments; }; } // namespace mbgl diff --git a/test/programs/binary_program.test.cpp b/test/programs/binary_program.test.cpp index ce544e7652..a5cf7b6e39 100644 --- a/test/programs/binary_program.test.cpp +++ b/test/programs/binary_program.test.cpp @@ -14,12 +14,12 @@ TEST(BinaryProgram, ObtainValues) { EXPECT_EQ(42u, binaryProgram.format()); EXPECT_EQ("binary code", binaryProgram.code()); EXPECT_EQ("identifier", binaryProgram.identifier()); - EXPECT_EQ(1, binaryProgram.attributeLocation("a_pos")); - EXPECT_EQ(0, binaryProgram.attributeLocation("u_world")); - EXPECT_EQ(4, binaryProgram.attributeLocation("a_data")); + EXPECT_EQ(1u, binaryProgram.attributeLocation("a_pos")); + EXPECT_FALSE(binaryProgram.attributeLocation("u_world")); + EXPECT_EQ(4u, binaryProgram.attributeLocation("a_data")); EXPECT_EQ(1, binaryProgram.uniformLocation("u_world")); EXPECT_EQ(3, binaryProgram.uniformLocation("u_ratio")); - EXPECT_EQ(0, binaryProgram.uniformLocation("a_data")); + EXPECT_EQ(-1, binaryProgram.uniformLocation("a_data")); auto serialized = binaryProgram.serialize(); @@ -28,12 +28,12 @@ TEST(BinaryProgram, ObtainValues) { EXPECT_EQ(42u, binaryProgram2.format()); EXPECT_EQ("binary code", binaryProgram2.code()); EXPECT_EQ("identifier", binaryProgram2.identifier()); - EXPECT_EQ(1, binaryProgram2.attributeLocation("a_pos")); - EXPECT_EQ(0, binaryProgram2.attributeLocation("u_world")); - EXPECT_EQ(4, binaryProgram2.attributeLocation("a_data")); + EXPECT_EQ(1u, binaryProgram2.attributeLocation("a_pos")); + EXPECT_FALSE(binaryProgram2.attributeLocation("u_world")); + EXPECT_EQ(4u, binaryProgram2.attributeLocation("a_data")); EXPECT_EQ(1, binaryProgram2.uniformLocation("u_world")); EXPECT_EQ(3, binaryProgram2.uniformLocation("u_ratio")); - EXPECT_EQ(0, binaryProgram2.uniformLocation("a_data")); + EXPECT_EQ(-1, binaryProgram2.uniformLocation("a_data")); EXPECT_THROW(BinaryProgram(""), std::runtime_error); } -- cgit v1.2.1 From 358b0305ae1f52b477ae145bcca4b7af242dd5c3 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Thu, 6 Jul 2017 08:06:12 -0700 Subject: [core] Per-segment-per-layer vertex arrays Reduces rebinding, matches gl-js, and works around the buggy VAO implementation on PowerVR SGX544 GPUs. --- src/mbgl/programs/program.hpp | 11 +++++++---- src/mbgl/programs/segment.hpp | 9 ++++++++- src/mbgl/programs/symbol_program.hpp | 11 +++++++---- src/mbgl/renderer/painter.cpp | 15 +++++++++++---- src/mbgl/renderer/painters/painter_background.cpp | 6 ++++-- src/mbgl/renderer/painters/painter_circle.cpp | 3 ++- src/mbgl/renderer/painters/painter_clipping.cpp | 3 ++- src/mbgl/renderer/painters/painter_debug.cpp | 6 ++++-- src/mbgl/renderer/painters/painter_fill.cpp | 6 ++++-- src/mbgl/renderer/painters/painter_fill_extrusion.cpp | 6 ++++-- src/mbgl/renderer/painters/painter_line.cpp | 3 ++- src/mbgl/renderer/painters/painter_raster.cpp | 3 ++- src/mbgl/renderer/painters/painter_symbol.cpp | 6 ++++-- 13 files changed, 61 insertions(+), 27 deletions(-) diff --git a/src/mbgl/programs/program.hpp b/src/mbgl/programs/program.hpp index 0199752b06..71d7569f53 100644 --- a/src/mbgl/programs/program.hpp +++ b/src/mbgl/programs/program.hpp @@ -58,7 +58,8 @@ public: const SegmentVector& segments, const PaintPropertyBinders& paintPropertyBinders, const typename PaintProperties::PossiblyEvaluated& currentProperties, - float currentZoom) { + float currentZoom, + const std::string& layerID) { typename AllUniforms::Values allUniformValues = uniformValues .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)); @@ -66,8 +67,10 @@ public: .concat(paintPropertyBinders.attributeBindings(currentProperties)); for (auto& segment : segments) { - if (!segment.vertexArray) { - segment.vertexArray = context.createVertexArray(); + optional& vertexArray = segment.vertexArrays[layerID]; + + if (!vertexArray) { + vertexArray = context.createVertexArray(); } program.draw( @@ -77,7 +80,7 @@ public: std::move(stencilMode), std::move(colorMode), allUniformValues, - *segment.vertexArray, + *vertexArray, Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset), indexBuffer, segment.indexOffset, diff --git a/src/mbgl/programs/segment.hpp b/src/mbgl/programs/segment.hpp index d8cc9679d7..74bf4a75c5 100644 --- a/src/mbgl/programs/segment.hpp +++ b/src/mbgl/programs/segment.hpp @@ -28,7 +28,14 @@ public: std::size_t vertexLength; std::size_t indexLength; - mutable optional vertexArray; + // One VertexArray per layer ID. This minimizes rebinding in cases where + // several layers share buckets but have different sets of active attributes. + // This can happen: + // * when two layers have the same layout properties, but differing + // data-driven paint properties + // * when two fill layers have the same layout properties, but one + // uses fill-color and the other uses fill-pattern + mutable std::map> vertexArrays; }; template diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index 8c59cfd5a2..ee4855cf8f 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -315,7 +315,8 @@ public: const SegmentVector& segments, const PaintPropertyBinders& paintPropertyBinders, const typename PaintProperties::PossiblyEvaluated& currentProperties, - float currentZoom) { + float currentZoom, + const std::string& layerID) { typename AllUniforms::Values allUniformValues = uniformValues .concat(symbolSizeBinder.uniformValues(currentZoom)) .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)); @@ -325,8 +326,10 @@ public: .concat(paintPropertyBinders.attributeBindings(currentProperties)); for (auto& segment : segments) { - if (!segment.vertexArray) { - segment.vertexArray = context.createVertexArray(); + optional& vertexArray = segment.vertexArrays[layerID]; + + if (!vertexArray) { + vertexArray = context.createVertexArray(); } program.draw( @@ -336,7 +339,7 @@ public: std::move(stencilMode), std::move(colorMode), allUniformValues, - *segment.vertexArray, + *vertexArray, Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset), indexBuffer, segment.indexOffset, diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index 35d03e7cb4..9ab50e83b0 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -316,16 +316,23 @@ void Painter::renderPass(PaintParameters& parameters, const Properties<>::PossiblyEvaluated properties; parameters.programs.extrusionTexture.draw( - context, gl::Triangles(), gl::DepthMode::disabled(), gl::StencilMode::disabled(), + context, + gl::Triangles(), + gl::DepthMode::disabled(), + gl::StencilMode::disabled(), colorModeForRenderPass(), ExtrusionTextureProgram::UniformValues{ uniforms::u_matrix::Value{ viewportMat }, uniforms::u_world::Value{ size }, uniforms::u_image::Value{ 0 }, uniforms::u_opacity::Value{ layer.as() ->evaluated.get() } }, - extrusionTextureVertexBuffer, quadTriangleIndexBuffer, extrusionTextureSegments, - ExtrusionTextureProgram::PaintPropertyBinders{ properties, 0 }, properties, - state.getZoom()); + extrusionTextureVertexBuffer, + quadTriangleIndexBuffer, + extrusionTextureSegments, + ExtrusionTextureProgram::PaintPropertyBinders{ properties, 0 }, + properties, + state.getZoom(), + layer.getID()); } else { renderItem(parameters, item); } diff --git a/src/mbgl/renderer/painters/painter_background.cpp b/src/mbgl/renderer/painters/painter_background.cpp index 577d7d6cda..661da0cc99 100644 --- a/src/mbgl/renderer/painters/painter_background.cpp +++ b/src/mbgl/renderer/painters/painter_background.cpp @@ -54,7 +54,8 @@ void Painter::renderBackground(PaintParameters& parameters, const RenderBackgrou tileTriangleSegments, paintAttibuteData, properties, - state.getZoom() + state.getZoom(), + layer.getID() ); } } else { @@ -74,7 +75,8 @@ void Painter::renderBackground(PaintParameters& parameters, const RenderBackgrou tileTriangleSegments, paintAttibuteData, properties, - state.getZoom() + state.getZoom(), + layer.getID() ); } } diff --git a/src/mbgl/renderer/painters/painter_circle.cpp b/src/mbgl/renderer/painters/painter_circle.cpp index a077f557fc..72a17d19fb 100644 --- a/src/mbgl/renderer/painters/painter_circle.cpp +++ b/src/mbgl/renderer/painters/painter_circle.cpp @@ -52,7 +52,8 @@ void Painter::renderCircle(PaintParameters& parameters, bucket.segments, bucket.paintPropertyBinders.at(layer.getID()), properties, - state.getZoom() + state.getZoom(), + layer.getID() ); } diff --git a/src/mbgl/renderer/painters/painter_clipping.cpp b/src/mbgl/renderer/painters/painter_clipping.cpp index cad092594e..025019b5c7 100644 --- a/src/mbgl/renderer/painters/painter_clipping.cpp +++ b/src/mbgl/renderer/painters/painter_clipping.cpp @@ -30,7 +30,8 @@ void Painter::renderClippingMask(const UnwrappedTileID& tileID, const ClipID& cl tileTriangleSegments, paintAttibuteData, properties, - state.getZoom() + state.getZoom(), + "clipping" ); } diff --git a/src/mbgl/renderer/painters/painter_debug.cpp b/src/mbgl/renderer/painters/painter_debug.cpp index ee76aee54c..989bbab5e5 100644 --- a/src/mbgl/renderer/painters/painter_debug.cpp +++ b/src/mbgl/renderer/painters/painter_debug.cpp @@ -39,7 +39,8 @@ void Painter::renderTileDebug(const RenderTile& renderTile) { segments, paintAttibuteData, properties, - state.getZoom() + state.getZoom(), + "debug" ); }; @@ -100,7 +101,8 @@ void Painter::renderTileDebug(const mat4& matrix) { tileBorderSegments, paintAttibuteData, properties, - state.getZoom() + state.getZoom(), + "debug" ); } } diff --git a/src/mbgl/renderer/painters/painter_fill.cpp b/src/mbgl/renderer/painters/painter_fill.cpp index 3a0bfed454..3ca3bdf6b8 100644 --- a/src/mbgl/renderer/painters/painter_fill.cpp +++ b/src/mbgl/renderer/painters/painter_fill.cpp @@ -61,7 +61,8 @@ void Painter::renderFill(PaintParameters& parameters, segments, bucket.paintPropertyBinders.at(layer.getID()), properties, - state.getZoom() + state.getZoom(), + layer.getID() ); }; @@ -105,7 +106,8 @@ void Painter::renderFill(PaintParameters& parameters, segments, bucket.paintPropertyBinders.at(layer.getID()), properties, - state.getZoom() + state.getZoom(), + layer.getID() ); }; diff --git a/src/mbgl/renderer/painters/painter_fill_extrusion.cpp b/src/mbgl/renderer/painters/painter_fill_extrusion.cpp index 165476944b..d7310dc208 100644 --- a/src/mbgl/renderer/painters/painter_fill_extrusion.cpp +++ b/src/mbgl/renderer/painters/painter_fill_extrusion.cpp @@ -58,7 +58,8 @@ void Painter::renderFillExtrusion(PaintParameters& parameters, bucket.triangleSegments, bucket.paintPropertyBinders.at(layer.getID()), properties, - state.getZoom()); + state.getZoom(), + layer.getID()); } else { parameters.programs.fillExtrusion.get(properties).draw( @@ -79,7 +80,8 @@ void Painter::renderFillExtrusion(PaintParameters& parameters, bucket.triangleSegments, bucket.paintPropertyBinders.at(layer.getID()), properties, - state.getZoom()); + state.getZoom(), + layer.getID()); }; } diff --git a/src/mbgl/renderer/painters/painter_line.cpp b/src/mbgl/renderer/painters/painter_line.cpp index 58f4131d96..667e19283d 100644 --- a/src/mbgl/renderer/painters/painter_line.cpp +++ b/src/mbgl/renderer/painters/painter_line.cpp @@ -36,7 +36,8 @@ void Painter::renderLine(PaintParameters& parameters, bucket.segments, bucket.paintPropertyBinders.at(layer.getID()), properties, - state.getZoom() + state.getZoom(), + layer.getID() ); }; diff --git a/src/mbgl/renderer/painters/painter_raster.cpp b/src/mbgl/renderer/painters/painter_raster.cpp index 56e38ae8f4..d0ab480616 100644 --- a/src/mbgl/renderer/painters/painter_raster.cpp +++ b/src/mbgl/renderer/painters/painter_raster.cpp @@ -82,7 +82,8 @@ void Painter::renderRaster(PaintParameters& parameters, useBucketBuffers ? bucket.segments : rasterSegments, paintAttributeData, properties, - state.getZoom() + state.getZoom(), + layer.getID() ); } diff --git a/src/mbgl/renderer/painters/painter_symbol.cpp b/src/mbgl/renderer/painters/painter_symbol.cpp index 51c3967ae7..183d09fa86 100644 --- a/src/mbgl/renderer/painters/painter_symbol.cpp +++ b/src/mbgl/renderer/painters/painter_symbol.cpp @@ -59,7 +59,8 @@ void Painter::renderSymbol(PaintParameters& parameters, buffers.segments, binders, paintProperties, - state.getZoom() + state.getZoom(), + layer.getID() ); }; @@ -181,7 +182,8 @@ void Painter::renderSymbol(PaintParameters& parameters, bucket.collisionBox.segments, paintAttributeData, properties, - state.getZoom() + state.getZoom(), + layer.getID() ); } } -- cgit v1.2.1 From 01aff0127458cc334e5d4d9f45f57fc96e314574 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 10 Jul 2017 11:49:25 -0700 Subject: [core] Use a type alias for SegmentVector --- src/mbgl/programs/segment.hpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/mbgl/programs/segment.hpp b/src/mbgl/programs/segment.hpp index 74bf4a75c5..ceb6b1536c 100644 --- a/src/mbgl/programs/segment.hpp +++ b/src/mbgl/programs/segment.hpp @@ -39,9 +39,6 @@ public: }; template -class SegmentVector : public std::vector> { -public: - SegmentVector() = default; -}; +using SegmentVector = std::vector>; } // namespace mbgl -- cgit v1.2.1 From 49726cdc7592eddb2c9dc37cd7af79e668755ce1 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 10 Jul 2017 11:54:02 -0700 Subject: [core] Remove segment.cpp --- cmake/core-files.cmake | 1 - src/mbgl/programs/segment.cpp | 7 ------- 2 files changed, 8 deletions(-) delete mode 100644 src/mbgl/programs/segment.cpp diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index 4ebb2a878d..28dd25376b 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -154,7 +154,6 @@ set(MBGL_CORE_FILES src/mbgl/programs/programs.hpp src/mbgl/programs/raster_program.cpp src/mbgl/programs/raster_program.hpp - src/mbgl/programs/segment.cpp src/mbgl/programs/segment.hpp src/mbgl/programs/symbol_program.cpp src/mbgl/programs/symbol_program.hpp diff --git a/src/mbgl/programs/segment.cpp b/src/mbgl/programs/segment.cpp deleted file mode 100644 index bb09843e21..0000000000 --- a/src/mbgl/programs/segment.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include - -namespace mbgl { -namespace gl { - -} // namespace gl -} // namespace mbgl -- cgit v1.2.1 From 4c42132183f81bd9263f8513b1fa9f610035ed57 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 10 Jul 2017 12:19:23 -0700 Subject: [core] Reduce memory requirements of VertexArrays --- src/mbgl/gl/attribute.hpp | 22 ++++++++++++++-------- src/mbgl/gl/context.cpp | 5 +++-- src/mbgl/gl/types.hpp | 2 +- src/mbgl/gl/vertex_array.hpp | 17 ++++++++++++++++- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp index 1f60c8c980..fa6c2ddeab 100644 --- a/src/mbgl/gl/attribute.hpp +++ b/src/mbgl/gl/attribute.hpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace mbgl { namespace gl { @@ -30,12 +31,12 @@ template <> struct DataTypeOf : std::integral_constant::value, "vertex type must use standard layout"); + assert(attributeSize >= 1); + assert(attributeSize <= 4); + assert(Vertex::attributeOffsets[attributeIndex] <= std::numeric_limits::max()); + static_assert(sizeof(Vertex) <= std::numeric_limits::max(), "vertex too large"); return AttributeBinding { DataTypeOf::value, - attributeSize, - Vertex::attributeOffsets[attributeIndex], + static_cast(attributeSize), + static_cast(Vertex::attributeOffsets[attributeIndex]), buffer.buffer, - sizeof(Vertex), + static_cast(sizeof(Vertex)), 0, }; } static optional offsetBinding(const optional& binding, std::size_t vertexOffset) { + assert(vertexOffset <= std::numeric_limits::max()); if (binding) { AttributeBinding result = *binding; - result.vertexOffset = vertexOffset; + result.vertexOffset = static_cast(vertexOffset); return result; } else { return binding; diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index f7d210d52e..35683cff89 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -285,11 +285,12 @@ VertexArray Context::createVertexArray() { if (supportsVertexArrays()) { VertexArrayID id = 0; MBGL_CHECK_ERROR(vertexArray->genVertexArrays(1, &id)); - return { std::make_unique(UniqueVertexArray(std::move(id), { this }), *this) }; + UniqueVertexArray vao(std::move(id), { this }); + return { UniqueVertexArrayState(new VertexArrayState(std::move(vao), *this), VertexArrayStateDeleter { true })}; } else { // On GL implementations which do not support vertex arrays, attribute bindings are global state. // So return a VertexArray which shares our global state tracking and whose deleter is a no-op. - return { UniqueVertexArrayState(&globalVertexArrayState, [] (VertexArrayState*) {}) }; + return { UniqueVertexArrayState(&globalVertexArrayState, VertexArrayStateDeleter { false }) }; } } diff --git a/src/mbgl/gl/types.hpp b/src/mbgl/gl/types.hpp index 058bc226b8..452c882ac9 100644 --- a/src/mbgl/gl/types.hpp +++ b/src/mbgl/gl/types.hpp @@ -24,7 +24,7 @@ enum class ShaderType : uint32_t { Fragment = 0x8B30 }; -enum class DataType : uint32_t { +enum class DataType : uint16_t { Byte = 0x1400, UnsignedByte = 0x1401, Short = 0x1402, diff --git a/src/mbgl/gl/vertex_array.hpp b/src/mbgl/gl/vertex_array.hpp index 9ccf48d9bd..46c67017bb 100644 --- a/src/mbgl/gl/vertex_array.hpp +++ b/src/mbgl/gl/vertex_array.hpp @@ -40,7 +40,22 @@ private: } }; -using UniqueVertexArrayState = std::unique_ptr>; +class VertexArrayStateDeleter { +public: + VertexArrayStateDeleter(bool destroy_) + : destroy(destroy_) {} + + void operator()(VertexArrayState* ptr) const { + if (destroy) { + delete ptr; + } + } + +private: + bool destroy; +}; + +using UniqueVertexArrayState = std::unique_ptr; class VertexArray { public: -- cgit v1.2.1 From 2691fe165d06e0cc015b28a52815e1b024472a97 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 10 Jul 2017 12:25:03 -0700 Subject: [core] Add comments explaining typing of AttributeLocation and UniformLocation --- src/mbgl/gl/types.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/mbgl/gl/types.hpp b/src/mbgl/gl/types.hpp index 452c882ac9..da08195e58 100644 --- a/src/mbgl/gl/types.hpp +++ b/src/mbgl/gl/types.hpp @@ -15,8 +15,16 @@ using VertexArrayID = uint32_t; using FramebufferID = uint32_t; using RenderbufferID = uint32_t; +// OpenGL does not formally define a type for attribute locations, but most APIs use +// GLuint. The exception is glGetAttribLocation, which returns GLint so that -1 can +// be used as an error indicator. using AttributeLocation = uint32_t; + +// OpenGL does not formally define a type for uniform locations, but all APIs use GLint. +// The value -1 is special, typically used as a placeholder for an unused uniform and +// "silently ignored". using UniformLocation = int32_t; + using TextureUnit = uint8_t; enum class ShaderType : uint32_t { -- cgit v1.2.1 From 86ee821c6e8e6e68a984c65492523fdf94425ea7 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 10 Jul 2017 12:31:46 -0700 Subject: [core] No need for optional in map of VertexArrays --- src/mbgl/programs/program.hpp | 8 ++++---- src/mbgl/programs/segment.hpp | 3 +-- src/mbgl/programs/symbol_program.hpp | 8 ++++---- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/mbgl/programs/program.hpp b/src/mbgl/programs/program.hpp index 71d7569f53..bcdb270b9c 100644 --- a/src/mbgl/programs/program.hpp +++ b/src/mbgl/programs/program.hpp @@ -67,10 +67,10 @@ public: .concat(paintPropertyBinders.attributeBindings(currentProperties)); for (auto& segment : segments) { - optional& vertexArray = segment.vertexArrays[layerID]; + auto vertexArrayIt = segment.vertexArrays.find(layerID); - if (!vertexArray) { - vertexArray = context.createVertexArray(); + if (vertexArrayIt == segment.vertexArrays.end()) { + vertexArrayIt = segment.vertexArrays.emplace(layerID, context.createVertexArray()).first; } program.draw( @@ -80,7 +80,7 @@ public: std::move(stencilMode), std::move(colorMode), allUniformValues, - *vertexArray, + vertexArrayIt->second, Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset), indexBuffer, segment.indexOffset, diff --git a/src/mbgl/programs/segment.hpp b/src/mbgl/programs/segment.hpp index ceb6b1536c..f729683ac9 100644 --- a/src/mbgl/programs/segment.hpp +++ b/src/mbgl/programs/segment.hpp @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -35,7 +34,7 @@ public: // data-driven paint properties // * when two fill layers have the same layout properties, but one // uses fill-color and the other uses fill-pattern - mutable std::map> vertexArrays; + mutable std::map vertexArrays; }; template diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index ee4855cf8f..a7abf94f56 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -326,10 +326,10 @@ public: .concat(paintPropertyBinders.attributeBindings(currentProperties)); for (auto& segment : segments) { - optional& vertexArray = segment.vertexArrays[layerID]; + auto vertexArrayIt = segment.vertexArrays.find(layerID); - if (!vertexArray) { - vertexArray = context.createVertexArray(); + if (vertexArrayIt == segment.vertexArrays.end()) { + vertexArrayIt = segment.vertexArrays.emplace(layerID, context.createVertexArray()).first; } program.draw( @@ -339,7 +339,7 @@ public: std::move(stencilMode), std::move(colorMode), allUniformValues, - *vertexArray, + vertexArrayIt->second, Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset), indexBuffer, segment.indexOffset, -- cgit v1.2.1 From c0d6a07a8e44c69267c2df98278d54c055c06ca4 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 11 Jul 2017 14:11:59 -0700 Subject: [core] Pass correct sources to programIdentifier --- src/mbgl/gl/program.hpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp index 9d8b0a5b04..3b54ec194a 100644 --- a/src/mbgl/gl/program.hpp +++ b/src/mbgl/gl/program.hpp @@ -52,15 +52,13 @@ public: const char* name, const char* vertexSource_, const char* fragmentSource_) { + const std::string vertexSource = shaders::vertexSource(programParameters, vertexSource_); + const std::string fragmentSource = shaders::fragmentSource(programParameters, fragmentSource_); + #if MBGL_HAS_BINARY_PROGRAMS optional cachePath = programParameters.cachePath(name); if (cachePath && context.supportsProgramBinaries()) { - const std::string vertexSource = - shaders::vertexSource(programParameters, vertexSource_); - const std::string fragmentSource = - shaders::fragmentSource(programParameters, fragmentSource_); - const std::string identifier = - shaders::programIdentifier(vertexSource, fragmentSource_); + const std::string identifier = shaders::programIdentifier(vertexSource, fragmentSource); try { if (auto cachedBinaryProgram = util::readFile(*cachePath)) { @@ -94,11 +92,9 @@ public: return std::move(result); } #endif + (void)name; - return Program { - context, shaders::vertexSource(programParameters, vertexSource_), - shaders::fragmentSource(programParameters, fragmentSource_) - }; + return Program { context, vertexSource, fragmentSource }; } template -- cgit v1.2.1 From 1176eade34114834e3c36c602b949ce84c7b356b Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 11 Jul 2017 14:11:02 -0700 Subject: [android] Force previously cached program binaries to be regenerated --- src/mbgl/shaders/shaders.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mbgl/shaders/shaders.cpp b/src/mbgl/shaders/shaders.cpp index 31ff405f02..2e5a318024 100644 --- a/src/mbgl/shaders/shaders.cpp +++ b/src/mbgl/shaders/shaders.cpp @@ -22,6 +22,7 @@ std::string programIdentifier(const std::string& vertexSource, const std::string ss << std::setfill('0') << std::setw(sizeof(size_t) * 2) << std::hex; ss << std::hash()(vertexSource); ss << std::hash()(fragmentSource); + ss << "v2"; return ss.str(); } -- cgit v1.2.1 From 11952db68cebf2927fc15127712072dc0043b5e4 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 11 Jul 2017 14:22:51 -0700 Subject: Update mapbox-gl-js --- mapbox-gl-js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapbox-gl-js b/mapbox-gl-js index 83c7fc2ee7..4c1ce2d2c1 160000 --- a/mapbox-gl-js +++ b/mapbox-gl-js @@ -1 +1 @@ -Subproject commit 83c7fc2ee78522de9905c4a49cd9c4665caa22a5 +Subproject commit 4c1ce2d2c1a504a1984073672d15288f92302b4d -- cgit v1.2.1 From a5cdbb084e489751297ffdfeb98ad208cfe03054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Wed, 14 Jun 2017 21:47:01 +0200 Subject: [all] make default_styles header-only --- cmake/glfw.cmake | 1 - cmake/offline.cmake | 1 - platform/default/mbgl/util/default_styles.cpp | 18 ------------------ platform/default/mbgl/util/default_styles.hpp | 16 ++++++++-------- platform/ios/config.cmake | 1 - platform/macos/config.cmake | 1 - platform/qt/qt.cmake | 1 - 7 files changed, 8 insertions(+), 31 deletions(-) delete mode 100644 platform/default/mbgl/util/default_styles.cpp diff --git a/cmake/glfw.cmake b/cmake/glfw.cmake index b176fbb5bc..8e001abb27 100644 --- a/cmake/glfw.cmake +++ b/cmake/glfw.cmake @@ -8,7 +8,6 @@ target_sources(mbgl-glfw PRIVATE platform/glfw/settings_json.hpp PRIVATE platform/glfw/settings_json.cpp PRIVATE platform/default/mbgl/util/default_styles.hpp - PRIVATE platform/default/mbgl/util/default_styles.cpp ) # Our GL implementation is internal to mbgl-core, which causes the GL header to diff --git a/cmake/offline.cmake b/cmake/offline.cmake index 1ec3f61e36..c9a3349792 100644 --- a/cmake/offline.cmake +++ b/cmake/offline.cmake @@ -4,7 +4,6 @@ add_executable(mbgl-offline target_sources(mbgl-offline PRIVATE platform/default/mbgl/util/default_styles.hpp - PRIVATE platform/default/mbgl/util/default_styles.cpp ) target_compile_options(mbgl-offline diff --git a/platform/default/mbgl/util/default_styles.cpp b/platform/default/mbgl/util/default_styles.cpp deleted file mode 100644 index 5f4ca862fe..0000000000 --- a/platform/default/mbgl/util/default_styles.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include - -namespace mbgl { -namespace util { -namespace default_styles { - -const DefaultStyle streets = { "mapbox://styles/mapbox/streets-v10", "Streets", 10 }; -const DefaultStyle outdoors = { "mapbox://styles/mapbox/outdoors-v10", "Outdoors", 10 }; -const DefaultStyle light = { "mapbox://styles/mapbox/light-v9", "Light", 9 }; -const DefaultStyle dark = { "mapbox://styles/mapbox/dark-v9", "Dark", 9 }; -const DefaultStyle satellite = { "mapbox://styles/mapbox/satellite-v9", "Satellite", 9 }; -const DefaultStyle satelliteStreets = { "mapbox://styles/mapbox/satellite-streets-v10", "Satellite Streets", 10 }; -const DefaultStyle trafficDay = { "mapbox://styles/mapbox/traffic-day-v2", "Traffic Day", 2 }; -const DefaultStyle trafficNight = { "mapbox://styles/mapbox/traffic-night-v2", "Traffic Night", 2 }; - -} // namespace default_styles -} // end namespace util -} // end namespace mbgl diff --git a/platform/default/mbgl/util/default_styles.hpp b/platform/default/mbgl/util/default_styles.hpp index 466102d623..43dafb8083 100644 --- a/platform/default/mbgl/util/default_styles.hpp +++ b/platform/default/mbgl/util/default_styles.hpp @@ -13,14 +13,14 @@ struct DefaultStyle { const unsigned currentVersion; }; -extern const DefaultStyle streets; -extern const DefaultStyle outdoors; -extern const DefaultStyle light; -extern const DefaultStyle dark; -extern const DefaultStyle satellite; -extern const DefaultStyle satelliteStreets; -extern const DefaultStyle trafficDay; -extern const DefaultStyle trafficNight; +constexpr const DefaultStyle streets = { "mapbox://styles/mapbox/streets-v10", "Streets", 10 }; +constexpr const DefaultStyle outdoors = { "mapbox://styles/mapbox/outdoors-v10", "Outdoors", 10 }; +constexpr const DefaultStyle light = { "mapbox://styles/mapbox/light-v9", "Light", 9 }; +constexpr const DefaultStyle dark = { "mapbox://styles/mapbox/dark-v9", "Dark", 9 }; +constexpr const DefaultStyle satellite = { "mapbox://styles/mapbox/satellite-v9", "Satellite", 9 }; +constexpr const DefaultStyle satelliteStreets = { "mapbox://styles/mapbox/satellite-streets-v10", "Satellite Streets", 10 }; +constexpr const DefaultStyle trafficDay = { "mapbox://styles/mapbox/traffic-day-v2", "Traffic Day", 2 }; +constexpr const DefaultStyle trafficNight = { "mapbox://styles/mapbox/traffic-night-v2", "Traffic Night", 2 }; const DefaultStyle orderedStyles[] = { streets, outdoors, light, dark, satellite, satelliteStreets, diff --git a/platform/ios/config.cmake b/platform/ios/config.cmake index 30cfad5d4b..dbf6780c04 100644 --- a/platform/ios/config.cmake +++ b/platform/ios/config.cmake @@ -23,7 +23,6 @@ macro(mbgl_platform_core) # Default styles PRIVATE platform/default/mbgl/util/default_styles.hpp - PRIVATE platform/default/mbgl/util/default_styles.cpp # Offline PRIVATE platform/default/mbgl/storage/offline.cpp diff --git a/platform/macos/config.cmake b/platform/macos/config.cmake index de17dfb067..742fce2517 100644 --- a/platform/macos/config.cmake +++ b/platform/macos/config.cmake @@ -19,7 +19,6 @@ macro(mbgl_platform_core) # Default styles PRIVATE platform/default/mbgl/util/default_styles.hpp - PRIVATE platform/default/mbgl/util/default_styles.cpp # Offline PRIVATE platform/default/mbgl/storage/offline.cpp diff --git a/platform/qt/qt.cmake b/platform/qt/qt.cmake index 5133d517d4..c8567bc2f3 100644 --- a/platform/qt/qt.cmake +++ b/platform/qt/qt.cmake @@ -68,7 +68,6 @@ add_library(qmapboxgl SHARED platform/qt/src/qmapboxgl.cpp platform/qt/src/qmapboxgl_p.hpp platform/default/mbgl/util/default_styles.hpp - platform/default/mbgl/util/default_styles.cpp ) # C++ app -- cgit v1.2.1 From 73869d12dd2e651b09a158a3cbd6100801b5c397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Thu, 5 Jan 2017 14:37:29 +0100 Subject: [build] enable -fvisibility=hidden for iOS --- Makefile | 2 +- platform/ios/config.cmake | 1 + platform/ios/ios.xcodeproj/project.pbxproj | 8 ++++++++ platform/ios/src/MGLAnnotationImage.h | 3 +++ platform/ios/src/MGLAnnotationView.h | 3 +++ platform/ios/src/MGLMapView.h | 9 +++++---- platform/ios/src/MGLUserLocation.h | 2 ++ platform/ios/src/MGLUserLocationAnnotationView.h | 2 ++ 8 files changed, 25 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 789825903a..46fbb9f464 100644 --- a/Makefile +++ b/Makefile @@ -260,7 +260,7 @@ darwin-update-examples: .PHONY: check-public-symbols check-public-symbols: - node platform/darwin/scripts/check-public-symbols.js macOS + node platform/darwin/scripts/check-public-symbols.js macOS iOS endif #### Linux targets ##################################################### diff --git a/platform/ios/config.cmake b/platform/ios/config.cmake index dbf6780c04..efb31d2e00 100644 --- a/platform/ios/config.cmake +++ b/platform/ios/config.cmake @@ -70,6 +70,7 @@ macro(mbgl_platform_core) target_compile_options(mbgl-core PRIVATE -fobjc-arc + PRIVATE -fvisibility=hidden ) # TODO: Remove this by converting to ARC diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index 37d87fa797..0197fba173 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -191,6 +191,7 @@ 40F887701D7A1E58008ECB67 /* MGLShapeSource_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 40F8876F1D7A1DB8008ECB67 /* MGLShapeSource_Private.h */; }; 40F887711D7A1E59008ECB67 /* MGLShapeSource_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 40F8876F1D7A1DB8008ECB67 /* MGLShapeSource_Private.h */; }; 40FDA76B1CCAAA6800442548 /* MBXAnnotationView.m in Sources */ = {isa = PBXBuildFile; fileRef = 40FDA76A1CCAAA6800442548 /* MBXAnnotationView.m */; }; + 5549A0381EF1D86B00073113 /* libmbgl-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5549A0371EF1D86B00073113 /* libmbgl-core.a */; }; 5549A0391EF2877100073113 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 554180411D2E97DE00012372 /* OpenGLES.framework */; }; 5549A03A1EF2877500073113 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 554180411D2E97DE00012372 /* OpenGLES.framework */; }; 556660CA1E1BF3A900E2C41B /* MGLFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = 556660C91E1BF3A900E2C41B /* MGLFoundation.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -666,6 +667,7 @@ 40FDA7691CCAAA6800442548 /* MBXAnnotationView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBXAnnotationView.h; sourceTree = ""; }; 40FDA76A1CCAAA6800442548 /* MBXAnnotationView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBXAnnotationView.m; sourceTree = ""; }; 554180411D2E97DE00012372 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + 5549A0371EF1D86B00073113 /* libmbgl-core.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libmbgl-core.a"; path = "../../build/ios/Debug-iphonesimulator/libmbgl-core.a"; sourceTree = ""; }; 556660C91E1BF3A900E2C41B /* MGLFoundation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLFoundation.h; sourceTree = ""; }; 556660D71E1D085500E2C41B /* MGLVersionNumber.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = MGLVersionNumber.m; path = ../../darwin/test/MGLVersionNumber.m; sourceTree = ""; }; 558DE79E1E5615E400C7916D /* MGLFoundation_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLFoundation_Private.h; sourceTree = ""; }; @@ -956,6 +958,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 5549A0381EF1D86B00073113 /* libmbgl-core.a in Frameworks */, DA2E88561CC036F400F24E7B /* Mapbox.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1234,6 +1237,7 @@ DA1DC9921CB6DF24006E619F /* Frameworks */ = { isa = PBXGroup; children = ( + 5549A0371EF1D86B00073113 /* libmbgl-core.a */, 36F1153B1D46080700878E1A /* libmbgl-core.a */, 36F1153C1D46080700878E1A /* libmbgl-platform-ios.a */, 554180411D2E97DE00012372 /* OpenGLES.framework */, @@ -2754,6 +2758,7 @@ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + OTHER_CFLAGS = "-fvisibility=hidden"; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "$(sqlite_cflags)", @@ -2788,6 +2793,7 @@ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + OTHER_CFLAGS = "-fvisibility=hidden"; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "$(sqlite_cflags)", @@ -2835,6 +2841,7 @@ buildSettings = { BITCODE_GENERATION_MODE = bitcode; HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; + OTHER_CFLAGS = "-fvisibility=hidden"; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "$(sqlite_cflags)", @@ -2861,6 +2868,7 @@ buildSettings = { BITCODE_GENERATION_MODE = bitcode; HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; + OTHER_CFLAGS = "-fvisibility=hidden"; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "$(sqlite_cflags)", diff --git a/platform/ios/src/MGLAnnotationImage.h b/platform/ios/src/MGLAnnotationImage.h index fbeee18624..0b5a111841 100644 --- a/platform/ios/src/MGLAnnotationImage.h +++ b/platform/ios/src/MGLAnnotationImage.h @@ -1,5 +1,7 @@ #import +#import "MGLFoundation.h" + NS_ASSUME_NONNULL_BEGIN /** @@ -8,6 +10,7 @@ NS_ASSUME_NONNULL_BEGIN objects and may be recycled later and put into a reuse queue that is maintained by the map view. */ +MGL_EXPORT @interface MGLAnnotationImage : NSObject #pragma mark Initializing and Preparing the Image Object diff --git a/platform/ios/src/MGLAnnotationView.h b/platform/ios/src/MGLAnnotationView.h index 2802d31b05..4fa0f196ab 100644 --- a/platform/ios/src/MGLAnnotationView.h +++ b/platform/ios/src/MGLAnnotationView.h @@ -1,5 +1,7 @@ #import +#import "MGLFoundation.h" + NS_ASSUME_NONNULL_BEGIN @protocol MGLAnnotation; @@ -50,6 +52,7 @@ typedef NS_ENUM(NSUInteger, MGLAnnotationViewDragState) { interactivity such as dragging, you can use an `MGLAnnotationImage` instead to conserve memory and optimize drawing performance. */ +MGL_EXPORT @interface MGLAnnotationView : UIView #pragma mark Initializing and Preparing the View diff --git a/platform/ios/src/MGLMapView.h b/platform/ios/src/MGLMapView.h index ca765a046b..7a1d200e44 100644 --- a/platform/ios/src/MGLMapView.h +++ b/platform/ios/src/MGLMapView.h @@ -4,6 +4,7 @@ #import #import +#import "MGLFoundation.h" #import "MGLTypes.h" NS_ASSUME_NONNULL_BEGIN @@ -23,13 +24,13 @@ NS_ASSUME_NONNULL_BEGIN @protocol MGLFeature; /** The default deceleration rate for a map view. */ -extern const CGFloat MGLMapViewDecelerationRateNormal; +extern MGL_EXPORT const CGFloat MGLMapViewDecelerationRateNormal; /** A fast deceleration rate for a map view. */ -extern const CGFloat MGLMapViewDecelerationRateFast; +extern MGL_EXPORT const CGFloat MGLMapViewDecelerationRateFast; /** Disables deceleration in a map view. */ -extern const CGFloat MGLMapViewDecelerationRateImmediate; +extern MGL_EXPORT const CGFloat MGLMapViewDecelerationRateImmediate; /** The vertical alignment of an annotation within a map view. Used with @@ -125,7 +126,7 @@ typedef NS_ENUM(NSUInteger, MGLUserTrackingMode) { ensuring that your use adheres to the relevant terms of use. */ -IB_DESIGNABLE +MGL_EXPORT IB_DESIGNABLE @interface MGLMapView : UIView #pragma mark Creating Instances diff --git a/platform/ios/src/MGLUserLocation.h b/platform/ios/src/MGLUserLocation.h index 30bfc592ca..8c6fe46136 100644 --- a/platform/ios/src/MGLUserLocation.h +++ b/platform/ios/src/MGLUserLocation.h @@ -1,6 +1,7 @@ #import #import +#import "MGLFoundation.h" #import "MGLAnnotation.h" NS_ASSUME_NONNULL_BEGIN @@ -11,6 +12,7 @@ NS_ASSUME_NONNULL_BEGIN directly. Instead, you retrieve an existing `MGLUserLocation` object from the `userLocation` property of the map view displayed in your application. */ +MGL_EXPORT @interface MGLUserLocation : NSObject #pragma mark Determining the User’s Position diff --git a/platform/ios/src/MGLUserLocationAnnotationView.h b/platform/ios/src/MGLUserLocationAnnotationView.h index 4b36236b8d..4d95f39cf3 100644 --- a/platform/ios/src/MGLUserLocationAnnotationView.h +++ b/platform/ios/src/MGLUserLocationAnnotationView.h @@ -1,6 +1,7 @@ #import #import +#import "MGLFoundation.h" #import "MGLAnnotationView.h" NS_ASSUME_NONNULL_BEGIN @@ -9,6 +10,7 @@ NS_ASSUME_NONNULL_BEGIN @class MGLUserLocation; /** View representing an `MGLUserLocation` on screen. */ +MGL_EXPORT @interface MGLUserLocationAnnotationView : MGLAnnotationView /** -- cgit v1.2.1 From c966c0e12f828e0e442b8a360314bd69627a228d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Tue, 20 Jun 2017 18:04:10 -0700 Subject: [ios] Update SMCalloutView to fix iOS 10 build warnings Reapplied 76a2a2db28ce70d06b64b747cfc59ed493eefc67, which was partially rolled back in f6e79d70735361438655f279c8699a786d25458c. --- platform/ios/vendor/SMCalloutView | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/ios/vendor/SMCalloutView b/platform/ios/vendor/SMCalloutView index 2aede5d8d1..d6ecaba377 160000 --- a/platform/ios/vendor/SMCalloutView +++ b/platform/ios/vendor/SMCalloutView @@ -1 +1 @@ -Subproject commit 2aede5d8d1577101bf18405246220e7a710df607 +Subproject commit d6ecaba377c9f963aef630faf86e3b8f8cdb88d1 -- cgit v1.2.1 From 3fce13349ccdcc1af0efd333020949c355376282 Mon Sep 17 00:00:00 2001 From: Jason Wray Date: Mon, 10 Jul 2017 17:32:43 -0400 Subject: [darwin] Include polylabel via cmake --- platform/ios/config.cmake | 1 + platform/ios/ios.xcodeproj/project.pbxproj | 30 ++++++-------------------- platform/macos/config.cmake | 1 + platform/macos/macos.xcodeproj/project.pbxproj | 20 ++++------------- scripts/config.xcconfig.in | 1 - 5 files changed, 12 insertions(+), 41 deletions(-) diff --git a/platform/ios/config.cmake b/platform/ios/config.cmake index fdb286a6d1..e9c56f2454 100644 --- a/platform/ios/config.cmake +++ b/platform/ios/config.cmake @@ -65,6 +65,7 @@ macro(mbgl_platform_core) ) target_add_mason_package(mbgl-core PUBLIC geojson) + target_add_mason_package(mbgl-core PUBLIC polylabel) target_add_mason_package(mbgl-core PRIVATE icu) target_compile_options(mbgl-core diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index ab110bca5c..82e385bbbc 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -2676,10 +2676,7 @@ baseConfigurationReference = 55D8C9941D0F133500F42F10 /* config.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; INFOPLIST_FILE = test/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -2703,10 +2700,7 @@ baseConfigurationReference = 55D8C9941D0F133500F42F10 /* config.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; INFOPLIST_FILE = test/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -2734,10 +2728,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; INFOPLIST_FILE = framework/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; @@ -2771,10 +2762,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; INFOPLIST_FILE = framework/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; @@ -2825,10 +2813,7 @@ baseConfigurationReference = 55D8C9941D0F133500F42F10 /* config.xcconfig */; buildSettings = { BITCODE_GENERATION_MODE = bitcode; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "$(sqlite_cflags)", @@ -2854,10 +2839,7 @@ baseConfigurationReference = 55D8C9941D0F133500F42F10 /* config.xcconfig */; buildSettings = { BITCODE_GENERATION_MODE = bitcode; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "$(sqlite_cflags)", diff --git a/platform/macos/config.cmake b/platform/macos/config.cmake index 8dc3c38245..c6ccdf8caf 100644 --- a/platform/macos/config.cmake +++ b/platform/macos/config.cmake @@ -61,6 +61,7 @@ macro(mbgl_platform_core) ) target_add_mason_package(mbgl-core PUBLIC geojson) + target_add_mason_package(mbgl-core PUBLIC polylabel) target_add_mason_package(mbgl-core PRIVATE icu) target_compile_options(mbgl-core diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj index 564d81afb2..1127524098 100644 --- a/platform/macos/macos.xcodeproj/project.pbxproj +++ b/platform/macos/macos.xcodeproj/project.pbxproj @@ -1779,10 +1779,7 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_VERSION = A; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; INFOPLIST_FILE = "$(SRCROOT)/sdk/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; @@ -1816,10 +1813,7 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_VERSION = A; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; INFOPLIST_FILE = "$(SRCROOT)/sdk/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; @@ -1843,10 +1837,7 @@ buildSettings = { CLANG_ENABLE_MODULES = YES; COMBINE_HIDPI_IMAGES = YES; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; INFOPLIST_FILE = test/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; LIBRARY_SEARCH_PATHS = ( @@ -1875,10 +1866,7 @@ buildSettings = { CLANG_ENABLE_MODULES = YES; COMBINE_HIDPI_IMAGES = YES; - HEADER_SEARCH_PATHS = ( - "$(mbgl_core_INCLUDE_DIRECTORIES)", - "$(polylabel_INCLUDE_DIRECTORIES)", - ); + HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; INFOPLIST_FILE = test/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; OTHER_CFLAGS = "-fvisibility=hidden"; diff --git a/scripts/config.xcconfig.in b/scripts/config.xcconfig.in index b70ff9d677..eb6bc71b89 100644 --- a/scripts/config.xcconfig.in +++ b/scripts/config.xcconfig.in @@ -3,4 +3,3 @@ // mbgl-core mbgl_core_INCLUDE_DIRECTORIES = "@mbgl_core_INCLUDE_DIRECTORIES@" mbgl_core_LINK_LIBRARIES = "@mbgl_core_LINK_LIBRARIES@" -polylabel_INCLUDE_DIRECTORIES = "@MASON_PACKAGE_polylabel_INCLUDE_DIRS@" -- cgit v1.2.1 From 629922f5570abc46011db092d204c2e7642812c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Thu, 5 Jan 2017 14:37:29 +0100 Subject: [build] enable -fvisibility=hidden for iOS --- Makefile | 2 +- platform/ios/config.cmake | 1 + platform/ios/ios.xcodeproj/project.pbxproj | 8 ++++++++ platform/ios/src/MGLAnnotationImage.h | 3 +++ platform/ios/src/MGLAnnotationView.h | 3 +++ platform/ios/src/MGLMapView.h | 9 +++++---- platform/ios/src/MGLUserLocation.h | 2 ++ platform/ios/src/MGLUserLocationAnnotationView.h | 2 ++ 8 files changed, 25 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 1a635cdd3c..b09d1a9ba3 100644 --- a/Makefile +++ b/Makefile @@ -273,7 +273,7 @@ darwin-update-examples: .PHONY: check-public-symbols check-public-symbols: - node platform/darwin/scripts/check-public-symbols.js macOS + node platform/darwin/scripts/check-public-symbols.js macOS iOS endif #### Linux targets ##################################################### diff --git a/platform/ios/config.cmake b/platform/ios/config.cmake index e9c56f2454..0adacddd35 100644 --- a/platform/ios/config.cmake +++ b/platform/ios/config.cmake @@ -70,6 +70,7 @@ macro(mbgl_platform_core) target_compile_options(mbgl-core PRIVATE -fobjc-arc + PRIVATE -fvisibility=hidden ) # TODO: Remove this by converting to ARC diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index 82e385bbbc..7c6f1115c5 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -186,6 +186,7 @@ 40F887701D7A1E58008ECB67 /* MGLShapeSource_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 40F8876F1D7A1DB8008ECB67 /* MGLShapeSource_Private.h */; }; 40F887711D7A1E59008ECB67 /* MGLShapeSource_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 40F8876F1D7A1DB8008ECB67 /* MGLShapeSource_Private.h */; }; 40FDA76B1CCAAA6800442548 /* MBXAnnotationView.m in Sources */ = {isa = PBXBuildFile; fileRef = 40FDA76A1CCAAA6800442548 /* MBXAnnotationView.m */; }; + 5549A0381EF1D86B00073113 /* libmbgl-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5549A0371EF1D86B00073113 /* libmbgl-core.a */; }; 556660CA1E1BF3A900E2C41B /* MGLFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = 556660C91E1BF3A900E2C41B /* MGLFoundation.h */; settings = {ATTRIBUTES = (Public, ); }; }; 556660D81E1D085500E2C41B /* MGLVersionNumber.m in Sources */ = {isa = PBXBuildFile; fileRef = 556660D71E1D085500E2C41B /* MGLVersionNumber.m */; }; 556660DB1E1D8E8D00E2C41B /* MGLFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = 556660C91E1BF3A900E2C41B /* MGLFoundation.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -656,6 +657,7 @@ 40FDA7691CCAAA6800442548 /* MBXAnnotationView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBXAnnotationView.h; sourceTree = ""; }; 40FDA76A1CCAAA6800442548 /* MBXAnnotationView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBXAnnotationView.m; sourceTree = ""; }; 554180411D2E97DE00012372 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + 5549A0371EF1D86B00073113 /* libmbgl-core.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libmbgl-core.a"; path = "../../build/ios/Debug-iphonesimulator/libmbgl-core.a"; sourceTree = ""; }; 556660C91E1BF3A900E2C41B /* MGLFoundation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLFoundation.h; sourceTree = ""; }; 556660D71E1D085500E2C41B /* MGLVersionNumber.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = MGLVersionNumber.m; path = ../../darwin/test/MGLVersionNumber.m; sourceTree = ""; }; 558DE79E1E5615E400C7916D /* MGLFoundation_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLFoundation_Private.h; sourceTree = ""; }; @@ -945,6 +947,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 5549A0381EF1D86B00073113 /* libmbgl-core.a in Frameworks */, DA2E88561CC036F400F24E7B /* Mapbox.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1219,6 +1222,7 @@ DA1DC9921CB6DF24006E619F /* Frameworks */ = { isa = PBXGroup; children = ( + 5549A0371EF1D86B00073113 /* libmbgl-core.a */, 36F1153B1D46080700878E1A /* libmbgl-core.a */, 36F1153C1D46080700878E1A /* libmbgl-platform-ios.a */, 554180411D2E97DE00012372 /* OpenGLES.framework */, @@ -2733,6 +2737,7 @@ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + OTHER_CFLAGS = "-fvisibility=hidden"; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "$(sqlite_cflags)", @@ -2767,6 +2772,7 @@ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + OTHER_CFLAGS = "-fvisibility=hidden"; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "$(sqlite_cflags)", @@ -2814,6 +2820,7 @@ buildSettings = { BITCODE_GENERATION_MODE = bitcode; HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; + OTHER_CFLAGS = "-fvisibility=hidden"; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "$(sqlite_cflags)", @@ -2840,6 +2847,7 @@ buildSettings = { BITCODE_GENERATION_MODE = bitcode; HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)"; + OTHER_CFLAGS = "-fvisibility=hidden"; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "$(sqlite_cflags)", diff --git a/platform/ios/src/MGLAnnotationImage.h b/platform/ios/src/MGLAnnotationImage.h index fbeee18624..0b5a111841 100644 --- a/platform/ios/src/MGLAnnotationImage.h +++ b/platform/ios/src/MGLAnnotationImage.h @@ -1,5 +1,7 @@ #import +#import "MGLFoundation.h" + NS_ASSUME_NONNULL_BEGIN /** @@ -8,6 +10,7 @@ NS_ASSUME_NONNULL_BEGIN objects and may be recycled later and put into a reuse queue that is maintained by the map view. */ +MGL_EXPORT @interface MGLAnnotationImage : NSObject #pragma mark Initializing and Preparing the Image Object diff --git a/platform/ios/src/MGLAnnotationView.h b/platform/ios/src/MGLAnnotationView.h index 2802d31b05..4fa0f196ab 100644 --- a/platform/ios/src/MGLAnnotationView.h +++ b/platform/ios/src/MGLAnnotationView.h @@ -1,5 +1,7 @@ #import +#import "MGLFoundation.h" + NS_ASSUME_NONNULL_BEGIN @protocol MGLAnnotation; @@ -50,6 +52,7 @@ typedef NS_ENUM(NSUInteger, MGLAnnotationViewDragState) { interactivity such as dragging, you can use an `MGLAnnotationImage` instead to conserve memory and optimize drawing performance. */ +MGL_EXPORT @interface MGLAnnotationView : UIView #pragma mark Initializing and Preparing the View diff --git a/platform/ios/src/MGLMapView.h b/platform/ios/src/MGLMapView.h index 31320ac977..a93b8e8511 100644 --- a/platform/ios/src/MGLMapView.h +++ b/platform/ios/src/MGLMapView.h @@ -4,6 +4,7 @@ #import #import +#import "MGLFoundation.h" #import "MGLTypes.h" NS_ASSUME_NONNULL_BEGIN @@ -23,13 +24,13 @@ NS_ASSUME_NONNULL_BEGIN @protocol MGLFeature; /** The default deceleration rate for a map view. */ -extern const CGFloat MGLMapViewDecelerationRateNormal; +extern MGL_EXPORT const CGFloat MGLMapViewDecelerationRateNormal; /** A fast deceleration rate for a map view. */ -extern const CGFloat MGLMapViewDecelerationRateFast; +extern MGL_EXPORT const CGFloat MGLMapViewDecelerationRateFast; /** Disables deceleration in a map view. */ -extern const CGFloat MGLMapViewDecelerationRateImmediate; +extern MGL_EXPORT const CGFloat MGLMapViewDecelerationRateImmediate; /** The vertical alignment of an annotation within a map view. Used with @@ -125,7 +126,7 @@ typedef NS_ENUM(NSUInteger, MGLUserTrackingMode) { ensuring that your use adheres to the relevant terms of use. */ -IB_DESIGNABLE +MGL_EXPORT IB_DESIGNABLE @interface MGLMapView : UIView #pragma mark Creating Instances diff --git a/platform/ios/src/MGLUserLocation.h b/platform/ios/src/MGLUserLocation.h index 30bfc592ca..8c6fe46136 100644 --- a/platform/ios/src/MGLUserLocation.h +++ b/platform/ios/src/MGLUserLocation.h @@ -1,6 +1,7 @@ #import #import +#import "MGLFoundation.h" #import "MGLAnnotation.h" NS_ASSUME_NONNULL_BEGIN @@ -11,6 +12,7 @@ NS_ASSUME_NONNULL_BEGIN directly. Instead, you retrieve an existing `MGLUserLocation` object from the `userLocation` property of the map view displayed in your application. */ +MGL_EXPORT @interface MGLUserLocation : NSObject #pragma mark Determining the User’s Position diff --git a/platform/ios/src/MGLUserLocationAnnotationView.h b/platform/ios/src/MGLUserLocationAnnotationView.h index 4b36236b8d..4d95f39cf3 100644 --- a/platform/ios/src/MGLUserLocationAnnotationView.h +++ b/platform/ios/src/MGLUserLocationAnnotationView.h @@ -1,6 +1,7 @@ #import #import +#import "MGLFoundation.h" #import "MGLAnnotationView.h" NS_ASSUME_NONNULL_BEGIN @@ -9,6 +10,7 @@ NS_ASSUME_NONNULL_BEGIN @class MGLUserLocation; /** View representing an `MGLUserLocation` on screen. */ +MGL_EXPORT @interface MGLUserLocationAnnotationView : MGLAnnotationView /** -- cgit v1.2.1 From f16a4e5da6609a17a29fde5295f19ca78adfeb7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Wed, 14 Jun 2017 21:47:01 +0200 Subject: [all] make default_styles header-only --- cmake/glfw.cmake | 1 - cmake/offline.cmake | 1 - platform/default/mbgl/util/default_styles.cpp | 18 ------------------ platform/default/mbgl/util/default_styles.hpp | 16 ++++++++-------- platform/ios/config.cmake | 1 - platform/macos/config.cmake | 1 - platform/qt/qt.cmake | 1 - 7 files changed, 8 insertions(+), 31 deletions(-) delete mode 100644 platform/default/mbgl/util/default_styles.cpp diff --git a/cmake/glfw.cmake b/cmake/glfw.cmake index f1ace9e6ef..c14bd6f2c2 100644 --- a/cmake/glfw.cmake +++ b/cmake/glfw.cmake @@ -8,7 +8,6 @@ target_sources(mbgl-glfw PRIVATE platform/glfw/settings_json.hpp PRIVATE platform/glfw/settings_json.cpp PRIVATE platform/default/mbgl/util/default_styles.hpp - PRIVATE platform/default/mbgl/util/default_styles.cpp ) # Our GL implementation is internal to mbgl-core, which causes the GL header to diff --git a/cmake/offline.cmake b/cmake/offline.cmake index d0124e661f..a79b22db54 100644 --- a/cmake/offline.cmake +++ b/cmake/offline.cmake @@ -4,7 +4,6 @@ add_executable(mbgl-offline target_sources(mbgl-offline PRIVATE platform/default/mbgl/util/default_styles.hpp - PRIVATE platform/default/mbgl/util/default_styles.cpp ) target_compile_options(mbgl-offline diff --git a/platform/default/mbgl/util/default_styles.cpp b/platform/default/mbgl/util/default_styles.cpp deleted file mode 100644 index 5f4ca862fe..0000000000 --- a/platform/default/mbgl/util/default_styles.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include - -namespace mbgl { -namespace util { -namespace default_styles { - -const DefaultStyle streets = { "mapbox://styles/mapbox/streets-v10", "Streets", 10 }; -const DefaultStyle outdoors = { "mapbox://styles/mapbox/outdoors-v10", "Outdoors", 10 }; -const DefaultStyle light = { "mapbox://styles/mapbox/light-v9", "Light", 9 }; -const DefaultStyle dark = { "mapbox://styles/mapbox/dark-v9", "Dark", 9 }; -const DefaultStyle satellite = { "mapbox://styles/mapbox/satellite-v9", "Satellite", 9 }; -const DefaultStyle satelliteStreets = { "mapbox://styles/mapbox/satellite-streets-v10", "Satellite Streets", 10 }; -const DefaultStyle trafficDay = { "mapbox://styles/mapbox/traffic-day-v2", "Traffic Day", 2 }; -const DefaultStyle trafficNight = { "mapbox://styles/mapbox/traffic-night-v2", "Traffic Night", 2 }; - -} // namespace default_styles -} // end namespace util -} // end namespace mbgl diff --git a/platform/default/mbgl/util/default_styles.hpp b/platform/default/mbgl/util/default_styles.hpp index 466102d623..43dafb8083 100644 --- a/platform/default/mbgl/util/default_styles.hpp +++ b/platform/default/mbgl/util/default_styles.hpp @@ -13,14 +13,14 @@ struct DefaultStyle { const unsigned currentVersion; }; -extern const DefaultStyle streets; -extern const DefaultStyle outdoors; -extern const DefaultStyle light; -extern const DefaultStyle dark; -extern const DefaultStyle satellite; -extern const DefaultStyle satelliteStreets; -extern const DefaultStyle trafficDay; -extern const DefaultStyle trafficNight; +constexpr const DefaultStyle streets = { "mapbox://styles/mapbox/streets-v10", "Streets", 10 }; +constexpr const DefaultStyle outdoors = { "mapbox://styles/mapbox/outdoors-v10", "Outdoors", 10 }; +constexpr const DefaultStyle light = { "mapbox://styles/mapbox/light-v9", "Light", 9 }; +constexpr const DefaultStyle dark = { "mapbox://styles/mapbox/dark-v9", "Dark", 9 }; +constexpr const DefaultStyle satellite = { "mapbox://styles/mapbox/satellite-v9", "Satellite", 9 }; +constexpr const DefaultStyle satelliteStreets = { "mapbox://styles/mapbox/satellite-streets-v10", "Satellite Streets", 10 }; +constexpr const DefaultStyle trafficDay = { "mapbox://styles/mapbox/traffic-day-v2", "Traffic Day", 2 }; +constexpr const DefaultStyle trafficNight = { "mapbox://styles/mapbox/traffic-night-v2", "Traffic Night", 2 }; const DefaultStyle orderedStyles[] = { streets, outdoors, light, dark, satellite, satelliteStreets, diff --git a/platform/ios/config.cmake b/platform/ios/config.cmake index 0adacddd35..836d0678cb 100644 --- a/platform/ios/config.cmake +++ b/platform/ios/config.cmake @@ -23,7 +23,6 @@ macro(mbgl_platform_core) # Default styles PRIVATE platform/default/mbgl/util/default_styles.hpp - PRIVATE platform/default/mbgl/util/default_styles.cpp # Offline PRIVATE platform/default/mbgl/storage/offline.cpp diff --git a/platform/macos/config.cmake b/platform/macos/config.cmake index c6ccdf8caf..1b8ea35814 100644 --- a/platform/macos/config.cmake +++ b/platform/macos/config.cmake @@ -19,7 +19,6 @@ macro(mbgl_platform_core) # Default styles PRIVATE platform/default/mbgl/util/default_styles.hpp - PRIVATE platform/default/mbgl/util/default_styles.cpp # Offline PRIVATE platform/default/mbgl/storage/offline.cpp diff --git a/platform/qt/qt.cmake b/platform/qt/qt.cmake index cee0d1080c..67622efca6 100644 --- a/platform/qt/qt.cmake +++ b/platform/qt/qt.cmake @@ -65,7 +65,6 @@ add_library(qmapboxgl SHARED platform/qt/src/qmapboxgl.cpp platform/qt/src/qmapboxgl_p.hpp platform/default/mbgl/util/default_styles.hpp - platform/default/mbgl/util/default_styles.cpp ) # C++ app -- cgit v1.2.1 From 76caec25c73ef3ddbf2d1673ecfe2c4d9e4f1b45 Mon Sep 17 00:00:00 2001 From: Jason Wray Date: Thu, 13 Jul 2017 01:52:55 -0400 Subject: [ios] Update changelog; kick-off 3.6.1 --- platform/ios/CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index c08952a664..93da2ff372 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -2,7 +2,11 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONTRIBUTING.md](../../CONTRIBUTING.md) to get started. -## 3.6.0 +## 3.6.1 + +* Reduced the size of the dynamic framework by optimizing symbol visibility. ([#7604](https://github.com/mapbox/mapbox-gl-native/pull/7604)) + +## 3.6.0 - June 29, 2017 ### Packaging -- cgit v1.2.1 From d0be2ed2a6876226c99591ddf1cde0f9fc85580c Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Thu, 13 Jul 2017 14:24:23 +0300 Subject: [build] Update GLFW to 2017-07-13-67c9155 --- cmake/glfw.cmake | 11 ----------- platform/linux/config.cmake | 2 +- platform/macos/config.cmake | 2 +- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/cmake/glfw.cmake b/cmake/glfw.cmake index 8e001abb27..3dca089c14 100644 --- a/cmake/glfw.cmake +++ b/cmake/glfw.cmake @@ -10,17 +10,6 @@ target_sources(mbgl-glfw PRIVATE platform/default/mbgl/util/default_styles.hpp ) -# Our GL implementation is internal to mbgl-core, which causes the GL header to -# be included after GLFW's own header. They both attempt to define GLAPIENTRY, -# but unfortunately the GL header doesn't check if it was previously defined, -# causing a macro redefinition compiler error. -# There is no particular compiler warning flag to ignore this check on GCC -# neither it does accept ignoring '-Werror' via diagnostics pragmas. We can -# only suppress this by either replacing the header path inclusion from -I to -# -isystem, or completely suppressing errors. Until the former solution is not -# available, we'll suppress the errors from that definition file. -set_source_files_properties(platform/glfw/glfw_view.cpp PROPERTIES COMPILE_FLAGS -Wno-error) - target_compile_options(mbgl-glfw PRIVATE -fvisibility-inlines-hidden ) diff --git a/platform/linux/config.cmake b/platform/linux/config.cmake index d16842c201..8fbfafb417 100644 --- a/platform/linux/config.cmake +++ b/platform/linux/config.cmake @@ -1,4 +1,4 @@ -mason_use(glfw VERSION 2017-02-09-77a8f10) +mason_use(glfw VERSION 2017-07-13-67c9155) mason_use(mesa VERSION 13.0.4) mason_use(boost_libprogram_options VERSION 1.62.0${MASON_CXXABI_SUFFIX}) mason_use(sqlite VERSION 3.14.2) diff --git a/platform/macos/config.cmake b/platform/macos/config.cmake index 742fce2517..d037469bd0 100644 --- a/platform/macos/config.cmake +++ b/platform/macos/config.cmake @@ -1,6 +1,6 @@ set(CMAKE_OSX_DEPLOYMENT_TARGET 10.10) -mason_use(glfw VERSION 2017-02-09-77a8f10) +mason_use(glfw VERSION 2017-07-13-67c9155) mason_use(boost_libprogram_options VERSION 1.62.0) mason_use(gtest VERSION 1.8.0) mason_use(benchmark VERSION 1.0.0-1) -- cgit v1.2.1 From bb1a209a6396dd5d41651092b354607b6852c0c8 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Wed, 12 Jul 2017 17:01:49 +0300 Subject: [Qt] Share the DefaultFileSource for all QMapboxGL instances Fix issues of concurrent access to the sqlite cache. Fixes #9108. --- platform/qt/src/qmapboxgl.cpp | 20 +++++++++++++++++++- platform/qt/src/qmapboxgl_p.hpp | 2 +- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/platform/qt/src/qmapboxgl.cpp b/platform/qt/src/qmapboxgl.cpp index eafc06c028..543a8bf2d6 100644 --- a/platform/qt/src/qmapboxgl.cpp +++ b/platform/qt/src/qmapboxgl.cpp @@ -70,6 +70,19 @@ namespace { QThreadStorage> loop; +std::shared_ptr sharedDefaultFileSource( + const std::string& cachePath, const std::string& assetRoot, uint64_t maximumCacheSize) { + static std::weak_ptr weak; + auto fs = weak.lock(); + + if (!fs) { + weak = fs = std::make_shared( + cachePath, assetRoot, maximumCacheSize); + } + + return fs; +} + // Conversion helper functions. mbgl::Size sanitizedSize(const QSize& size) { @@ -106,6 +119,11 @@ std::unique_ptr toStyleImage(const QString &id, const QImage QMapboxGLSettings is used to configure QMapboxGL at the moment of its creation. Once created, the QMapboxGLSettings of a QMapboxGL can no longer be changed. + Cache-related settings are shared between all QMapboxGL instances because different + maps will share the same cache database file. The first map to configure cache properties + such as size and path will force the configuration to all newly instantiated QMapboxGL + objects. + \since 4.7 */ @@ -1473,7 +1491,7 @@ QMapboxGLPrivate::QMapboxGLPrivate(QMapboxGL *q, const QMapboxGLSettings &settin : QObject(q) , size(size_) , q_ptr(q) - , fileSourceObj(std::make_unique( + , fileSourceObj(sharedDefaultFileSource( settings.cacheDatabasePath().toStdString(), settings.assetPath().toStdString(), settings.cacheDatabaseMaximumSize())) diff --git a/platform/qt/src/qmapboxgl_p.hpp b/platform/qt/src/qmapboxgl_p.hpp index 49a7942cce..3c8a6cf09e 100644 --- a/platform/qt/src/qmapboxgl_p.hpp +++ b/platform/qt/src/qmapboxgl_p.hpp @@ -52,7 +52,7 @@ public: QMapboxGL *q_ptr { nullptr }; - std::unique_ptr fileSourceObj; + std::shared_ptr fileSourceObj; std::shared_ptr threadPool; std::unique_ptr mapObj; -- cgit v1.2.1 From ee32df46874f3a922574cafb692c38e24fe7ad8b Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Wed, 12 Jul 2017 17:06:20 +0300 Subject: [Qt] Fix docs warnings --- platform/qt/src/qmapbox.cpp | 2 +- platform/qt/src/qmapboxgl.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/platform/qt/src/qmapbox.cpp b/platform/qt/src/qmapbox.cpp index 751b16f9db..aad32a35dc 100644 --- a/platform/qt/src/qmapbox.cpp +++ b/platform/qt/src/qmapbox.cpp @@ -216,7 +216,7 @@ Q_DECL_EXPORT NetworkMode networkMode() Forwards the network status \a mode to Mapbox GL Native engine. - File source requests uses the available network when \a mode is set to \a + File source requests uses the available network when \a mode is set to \b Online, otherwise scoped to the local cache. */ Q_DECL_EXPORT void setNetworkMode(NetworkMode mode) diff --git a/platform/qt/src/qmapboxgl.cpp b/platform/qt/src/qmapboxgl.cpp index 543a8bf2d6..46385bc3e3 100644 --- a/platform/qt/src/qmapboxgl.cpp +++ b/platform/qt/src/qmapboxgl.cpp @@ -1027,7 +1027,7 @@ void QMapboxGL::resize(const QSize& size, const QSize& framebufferSize) } /*! - If Mapbox GL needs to rebind the default framebuffer, it will use the + If Mapbox GL needs to rebind the default \a fbo, it will use the ID supplied here. */ void QMapboxGL::setFramebufferObject(quint32 fbo) { @@ -1426,10 +1426,10 @@ void QMapboxGL::setFilter(const QString& layer, const QVariant& filter) } /*! - Renders the map using OpenGL draw calls. If \a fbo is passed, it will - make sure to bind the framebuffer object before drawing; otherwise a - valid OpenGL context is expected with an appropriate OpenGL viewport state set - for the size of the canvas. + Renders the map using OpenGL draw calls. It will make sure to bind the + framebuffer object before drawing; otherwise a valid OpenGL context is + expected with an appropriate OpenGL viewport state set for the size of + the canvas. This function should be called only after the signal needsRendering() is emitted at least once. -- cgit v1.2.1 From b0dcc25584e7d064e9311321233fe843a000467e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Fri, 23 Jun 2017 15:50:13 -0700 Subject: [build] upgrade to v4 CircleCI images that have logbt/mesa/gdb/apitrace installed --- circle.yml | 52 ++------ scripts/check-cxx11abi.sh | 4 +- scripts/circle_setup.sh | 35 ------ scripts/valgrind.sup | 296 +++------------------------------------------- 4 files changed, 33 insertions(+), 354 deletions(-) delete mode 100755 scripts/circle_setup.sh diff --git a/circle.yml b/circle.yml index 6620a44541..58e08cfc4f 100644 --- a/circle.yml +++ b/circle.yml @@ -21,7 +21,7 @@ jobs: # ------------------------------------------------------------------------------ clang-tidy: docker: - - image: mbgl/ci:r3-linux-clang-3.9 + - image: mbgl/ci:r4-linux-clang-3.9 working_directory: /src environment: LIBSYSCONFCPUS: 6 @@ -55,7 +55,7 @@ jobs: # ------------------------------------------------------------------------------ android-debug-arm-v7: docker: - - image: mbgl/ci:r3-android-ndk-r15-gradle + - image: mbgl/ci:r4-android-ndk-r15-gradle working_directory: /src environment: LIBSYSCONFCPUS: 6 @@ -131,7 +131,7 @@ jobs: # ------------------------------------------------------------------------------ android-release-all: docker: - - image: mbgl/ci:r3-android-ndk-r15-gradle + - image: mbgl/ci:r4-android-ndk-r15-gradle working_directory: /src environment: LIBSYSCONFCPUS: 6 @@ -178,7 +178,7 @@ jobs: # ------------------------------------------------------------------------------ node4-clang39-release: docker: - - image: mbgl/ci:r3-linux-clang-3.9-node-4 + - image: mbgl/ci:r4-linux-clang-3.9-node-4 working_directory: /src environment: LIBSYSCONFCPUS: 6 @@ -187,7 +187,6 @@ jobs: WITH_EGL: 1 PACKAGE_JSON_VERSION: $(node -e "console.log(require('./package.json').version)") PUBLISH: $([[ "${CIRCLE_BRANCH}" == "node-v${PACKAGE_JSON_VERSION}" ]] && echo true) - DISPLAY: :0 steps: - checkout - restore_cache: @@ -201,12 +200,8 @@ jobs: - run: name: Run node tests command: | - source scripts/circle_setup.sh - mapbox_install_logbt - mapbox_install_apitrace - mapbox_export_mesa_library_path xvfb-run --server-args="-screen 0 1024x768x24" \ - ./logbt -- apitrace trace --api=egl -v make test-node + logbt -- apitrace trace --api=egl -v make test-node - run: name: Publish node package when: on_success @@ -223,7 +218,7 @@ jobs: # ------------------------------------------------------------------------------ node6-clang39-release: docker: - - image: mbgl/ci:r3-linux-clang-3.9 + - image: mbgl/ci:r4-linux-clang-3.9 working_directory: /src environment: LIBSYSCONFCPUS: 6 @@ -232,7 +227,6 @@ jobs: WITH_EGL: 1 PACKAGE_JSON_VERSION: $(node -e "console.log(require('./package.json').version)") PUBLISH: $([[ "${CIRCLE_BRANCH}" == "node-v${PACKAGE_JSON_VERSION}" ]] && echo true) - DISPLAY: :0 steps: - checkout - restore_cache: @@ -246,12 +240,8 @@ jobs: - run: name: Run node tests command: | - source scripts/circle_setup.sh - mapbox_install_logbt - mapbox_install_apitrace - mapbox_export_mesa_library_path xvfb-run --server-args="-screen 0 1024x768x24" \ - ./logbt -- apitrace trace --api=egl -v make test-node + logbt -- apitrace trace --api=egl -v make test-node - run: name: Publish node package when: on_success @@ -268,7 +258,7 @@ jobs: # ------------------------------------------------------------------------------ node6-clang39-debug: docker: - - image: mbgl/ci:r3-linux-clang-3.9 + - image: mbgl/ci:r4-linux-clang-3.9 working_directory: /src environment: LIBSYSCONFCPUS: 6 @@ -277,7 +267,6 @@ jobs: WITH_EGL: 1 PACKAGE_JSON_VERSION: $(node -e "console.log(require('./package.json').version)") PUBLISH: $([[ "${CIRCLE_BRANCH}" == "node-v${PACKAGE_JSON_VERSION}" ]] && echo true) - DISPLAY: :0 steps: - checkout - restore_cache: @@ -291,12 +280,8 @@ jobs: - run: name: Run node tests command: | - source scripts/circle_setup.sh - mapbox_install_logbt - mapbox_install_apitrace - mapbox_export_mesa_library_path xvfb-run --server-args="-screen 0 1024x768x24" \ - ./logbt -- apitrace trace --api=egl -v make test-node + logbt -- apitrace trace --api=egl -v make test-node - run: name: Publish node package when: on_success @@ -313,14 +298,13 @@ jobs: # ------------------------------------------------------------------------------ linux-clang39-debug: docker: - - image: mbgl/ci:r3-linux-clang-3.9 + - image: mbgl/ci:r4-linux-clang-3.9 working_directory: /src environment: LIBSYSCONFCPUS: 6 JOBS: 6 BUILDTYPE: Debug WITH_EGL: 1 - DISPLAY: :0 steps: - checkout - restore_cache: @@ -340,8 +324,6 @@ jobs: - run: name: Run tests command: | - source scripts/circle_setup.sh - mapbox_export_mesa_library_path xvfb-run --server-args="-screen 0 1024x768x24" \ make run-test - save_cache: @@ -394,7 +376,7 @@ jobs: # ------------------------------------------------------------------------------ linux-gcc5-debug-coverage: docker: - - image: mbgl/ci:r3-linux-gcc-5 + - image: mbgl/ci:r4-linux-gcc-5 working_directory: /src environment: LIBSYSCONFCPUS: 6 @@ -402,7 +384,6 @@ jobs: BUILDTYPE: Debug WITH_EGL: 1 WITH_COVERAGE: 1 - DISPLAY: :0 steps: - checkout - restore_cache: @@ -422,14 +403,11 @@ jobs: - run: name: Run tests command: | - source scripts/circle_setup.sh - mapbox_export_mesa_library_path xvfb-run --server-args="-screen 0 1024x768x24" \ make run-test - run: name: Upload coverage results to coveralls command: | - source scripts/circle_setup.sh platform/linux/scripts/coveralls.sh - save_cache: key: v1-linux-gcc5-debug-coverage @@ -440,7 +418,7 @@ jobs: # ------------------------------------------------------------------------------ linux-gcc5-release-qt4: docker: - - image: mbgl/ci:r3-linux-gcc-5-qt-4 + - image: mbgl/ci:r4-linux-gcc-5-qt-4 working_directory: /src environment: LIBSYSCONFCPUS: 6 @@ -465,8 +443,6 @@ jobs: - run: name: Run memory-load tests command: | - source scripts/circle_setup.sh - mapbox_export_mesa_library_path xvfb-run --server-args="-screen 0 1024x768x24" \ make run-qt-test-Memory.*:*.Load scripts/log_memory_benchmarks.sh test_detail.xml "Platform=Linux,Compiler=${_CC},Arch=$(uname -m)" @@ -479,7 +455,7 @@ jobs: # ------------------------------------------------------------------------------ linux-gcc5-release-qt5: docker: - - image: mbgl/ci:r3-linux-gcc-5-qt-5 + - image: mbgl/ci:r4-linux-gcc-5-qt-5 working_directory: /src environment: LIBSYSCONFCPUS: 6 @@ -508,8 +484,6 @@ jobs: environment: JOBS: 1 # https://github.com/mapbox/mapbox-gl-native/issues/9108 command: | - source scripts/circle_setup.sh - mapbox_export_mesa_library_path xvfb-run --server-args="-screen 0 1024x768x24" \ scripts/valgrind.sh build/qt-linux-x86_64/Release/mbgl-test --gtest_filter=-*.Load --gtest_filter=-Memory.Vector - save_cache: diff --git a/scripts/check-cxx11abi.sh b/scripts/check-cxx11abi.sh index c543e52cb6..c6fd9258c5 100755 --- a/scripts/check-cxx11abi.sh +++ b/scripts/check-cxx11abi.sh @@ -3,7 +3,9 @@ set -e set -o pipefail -if [ ! `uname -s` = 'Linux' ]; then +if ! [ `uname -s` = 'Linux' ] || \ + ! command -v readelf > /dev/null || \ + ! command -v c++filt > /dev/null; then echo -n "OFF" exit 0 fi diff --git a/scripts/circle_setup.sh b/scripts/circle_setup.sh deleted file mode 100755 index 308cac34fb..0000000000 --- a/scripts/circle_setup.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash -# This script is sourced; do not set -e or -o pipefail here. - -# Touch package.json so that we are definitely going to run an npm update action -touch package.json - -function mapbox_install_logbt { - export PATH=$(scripts/mason.sh PREFIX gdb VERSION 7.12)/bin:${PATH} - curl -sSfL https://github.com/mapbox/logbt/archive/v2.0.1.tar.gz | tar --gunzip --extract --strip-components=2 --exclude="*md" --exclude="test*" --directory=. - ./logbt --test -} - -export -f mapbox_install_logbt - -function mapbox_install_apitrace { - export PATH=$(scripts/mason.sh PREFIX apitrace VERSION 6a30de1)/bin:${PATH} -} - -export -f mapbox_install_apitrace - -function mapbox_export_mesa_library_path { - # Install and set up to load a more recent version of mesa - MESA_PREFIX=$(scripts/mason.sh PREFIX mesa VERSION 13.0.4) - export LD_LIBRARY_PATH="${MESA_PREFIX}/lib:${LD_LIBRARY_PATH:-}" - export LIBGL_DRIVERS_PATH="${MESA_PREFIX}/lib/dri" -} - -export -f mapbox_export_mesa_library_path - -# Install and set up to load awscli -pip install --user awscli -export PATH="`python -m site --user-base`/bin:${PATH}" - -# Install coveralls gem -gem install coveralls-lcov --no-rdoc --no-ri diff --git a/scripts/valgrind.sup b/scripts/valgrind.sup index d8870536ac..f659122dc1 100644 --- a/scripts/valgrind.sup +++ b/scripts/valgrind.sup @@ -1,142 +1,19 @@ { - Graphics driver buffers - Memcheck:Leak - ... - obj:*/r600_dri.* - obj:*/r600_dri.* - obj:*/r600_dri.* - ... -} -{ - Graphics driver buffers - Memcheck:Leak - ... - obj:*/i965_dri.* - obj:*/i965_dri.* - obj:*/i965_dri.* - ... -} -{ - Graphics driver buffers - Memcheck:Leak - ... - obj:*/nouveau_dri.* - obj:*/nouveau_dri.* - obj:*/nouveau_dri.* - ... -} -{ - Ubuntu 16.04 - GLFW - Memcheck:Leak - ... - fun:glfwInit - ... -} -{ - Ubuntu 16.04 - GLFW - Memcheck:Cond - ... - fun:glfwInit - ... -} -{ - Ubuntu 16.04 - Qt + glib - Memcheck:Cond - fun:g_utf8_offset_to_pointer - ... -} -{ - Ubuntu 16.04 - Qt + glib + Graphics driver bugs Memcheck:Cond ... - fun:g_signal_emit_valist - ... - fun:*QApplicationPrivate* - ... -} -{ - Ubuntu 16.04 - Qt + X11 - Memcheck:Param - writev(vector[...]) - ... - obj:*/libxcb.* - fun:xcb_flush - ... -} -{ - Ubuntu 16.04 - Qt + X11 - Memcheck:Leak - ... - fun:_XmbTextListToTextProperty - ... - fun:*QWidget*setVisible* - ... -} -{ - Ubuntu 16.04 - Qt + Fontconfig - Memcheck:Leak - ... - obj:*/libfontconfig.* - obj:*/libfontconfig.* - ... - fun:FcFontRenderPrepare - ... -} -{ - Ubuntu 16.04 - Qt + Fontconfig - Memcheck:Leak - ... - obj:*/libfontconfig.* - obj:*/libfontconfig.* - ... - fun:FcPatternAddInteger - ... -} -{ - Ubuntu 16.04 - Qt + Fontconfig - Memcheck:Leak - ... - obj:*/libfontconfig.* - obj:*/libfontconfig.* - ... - fun:FcConfigParseAndLoad - ... -} -{ - Ubuntu 16.04 - Qt + Dbus - Memcheck:Leak - ... - fun:dbus_connection_send_with_reply - ... - fun:*QWidget* -} -{ - Ubuntu 16.04 - Qt + Dbus - Memcheck:Leak - ... - fun:px_proxy_factory_get_proxies - obj:*/libQt5Network.* -} -{ - Ubuntu 16.04 - Qt - Memcheck:Leak - ... - fun:*QGuiApplicationPrivate*createEventDispatcher* - fun:*QCoreApplication*init* - ... -} -{ - Ubuntu 16.04 - Qt - Memcheck:Leak - ... - fun:*QWidget*setWindowTitle* + obj:*/swrast_dri.* + obj:*/swrast_dri.* + obj:*/swrast_dri.* ... } { - Ubuntu 16.04 - Qt - Memcheck:Leak + Graphics driver bugs + Memcheck:Value8 ... - fun:*QNetworkConfigurationManagerPrivate*updateConfigurations* + obj:*/swrast_dri.* + obj:*/swrast_dri.* + obj:*/swrast_dri.* ... } { @@ -156,118 +33,42 @@ obj:* } { - Ubuntu 16.04 - Mysterious leak when running utests - Memcheck:Leak - fun:malloc - obj:* - obj:* - obj:* - obj:* - obj:* - obj:* - obj:* - obj:* - obj:* - obj:* - obj:* -} -{ - Ubuntu 14.04 - Travis CI bot using swrast + Qt5 Memcheck:Cond - fun:do_stencil_test - fun:_swrast_stencil_and_ztest_span - fun:_swrast_write_rgba_span - fun:draw_wide_line - ... -} -{ - Ubuntu 14.04 - Travis + Qt5 - Memcheck:Leak ... obj:*/libQt5Core.* ... } { - Ubuntu 14.04 - Travis + Qt5 - Memcheck:Cond - ... - obj:*/libQt5Core.* - ... -} -{ - Ubuntu 14.04 - Travis + Qt5 + Qt5 Memcheck:Value8 ... obj:*/libQt5Core.* ... } { - Ubuntu 14.04 - Travis + Qt5 - Memcheck:Leak - ... - obj:*/libQt5Gui.* - ... -} -{ - Ubuntu 14.04 - Travis + Qt5 + Qt5 Memcheck:Cond ... obj:*/libQt5Gui.* ... } { - Ubuntu 14.04 - Travis + Qt5 + Qt5 Memcheck:Value8 ... obj:*/libQt5Gui.* ... } { - Ubuntu 14.04 - Travis + mesa 13.0.0-glx - Memcheck:Cond - ... - obj:*/mesa/libGL.so.* - ... -} -{ - Ubuntu 14.04 - Travis + mesa 13.0.0-glx - Memcheck:Value8 - ... - obj:*/mesa/libGL.so.* - ... -} -{ - Ubuntu 14.04 - Travis + mesa 13.0.0-glx - Memcheck:Cond - ... - fun:do_rasterize_bin - ... -} -{ - Ubuntu 14.04 - Travis + mesa 13.0.0-glx - Memcheck:Value8 - ... - fun:do_rasterize_bin - ... -} -{ - Ubuntu 14.04 - Travis + mesa 13.0.0-glx + mapbox::pixelmatch Memcheck:Cond ... fun:_ZN6mapbox10pixelmatchEPKhS1_mmPhdb ... } { - Ubuntu 14.04 - Travis + mesa 13.0.0-glx - Memcheck:Param - write(buf) - ... - obj:*/libc-* - fun:_ZN4mbgl4util10write_fileERKSsS2_ - ... -} -{ - Ubuntu 16.04 - CircleCI + mesa 13.0.4 + util::write_file Memcheck:Param write(buf) ... @@ -276,73 +77,10 @@ ... } { - Ubuntu 14.04 - Travis + mesa 13.0.3 - Memcheck:Cond - fun:_ZN12_GLOBAL__N_117PeepholeOptimizer20runOnMachineFunctionERN4llvm15MachineFunctionE - fun:_ZN4llvm19MachineFunctionPass13runOnFunctionERNS_8FunctionE - fun:_ZN4llvm13FPPassManager13runOnFunctionERNS_8FunctionE - fun:_ZN4llvm13FPPassManager11runOnModuleERNS_6ModuleE - fun:_ZN4llvm6legacy15PassManagerImpl3runERNS_6ModuleE - fun:_ZN4llvm5MCJIT10emitObjectEPNS_6ModuleE - fun:_ZN4llvm5MCJIT21generateCodeForModuleEPNS_6ModuleE - fun:_ZN4llvm5MCJIT14finalizeObjectEv - fun:LLVMGetPointerToGlobal - fun:gallivm_jit_function - fun:generate_variant - fun:llvmpipe_update_fs -} -{ - Ubuntu 14.04 - Travis + mesa 13.0.3 - Memcheck:Cond - fun:_ZNK4llvm12X86InstrInfo13reMaterializeERNS_17MachineBasicBlockENS1_15bundle_iteratorINS_12MachineInstrENS_14ilist_iteratorIS4_EEEEjjPKS4_RKNS_18TargetRegisterInfoE - fun:_ZN12_GLOBAL__N_117RegisterCoalescer23reMaterializeTrivialDefERKN4llvm13CoalescerPairEPNS1_12MachineInstrERb - fun:_ZN12_GLOBAL__N_117RegisterCoalescer8joinCopyEPN4llvm12MachineInstrERb - fun:_ZN12_GLOBAL__N_117RegisterCoalescer20runOnMachineFunctionERN4llvm15MachineFunctionE - fun:_ZN4llvm19MachineFunctionPass13runOnFunctionERNS_8FunctionE - fun:_ZN4llvm13FPPassManager13runOnFunctionERNS_8FunctionE - fun:_ZN4llvm13FPPassManager11runOnModuleERNS_6ModuleE - fun:_ZN4llvm6legacy15PassManagerImpl3runERNS_6ModuleE - fun:_ZN4llvm5MCJIT10emitObjectEPNS_6ModuleE - fun:_ZN4llvm5MCJIT21generateCodeForModuleEPNS_6ModuleE - fun:_ZN4llvm5MCJIT14finalizeObjectEv - fun:LLVMGetPointerToGlobal -} -{ - Ubuntu 14.04 - Travis + mesa 13.0.3 - Memcheck:Cond - fun:_ZNK4llvm12X86InstrInfo13reMaterializeERNS_17MachineBasicBlockENS1_15bundle_iteratorINS_12MachineInstrENS_14ilist_iteratorIS4_EEEEjjPKS4_RKNS_18TargetRegisterInfoE - fun:_ZN4llvm13LiveRangeEdit15rematerializeAtERNS_17MachineBasicBlockENS1_15bundle_iteratorINS_12MachineInstrENS_14ilist_iteratorIS4_EEEEjRKNS0_5RematERKNS_18TargetRegisterInfoEb - fun:_ZN12_GLOBAL__N_113InlineSpiller5spillERN4llvm13LiveRangeEditE - fun:_ZN12_GLOBAL__N_18RAGreedy17selectOrSplitImplERN4llvm12LiveIntervalERNS1_15SmallVectorImplIjEERNS1_8SmallSetIjLj16ESt4lessIjEEEj - fun:_ZN12_GLOBAL__N_18RAGreedy13selectOrSplitERN4llvm12LiveIntervalERNS1_15SmallVectorImplIjEE - fun:_ZN4llvm12RegAllocBase16allocatePhysRegsEv - fun:_ZN12_GLOBAL__N_18RAGreedy20runOnMachineFunctionERN4llvm15MachineFunctionE - fun:_ZN4llvm19MachineFunctionPass13runOnFunctionERNS_8FunctionE - fun:_ZN4llvm13FPPassManager13runOnFunctionERNS_8FunctionE - fun:_ZN4llvm13FPPassManager11runOnModuleERNS_6ModuleE - fun:_ZN4llvm6legacy15PassManagerImpl3runERNS_6ModuleE - fun:_ZN4llvm5MCJIT10emitObjectEPNS_6ModuleE -} -{ - Ubuntu 14.04 - Travis + mesa 13.0.3 - Memcheck:Cond - fun:_ZNK4llvm12X86InstrInfo13reMaterializeERNS_17MachineBasicBlockENS1_15bundle_iteratorINS_12MachineInstrENS_14ilist_iteratorIS4_EEEEjjPKS4_RKNS_18TargetRegisterInfoE - fun:_ZN4llvm13LiveRangeEdit15rematerializeAtERNS_17MachineBasicBlockENS1_15bundle_iteratorINS_12MachineInstrENS_14ilist_iteratorIS4_EEEEjRKNS0_5RematERKNS_18TargetRegisterInfoEb - fun:_ZN4llvm11SplitEditor13defFromParentEjPNS_6VNInfoENS_9SlotIndexERNS_17MachineBasicBlockENS4_15bundle_iteratorINS_12MachineInstrENS_14ilist_iteratorIS7_EEEE - fun:_ZN4llvm11SplitEditor16splitRegOutBlockERKNS_13SplitAnalysis9BlockInfoEjNS_9SlotIndexE - fun:_ZN12_GLOBAL__N_18RAGreedy13doRegionSplitERN4llvm12LiveIntervalEjbRNS1_15SmallVectorImplIjEE - fun:_ZN12_GLOBAL__N_18RAGreedy17selectOrSplitImplERN4llvm12LiveIntervalERNS1_15SmallVectorImplIjEERNS1_8SmallSetIjLj16ESt4lessIjEEEj - fun:_ZN12_GLOBAL__N_18RAGreedy13selectOrSplitERN4llvm12LiveIntervalERNS1_15SmallVectorImplIjEE - fun:_ZN4llvm12RegAllocBase16allocatePhysRegsEv - fun:_ZN12_GLOBAL__N_18RAGreedy20runOnMachineFunctionERN4llvm15MachineFunctionE - fun:_ZN4llvm19MachineFunctionPass13runOnFunctionERNS_8FunctionE - fun:_ZN4llvm13FPPassManager13runOnFunctionERNS_8FunctionE - fun:_ZN4llvm13FPPassManager11runOnModuleERNS_6ModuleE -} -{ - Ubuntu 14.04 - Travis + mesa 13.0.3 + Qt5 ThreadStorage Memcheck:Leak match-leak-kinds: definite fun:_Znwm + fun:_Z24qThreadStorage_localDataISt5arrayIPiLm1EEERT_R18QThreadStorageDataPS3_.isra.5 ... } -- cgit v1.2.1 From 92354bdc25d7857b5142da35806a3b2e7bad2b4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Fri, 23 Jun 2017 15:51:55 -0700 Subject: [build] add address, undefined behavior + thread sanitizer --- CMakeLists.txt | 3 +- Makefile | 11 +++-- circle.yml | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0acc58004c..e0d60240cd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,7 +68,7 @@ if(WITH_COVERAGE) set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --coverage") endif(WITH_COVERAGE) -set(CMAKE_CONFIGURATION_TYPES Debug Release) +set(CMAKE_CONFIGURATION_TYPES Debug Release Sanitize) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -ftemplate-depth=1024 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Werror -Wno-variadic-macros -Wno-unknown-pragmas") if(APPLE AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") @@ -76,6 +76,7 @@ if(APPLE AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=unused-command-line-argument") endif() set(CMAKE_CXX_FLAGS_RELEASE "-Os -DNDEBUG") +set(CMAKE_CXX_FLAGS_SANITIZE "-O1 -g -fno-omit-frame-pointer -fno-optimize-sibling-calls") if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") diff --git a/Makefile b/Makefile index 46fbb9f464..b6e4b608fa 100644 --- a/Makefile +++ b/Makefile @@ -2,9 +2,10 @@ export BUILDTYPE ?= Debug export WITH_CXX11ABI ?= $(shell scripts/check-cxx11abi.sh) ifeq ($(BUILDTYPE), Release) +else ifeq ($(BUILDTYPE), Sanitize) else ifeq ($(BUILDTYPE), Debug) else - $(error BUILDTYPE must be Debug or Release) + $(error BUILDTYPE must be Debug, Sanitize or Release) endif buildtype := $(shell echo "$(BUILDTYPE)" | tr "[A-Z]" "[a-z]") @@ -297,8 +298,12 @@ benchmark: $(LINUX_BUILD) $(NINJA) $(NINJA_ARGS) -j$(JOBS) -C $(LINUX_OUTPUT_PATH) mbgl-benchmark ifneq (,$(shell command -v gdb 2> /dev/null)) - GDB = $(shell scripts/mason.sh PREFIX gdb VERSION 2017-04-08-aebcde5)/bin/gdb \ - -batch -return-child-result -ex 'set print thread-events off' -ex 'run' -ex 'thread apply all bt' --args + GDB ?= $(shell scripts/mason.sh PREFIX gdb VERSION 2017-04-08-aebcde5)/bin/gdb \ + -batch -return-child-result \ + -ex 'set print thread-events off' \ + -ex 'set disable-randomization off' \ + -ex 'run' \ + -ex 'thread apply all bt' --args endif .PHONY: run-test diff --git a/circle.yml b/circle.yml index 58e08cfc4f..99e9be5a9d 100644 --- a/circle.yml +++ b/circle.yml @@ -11,6 +11,9 @@ workflows: - node6-clang39-release - node6-clang39-debug - linux-clang39-debug + - linux-clang4-sanitize-address + - linux-clang4-sanitize-undefined + - linux-clang4-sanitize-thread - linux-gcc4.9-debug - linux-gcc5-debug-coverage - linux-gcc5-release-qt4 @@ -332,6 +335,144 @@ jobs: - node_modules - /root/.ccache + +# ------------------------------------------------------------------------------ + linux-clang4-sanitize-address: + docker: + - image: mbgl/ci:r4-linux-clang-4 + working_directory: /src + environment: + LIBSYSCONFCPUS: 6 + JOBS: 6 + BUILDTYPE: Sanitize + WITH_EGL: 1 + GDB: '' # Do not run with GDB + CXXFLAGS: -fsanitize=address + LDFLAGS: -fsanitize=address + ASAN_OPTIONS: detect_leaks=0:color=always + steps: + - checkout + - restore_cache: + key: v1-linux-clang4-sanitize-address + paths: + - node_modules + - /root/.ccache + - run: + name: Environment Setup + command: | + # LLVM has a hard check for "llvm-symbolizer" and doesn't support suffixed executables + ln -s /usr/bin/llvm-symbolizer-* /usr/bin/llvm-symbolizer + # We'll use tee to redirect stderr to a file so we can check for sanitiziation + # https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/1059947 + sed -i 's/"$@" 2>&1/"$@"/' /usr/bin/xvfb-run + - run: + name: Build test + command: make test + - run: + name: Run tests + command: | + xvfb-run --server-args="-screen 0 1024x768x24" make run-test 2> >(tee sanitizer 1>&2) + # Unfortunately, Google Test eats the status code, so we'll have to check the output. + [ -z "$(sed -n '/^SUMMARY: AddressSanitizer:/p' sanitizer)" ] + - save_cache: + key: v1-linux-clang4-sanitize-address + paths: + - node_modules + - /root/.ccache + + +# ------------------------------------------------------------------------------ + linux-clang4-sanitize-undefined: + docker: + - image: mbgl/ci:r4-linux-clang-4 + working_directory: /src + environment: + LIBSYSCONFCPUS: 6 + JOBS: 6 + BUILDTYPE: Sanitize + WITH_EGL: 1 + GDB: '' # Do not run with GDB + CXXFLAGS: -fsanitize=undefined + LDFLAGS: -fsanitize=undefined + UBSAN_OPTIONS: print_stacktrace=1:color=always + steps: + - checkout + - restore_cache: + key: v1-linux-clang4-sanitize-undefined + paths: + - node_modules + - /root/.ccache + - run: + name: Environment Setup + command: | + # LLVM has a hard check for "llvm-symbolizer" and doesn't support suffixed executables + ln -s /usr/bin/llvm-symbolizer-* /usr/bin/llvm-symbolizer + # We'll use tee to redirect stderr to a file so we can check for sanitiziation + # https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/1059947 + sed -i 's/"$@" 2>&1/"$@"/' /usr/bin/xvfb-run + - run: + name: Build test + command: make test + - run: + name: Run tests + command: | + xvfb-run --server-args="-screen 0 1024x768x24" make run-test 2> >(tee sanitizer 1>&2) + # Unfortunately, Google Test eats the status code, so we'll have to check the output. + # Uncomment this once we've fixed all thread behavior to make new thread behavior + # fail on CircleCI. + # [ -z "$(sed -n '/^SUMMARY: UndefinedBehaviorSanitizer:/p' sanitizer)" ] + - save_cache: + key: v1-linux-clang4-sanitize-address-undefined + paths: + - node_modules + - /root/.ccache + + +# ------------------------------------------------------------------------------ + linux-clang4-sanitize-thread: + docker: + - image: mbgl/ci:r4-linux-clang-4 + working_directory: /src + environment: + LIBSYSCONFCPUS: 6 + JOBS: 6 + BUILDTYPE: Sanitize + WITH_EGL: 1 + GDB: '' # Do not run with GDB + CXXFLAGS: -fsanitize=thread + LDFLAGS: -fsanitize=thread + TSAN_OPTIONS: color=always + steps: + - checkout + - restore_cache: + key: v1-linux-clang4-sanitize-thread + paths: + - node_modules + - /root/.ccache + - run: + name: Environment Setup + command: | + # LLVM has a hard check for "llvm-symbolizer" and doesn't support suffixed executables + ln -s /usr/bin/llvm-symbolizer-* /usr/bin/llvm-symbolizer + # We'll use tee to redirect stderr to a file so we can check for sanitiziation + # https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/1059947 + sed -i 's/"$@" 2>&1/"$@"/' /usr/bin/xvfb-run + - run: + name: Build test + command: make test + - run: + name: Run tests + command: | + xvfb-run --server-args="-screen 0 1024x768x24" make run-test 2> >(tee sanitizer 1>&2) + # Unfortunately, Google Test eats the status code, so we'll have to check the output. + [ -z "$(sed -n '/^SUMMARY: ThreadSanitizer:/p' sanitizer)" ] + - save_cache: + key: v1-linux-clang4-sanitize-thread + paths: + - node_modules + - /root/.ccache + + # ------------------------------------------------------------------------------ linux-gcc4.9-debug: docker: -- cgit v1.2.1 From 6ca7b28e60afdc72d888b4c96fff509568ee3bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Fri, 30 Jun 2017 12:49:47 -0700 Subject: [build] add ccache + Circle CI caching --- .gitignore | 1 + CMakeLists.txt | 30 ++- circle.yml | 543 +++++++++++++++++++++----------------------------- scripts/launch-c.in | 10 + scripts/launch-cxx.in | 10 + 5 files changed, 279 insertions(+), 315 deletions(-) create mode 100644 scripts/launch-c.in create mode 100644 scripts/launch-cxx.in diff --git a/.gitignore b/.gitignore index 653ff30c45..b6a8498460 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ xcuserdata /documentation test/fixtures/api/assets.zip test/fixtures/storage/assets.zip +/.circle-week diff --git a/CMakeLists.txt b/CMakeLists.txt index e0d60240cd..a4a6e4d8c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.4) project(mbgl LANGUAGES CXX C) set(CMAKE_CXX_STANDARD 14) @@ -86,6 +86,34 @@ elseif(CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fext-numeric-literals") endif() +# Technique from https://crascit.com/2016/04/09/using-ccache-with-cmake/ +find_program(CCACHE_PROGRAM ccache) +if(CCACHE_PROGRAM) + set(C_LAUNCHER "${CCACHE_PROGRAM}") + set(CXX_LAUNCHER "${CCACHE_PROGRAM}") + configure_file(scripts/launch-c.in launch-c) + configure_file(scripts/launch-cxx.in launch-cxx) + execute_process(COMMAND chmod a+rx "${CMAKE_BINARY_DIR}/launch-c" "${CMAKE_BINARY_DIR}/launch-cxx") + + if(CMAKE_GENERATOR STREQUAL "Xcode") + # Set Xcode project attributes to route compilation and linking through our scripts + set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_BINARY_DIR}/launch-c") + set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_BINARY_DIR}/launch-cxx") + set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_BINARY_DIR}/launch-c") + set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_BINARY_DIR}/launch-cxx") + else() + # Support Unix Makefiles and Ninja + set(CMAKE_C_COMPILER_LAUNCHER "${CMAKE_BINARY_DIR}/launch-c") + set(CMAKE_CXX_COMPILER_LAUNCHER "${CMAKE_BINARY_DIR}/launch-cxx") + endif() + + if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") + # ccache splits up the compile steps, so we end up with unused arguments in some steps. + # Clang also thinks that ccache isn't interactive, so we explicitly need to enable color. + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Qunused-arguments -fcolor-diagnostics") + endif() +endif() + if(NOT EXISTS ${CMAKE_SOURCE_DIR}/platform/${MBGL_PLATFORM}/config.cmake) message(ERROR "Can't find config.cmake file for platform ${MBGL_PLATFORM}") endif() diff --git a/circle.yml b/circle.yml index 99e9be5a9d..7722bc2115 100644 --- a/circle.yml +++ b/circle.yml @@ -19,27 +19,118 @@ workflows: - linux-gcc5-release-qt4 - linux-gcc5-release-qt5 -jobs: +step-library: + - &generate-cache-key + run: + name: Generate cache key + command: | + echo "$(date +"%Y-%V")" > .circle-week + ccache --clear + ccache --max-size=5G + - &restore-cache + restore_cache: + keys: + - 'v3/{{ .Environment.CIRCLE_JOB }}/{{ .Branch }}/{{ checksum ".circle-week" }}' + - 'v3/{{ .Environment.CIRCLE_JOB }}/master/{{ checksum ".circle-week" }}' + - &save-cache + save_cache: + key: 'v3/{{ .Environment.CIRCLE_JOB }}/{{ .Branch }}/{{ checksum ".circle-week" }}' + paths: [ "node_modules", "/root/.ccache", "mason_packages/.binaries" ] + + + - &reset-ccache-stats + run: + name: Clear ccache statistics + command: | + ccache --zero-stats + ccache --show-stats + - &show-ccache-stats + run: + name: Show ccache statistics + command: ccache --show-stats + + + - &setup-llvm-symbolizer + run: + name: Environment Setup + command: | + # LLVM has a hard check for "llvm-symbolizer" and doesn't support suffixed executables + ln -s /usr/bin/llvm-symbolizer-* /usr/bin/llvm-symbolizer + # We'll use tee to redirect stderr to a file so we can check for sanitiziation + # https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/1059947 + sed -i 's/"$@" 2>&1/"$@"/' /usr/bin/xvfb-run + + + - &build-node + run: + name: Build node + command: make node + - &build-linux + run: + name: Build linux + command: make linux + - &build-benchmark + run: + name: Build benchmark + command: make benchmark + - &build-test + run: + name: Build test + command: make test + - &build-qt-app + run: + name: Build qt-app + command: make qt-app + - &build-qt-test + run: + name: Build qt-test + command: make qt-test + + + - &run-node-tests + run: + name: Run node tests + command: | + xvfb-run --server-args="-screen 0 1024x768x24" \ + logbt -- apitrace trace --api=egl -v make test-node + - &run-unit-tests + run: + name: Run tests + command: | + xvfb-run --server-args="-screen 0 1024x768x24" \ + make run-test + + - &publish-node-package + run: + name: Publish node package + when: on_success + command: platform/node/scripts/after_success.sh + + + - &upload-render-tests + store_artifacts: + path: mapbox-gl-js/test/integration/render-tests/index.html + destination: render-tests + +jobs: # ------------------------------------------------------------------------------ clang-tidy: docker: - image: mbgl/ci:r4-linux-clang-3.9 working_directory: /src environment: - LIBSYSCONFCPUS: 6 - JOBS: 6 + LIBSYSCONFCPUS: 4 + JOBS: 4 BUILDTYPE: Debug branches: ignore: - master steps: - checkout - - restore_cache: - key: v1-clang-tidy - paths: - - node_modules - - /root/.ccache + - *generate-cache-key + - *restore-cache + - *reset-ccache-stats - run: name: Fetch 'origin/master' branch command: git fetch origin master:refs/remotes/origin/master @@ -49,28 +140,23 @@ jobs: - run: name: Run Clang checks command: make check - - save_cache: - key: v1-clang-tidy - paths: - - node_modules - - /root/.ccache + - *show-ccache-stats + - *save-cache # ------------------------------------------------------------------------------ android-debug-arm-v7: docker: - - image: mbgl/ci:r4-android-ndk-r15-gradle + - image: mbgl/ci@sha256:c34e221294d81da80918d3e9a9df5de795b067e88f86d7c9a5e262763332536e working_directory: /src environment: - LIBSYSCONFCPUS: 6 - JOBS: 6 + LIBSYSCONFCPUS: 4 + JOBS: 4 BUILDTYPE: Debug steps: - checkout - - restore_cache: - key: v1-android-debug-arm-v7 - paths: - - node_modules - - /root/.ccache + - *generate-cache-key + - *restore-cache + - *reset-ccache-stats - run: name: Build libmapbox-gl.so for arm-v7 command: make android-lib-arm-v7 @@ -94,6 +180,8 @@ jobs: command: | echo "${MAPBOX_DEVELOPER_CONFIG_XML}" > platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/developer-config.xml make android-ui-test-arm-v7 + - *show-ccache-stats + - *save-cache - run: name: Log in to Google Cloud Platform shell: /bin/bash -euo pipefail @@ -122,11 +210,6 @@ jobs: xargs -0 -I '{}' ${ANDROID_NDK_HOME}/ndk-stack -sym build/android-arm-v7/Debug -dump {} exit ${EXIT_CODE:-0} - - save_cache: - key: v1-android-debug-arm-v7 - paths: - - node_modules - - /root/.ccache - store_artifacts: path: platform/android/MapboxGLAndroidSDKTestApp/build/outputs/apk destination: . @@ -134,19 +217,17 @@ jobs: # ------------------------------------------------------------------------------ android-release-all: docker: - - image: mbgl/ci:r4-android-ndk-r15-gradle + - image: mbgl/ci@sha256:c34e221294d81da80918d3e9a9df5de795b067e88f86d7c9a5e262763332536e working_directory: /src environment: - LIBSYSCONFCPUS: 6 - JOBS: 6 + LIBSYSCONFCPUS: 4 + JOBS: 4 BUILDTYPE: Release steps: - checkout - - restore_cache: - key: v1-android-release-all - paths: - - node_modules - - /root/.ccache + - *generate-cache-key + - *restore-cache + - *reset-ccache-stats - run: name: Generate Maven credentials shell: /bin/bash -euo pipefail @@ -160,6 +241,8 @@ jobs: - run: name: Build package command: make apackage + - *show-ccache-stats + - *save-cache - store_artifacts: path: platform/android/MapboxGLAndroidSDKTestApp/build/outputs/apk destination: . @@ -172,11 +255,7 @@ jobs: name: Publish to Maven command: | if [ "${CIRCLE_BRANCH}" == "master" ]; then make run-android-upload-archives ; fi - - save_cache: - key: v1-android-release-all - paths: - - node_modules - - /root/.ccache + # ------------------------------------------------------------------------------ node4-clang39-release: @@ -184,39 +263,23 @@ jobs: - image: mbgl/ci:r4-linux-clang-3.9-node-4 working_directory: /src environment: - LIBSYSCONFCPUS: 6 - JOBS: 6 + LIBSYSCONFCPUS: 4 + JOBS: 4 BUILDTYPE: Release WITH_EGL: 1 PACKAGE_JSON_VERSION: $(node -e "console.log(require('./package.json').version)") PUBLISH: $([[ "${CIRCLE_BRANCH}" == "node-v${PACKAGE_JSON_VERSION}" ]] && echo true) steps: - checkout - - restore_cache: - key: v1-node4-clang39-release - paths: - - node_modules - - /root/.ccache - - run: - name: Build node - command: make node - - run: - name: Run node tests - command: | - xvfb-run --server-args="-screen 0 1024x768x24" \ - logbt -- apitrace trace --api=egl -v make test-node - - run: - name: Publish node package - when: on_success - command: platform/node/scripts/after_success.sh - - save_cache: - key: v1-node4-clang39-release - paths: - - node_modules - - /root/.ccache - - store_artifacts: - path: mapbox-gl-js/test/integration/render-tests/index.html - destination: render-tests + - *generate-cache-key + - *restore-cache + - *reset-ccache-stats + - *build-node + - *show-ccache-stats + - *run-node-tests + - *publish-node-package + - *save-cache + - *upload-render-tests # ------------------------------------------------------------------------------ node6-clang39-release: @@ -224,39 +287,23 @@ jobs: - image: mbgl/ci:r4-linux-clang-3.9 working_directory: /src environment: - LIBSYSCONFCPUS: 6 - JOBS: 6 + LIBSYSCONFCPUS: 4 + JOBS: 4 BUILDTYPE: Release WITH_EGL: 1 PACKAGE_JSON_VERSION: $(node -e "console.log(require('./package.json').version)") PUBLISH: $([[ "${CIRCLE_BRANCH}" == "node-v${PACKAGE_JSON_VERSION}" ]] && echo true) steps: - checkout - - restore_cache: - key: v1-node6-clang39-release - paths: - - node_modules - - /root/.ccache - - run: - name: Build node - command: make node - - run: - name: Run node tests - command: | - xvfb-run --server-args="-screen 0 1024x768x24" \ - logbt -- apitrace trace --api=egl -v make test-node - - run: - name: Publish node package - when: on_success - command: platform/node/scripts/after_success.sh - - save_cache: - key: v1-node6-clang39-release - paths: - - node_modules - - /root/.ccache - - store_artifacts: - path: mapbox-gl-js/test/integration/render-tests/index.html - destination: render-tests + - *generate-cache-key + - *restore-cache + - *reset-ccache-stats + - *build-node + - *show-ccache-stats + - *run-node-tests + - *publish-node-package + - *save-cache + - *upload-render-tests # ------------------------------------------------------------------------------ node6-clang39-debug: @@ -264,39 +311,23 @@ jobs: - image: mbgl/ci:r4-linux-clang-3.9 working_directory: /src environment: - LIBSYSCONFCPUS: 6 - JOBS: 6 + LIBSYSCONFCPUS: 4 + JOBS: 4 BUILDTYPE: Debug WITH_EGL: 1 PACKAGE_JSON_VERSION: $(node -e "console.log(require('./package.json').version)") PUBLISH: $([[ "${CIRCLE_BRANCH}" == "node-v${PACKAGE_JSON_VERSION}" ]] && echo true) steps: - checkout - - restore_cache: - key: v1-node6-clang39-debug - paths: - - node_modules - - /root/.ccache - - run: - name: Build node - command: make node - - run: - name: Run node tests - command: | - xvfb-run --server-args="-screen 0 1024x768x24" \ - logbt -- apitrace trace --api=egl -v make test-node - - run: - name: Publish node package - when: on_success - command: platform/node/scripts/after_success.sh - - save_cache: - key: v1-node6-clang39-debug - paths: - - node_modules - - /root/.ccache - - store_artifacts: - path: mapbox-gl-js/test/integration/render-tests/index.html - destination: render-tests + - *generate-cache-key + - *restore-cache + - *reset-ccache-stats + - *build-node + - *show-ccache-stats + - *run-node-tests + - *publish-node-package + - *save-cache + - *upload-render-tests # ------------------------------------------------------------------------------ linux-clang39-debug: @@ -304,37 +335,21 @@ jobs: - image: mbgl/ci:r4-linux-clang-3.9 working_directory: /src environment: - LIBSYSCONFCPUS: 6 - JOBS: 6 + LIBSYSCONFCPUS: 4 + JOBS: 4 BUILDTYPE: Debug WITH_EGL: 1 steps: - checkout - - restore_cache: - key: v1-linux-clang39-debug - paths: - - node_modules - - /root/.ccache - - run: - name: Build linux - command: make linux - - run: - name: Build benchmark - command: make benchmark - - run: - name: Build test - command: make test - - run: - name: Run tests - command: | - xvfb-run --server-args="-screen 0 1024x768x24" \ - make run-test - - save_cache: - key: v1-linux-clang39-debug - paths: - - node_modules - - /root/.ccache - + - *generate-cache-key + - *restore-cache + - *reset-ccache-stats + - *build-linux + - *build-benchmark + - *build-test + - *show-ccache-stats + - *run-unit-tests + - *save-cache # ------------------------------------------------------------------------------ linux-clang4-sanitize-address: @@ -342,44 +357,29 @@ jobs: - image: mbgl/ci:r4-linux-clang-4 working_directory: /src environment: - LIBSYSCONFCPUS: 6 - JOBS: 6 + LIBSYSCONFCPUS: 4 + JOBS: 4 BUILDTYPE: Sanitize WITH_EGL: 1 GDB: '' # Do not run with GDB CXXFLAGS: -fsanitize=address LDFLAGS: -fsanitize=address - ASAN_OPTIONS: detect_leaks=0:color=always + ASAN_OPTIONS: detect_leaks=0:color=always:print_summary=1 steps: - checkout - - restore_cache: - key: v1-linux-clang4-sanitize-address - paths: - - node_modules - - /root/.ccache - - run: - name: Environment Setup - command: | - # LLVM has a hard check for "llvm-symbolizer" and doesn't support suffixed executables - ln -s /usr/bin/llvm-symbolizer-* /usr/bin/llvm-symbolizer - # We'll use tee to redirect stderr to a file so we can check for sanitiziation - # https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/1059947 - sed -i 's/"$@" 2>&1/"$@"/' /usr/bin/xvfb-run - - run: - name: Build test - command: make test + - *generate-cache-key + - *restore-cache + - *reset-ccache-stats + - *setup-llvm-symbolizer + - *build-test + - *show-ccache-stats - run: name: Run tests command: | xvfb-run --server-args="-screen 0 1024x768x24" make run-test 2> >(tee sanitizer 1>&2) # Unfortunately, Google Test eats the status code, so we'll have to check the output. [ -z "$(sed -n '/^SUMMARY: AddressSanitizer:/p' sanitizer)" ] - - save_cache: - key: v1-linux-clang4-sanitize-address - paths: - - node_modules - - /root/.ccache - + - *save-cache # ------------------------------------------------------------------------------ linux-clang4-sanitize-undefined: @@ -387,46 +387,29 @@ jobs: - image: mbgl/ci:r4-linux-clang-4 working_directory: /src environment: - LIBSYSCONFCPUS: 6 - JOBS: 6 + LIBSYSCONFCPUS: 4 + JOBS: 4 BUILDTYPE: Sanitize WITH_EGL: 1 GDB: '' # Do not run with GDB CXXFLAGS: -fsanitize=undefined LDFLAGS: -fsanitize=undefined - UBSAN_OPTIONS: print_stacktrace=1:color=always + UBSAN_OPTIONS: print_stacktrace=1:color=always:print_summary=1 steps: - checkout - - restore_cache: - key: v1-linux-clang4-sanitize-undefined - paths: - - node_modules - - /root/.ccache - - run: - name: Environment Setup - command: | - # LLVM has a hard check for "llvm-symbolizer" and doesn't support suffixed executables - ln -s /usr/bin/llvm-symbolizer-* /usr/bin/llvm-symbolizer - # We'll use tee to redirect stderr to a file so we can check for sanitiziation - # https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/1059947 - sed -i 's/"$@" 2>&1/"$@"/' /usr/bin/xvfb-run - - run: - name: Build test - command: make test + - *generate-cache-key + - *restore-cache + - *reset-ccache-stats + - *setup-llvm-symbolizer + - *build-test + - *show-ccache-stats - run: name: Run tests command: | xvfb-run --server-args="-screen 0 1024x768x24" make run-test 2> >(tee sanitizer 1>&2) # Unfortunately, Google Test eats the status code, so we'll have to check the output. - # Uncomment this once we've fixed all thread behavior to make new thread behavior - # fail on CircleCI. - # [ -z "$(sed -n '/^SUMMARY: UndefinedBehaviorSanitizer:/p' sanitizer)" ] - - save_cache: - key: v1-linux-clang4-sanitize-address-undefined - paths: - - node_modules - - /root/.ccache - + [ -z "$(sed -n '/^SUMMARY: UndefinedBehaviorSanitizer:/p' sanitizer)" ] + - *save-cache # ------------------------------------------------------------------------------ linux-clang4-sanitize-thread: @@ -434,52 +417,37 @@ jobs: - image: mbgl/ci:r4-linux-clang-4 working_directory: /src environment: - LIBSYSCONFCPUS: 6 - JOBS: 6 + LIBSYSCONFCPUS: 4 + JOBS: 4 BUILDTYPE: Sanitize WITH_EGL: 1 GDB: '' # Do not run with GDB CXXFLAGS: -fsanitize=thread LDFLAGS: -fsanitize=thread - TSAN_OPTIONS: color=always + TSAN_OPTIONS: color=always:print_summary=1 steps: - checkout - - restore_cache: - key: v1-linux-clang4-sanitize-thread - paths: - - node_modules - - /root/.ccache - - run: - name: Environment Setup - command: | - # LLVM has a hard check for "llvm-symbolizer" and doesn't support suffixed executables - ln -s /usr/bin/llvm-symbolizer-* /usr/bin/llvm-symbolizer - # We'll use tee to redirect stderr to a file so we can check for sanitiziation - # https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/1059947 - sed -i 's/"$@" 2>&1/"$@"/' /usr/bin/xvfb-run - - run: - name: Build test - command: make test + - *generate-cache-key + - *restore-cache + - *reset-ccache-stats + - *setup-llvm-symbolizer + - *build-test + - *show-ccache-stats + - *save-cache - run: name: Run tests command: | xvfb-run --server-args="-screen 0 1024x768x24" make run-test 2> >(tee sanitizer 1>&2) # Unfortunately, Google Test eats the status code, so we'll have to check the output. [ -z "$(sed -n '/^SUMMARY: ThreadSanitizer:/p' sanitizer)" ] - - save_cache: - key: v1-linux-clang4-sanitize-thread - paths: - - node_modules - - /root/.ccache - # ------------------------------------------------------------------------------ linux-gcc4.9-debug: docker: - - image: mbgl/ci:r3-linux-gcc-4.9 + - image: mbgl/ci:r4-linux-gcc-4.9 working_directory: /src environment: - LIBSYSCONFCPUS: 6 + LIBSYSCONFCPUS: 4 JOBS: 2 BUILDTYPE: Debug WITH_EGL: 1 @@ -487,32 +455,15 @@ jobs: DISPLAY: :0 steps: - checkout - - restore_cache: - key: v1-linux-gcc4.9-debug - paths: - - node_modules - - /root/.ccache - - run: - name: Build linux - command: make linux - - run: - name: Build benchmark - command: make benchmark - - run: - name: Build test - command: make test - - run: - name: Run tests - command: | - source scripts/circle_setup.sh - mapbox_export_mesa_library_path - xvfb-run --server-args="-screen 0 1024x768x24" \ - make run-test - - save_cache: - key: v1-linux-gcc4.9-debug - paths: - - node_modules - - /root/.ccache + - *generate-cache-key + - *restore-cache + - *reset-ccache-stats + - *build-linux + - *build-benchmark + - *build-test + - *show-ccache-stats + - *save-cache + - *run-unit-tests # ------------------------------------------------------------------------------ linux-gcc5-debug-coverage: @@ -520,41 +471,25 @@ jobs: - image: mbgl/ci:r4-linux-gcc-5 working_directory: /src environment: - LIBSYSCONFCPUS: 6 + LIBSYSCONFCPUS: 4 JOBS: 2 BUILDTYPE: Debug WITH_EGL: 1 WITH_COVERAGE: 1 steps: - checkout - - restore_cache: - key: v1-linux-gcc5-debug-coverage - paths: - - node_modules - - /root/.ccache - - run: - name: Build linux - command: make linux - - run: - name: Build benchmark - command: make benchmark - - run: - name: Build test - command: make test - - run: - name: Run tests - command: | - xvfb-run --server-args="-screen 0 1024x768x24" \ - make run-test + - *generate-cache-key + - *restore-cache + - *reset-ccache-stats + - *build-linux + - *build-benchmark + - *build-test + - *run-unit-tests - run: name: Upload coverage results to coveralls command: | platform/linux/scripts/coveralls.sh - - save_cache: - key: v1-linux-gcc5-debug-coverage - paths: - - node_modules - - /root/.ccache + - *save-cache # ------------------------------------------------------------------------------ linux-gcc5-release-qt4: @@ -562,36 +497,26 @@ jobs: - image: mbgl/ci:r4-linux-gcc-5-qt-4 working_directory: /src environment: - LIBSYSCONFCPUS: 6 + LIBSYSCONFCPUS: 4 JOBS: 2 # OOM, causing the compiler to crash. BUILDTYPE: Release GTEST_OUTPUT: xml LD_PRELOAD: /usr/lib/x86_64-linux-gnu/libjemalloc.so - DISPLAY: 0 steps: - checkout - - restore_cache: - key: v1-linux-gcc5-release-qt4 - paths: - - node_modules - - /root/.ccache - - run: - name: Build qt-app - command: make qt-app - - run: - name: Build qt-test - command: make qt-test + - *generate-cache-key + - *restore-cache + - *reset-ccache-stats + - *build-qt-app + - *build-qt-test + - *show-ccache-stats - run: name: Run memory-load tests command: | xvfb-run --server-args="-screen 0 1024x768x24" \ make run-qt-test-Memory.*:*.Load scripts/log_memory_benchmarks.sh test_detail.xml "Platform=Linux,Compiler=${_CC},Arch=$(uname -m)" - - save_cache: - key: v1-linux-gcc5-release-qt4 - paths: - - node_modules - - /root/.ccache + - *save-cache # ------------------------------------------------------------------------------ linux-gcc5-release-qt5: @@ -599,27 +524,21 @@ jobs: - image: mbgl/ci:r4-linux-gcc-5-qt-5 working_directory: /src environment: - LIBSYSCONFCPUS: 6 + LIBSYSCONFCPUS: 4 JOBS: 2 # OOM, causing the compiler to crash. BUILDTYPE: Release WITH_QT_I18N: 1 - DISPLAY: 0 steps: - checkout - - restore_cache: - key: v1-linux-gcc5-release-qt5 - paths: - - node_modules - - /root/.ccache - - run: - name: Build qt-app - command: make qt-app - - run: - name: Build qt-test - command: make qt-test + - *generate-cache-key + - *restore-cache + - *reset-ccache-stats + - *build-qt-app + - *build-qt-test - run: name: Build qt-docs command: make qt-docs + - *show-ccache-stats - run: name: Run valgrind-backed tests environment: @@ -627,8 +546,4 @@ jobs: command: | xvfb-run --server-args="-screen 0 1024x768x24" \ scripts/valgrind.sh build/qt-linux-x86_64/Release/mbgl-test --gtest_filter=-*.Load --gtest_filter=-Memory.Vector - - save_cache: - key: v1-linux-gcc5-release-qt5 - paths: - - node_modules - - /root/.ccache + - *save-cache diff --git a/scripts/launch-c.in b/scripts/launch-c.in new file mode 100644 index 0000000000..6c6c9180bc --- /dev/null +++ b/scripts/launch-c.in @@ -0,0 +1,10 @@ +#!/bin/sh + +# Xcode generator doesn't include the compiler as the +# first argument, Ninja and Makefiles do. Handle both cases. +if [ "$1" = "${CMAKE_C_COMPILER}" ] ; then + shift +fi + +export CCACHE_CPP2=true +exec "${C_LAUNCHER}" "${CMAKE_C_COMPILER}" "$@" diff --git a/scripts/launch-cxx.in b/scripts/launch-cxx.in new file mode 100644 index 0000000000..23f107ce48 --- /dev/null +++ b/scripts/launch-cxx.in @@ -0,0 +1,10 @@ +#!/bin/sh + +# Xcode generator doesn't include the compiler as the +# first argument, Ninja and Makefiles do. Handle both cases. +if [ "$1" = "${CMAKE_CXX_COMPILER}" ] ; then + shift +fi + +export CCACHE_CPP2=true +exec "${CXX_LAUNCHER}" "${CMAKE_CXX_COMPILER}" "$@" \ No newline at end of file -- cgit v1.2.1 From 06e202441e9ba5bfc87a5be7c7e157fff61a6264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Thu, 13 Jul 2017 16:44:45 +0200 Subject: [build] upload cache on Circle CI before running tests --- circle.yml | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/circle.yml b/circle.yml index 7722bc2115..81826102e5 100644 --- a/circle.yml +++ b/circle.yml @@ -137,11 +137,11 @@ jobs: - run: name: Generate compilation database command: make compdb + - *show-ccache-stats + - *save-cache - run: name: Run Clang checks command: make check - - *show-ccache-stats - - *save-cache # ------------------------------------------------------------------------------ android-debug-arm-v7: @@ -276,9 +276,9 @@ jobs: - *reset-ccache-stats - *build-node - *show-ccache-stats + - *save-cache - *run-node-tests - *publish-node-package - - *save-cache - *upload-render-tests # ------------------------------------------------------------------------------ @@ -300,9 +300,9 @@ jobs: - *reset-ccache-stats - *build-node - *show-ccache-stats + - *save-cache - *run-node-tests - *publish-node-package - - *save-cache - *upload-render-tests # ------------------------------------------------------------------------------ @@ -324,9 +324,9 @@ jobs: - *reset-ccache-stats - *build-node - *show-ccache-stats + - *save-cache - *run-node-tests - *publish-node-package - - *save-cache - *upload-render-tests # ------------------------------------------------------------------------------ @@ -348,8 +348,8 @@ jobs: - *build-benchmark - *build-test - *show-ccache-stats - - *run-unit-tests - *save-cache + - *run-unit-tests # ------------------------------------------------------------------------------ linux-clang4-sanitize-address: @@ -373,13 +373,13 @@ jobs: - *setup-llvm-symbolizer - *build-test - *show-ccache-stats + - *save-cache - run: name: Run tests command: | xvfb-run --server-args="-screen 0 1024x768x24" make run-test 2> >(tee sanitizer 1>&2) # Unfortunately, Google Test eats the status code, so we'll have to check the output. [ -z "$(sed -n '/^SUMMARY: AddressSanitizer:/p' sanitizer)" ] - - *save-cache # ------------------------------------------------------------------------------ linux-clang4-sanitize-undefined: @@ -403,13 +403,13 @@ jobs: - *setup-llvm-symbolizer - *build-test - *show-ccache-stats + - *save-cache - run: name: Run tests command: | xvfb-run --server-args="-screen 0 1024x768x24" make run-test 2> >(tee sanitizer 1>&2) # Unfortunately, Google Test eats the status code, so we'll have to check the output. [ -z "$(sed -n '/^SUMMARY: UndefinedBehaviorSanitizer:/p' sanitizer)" ] - - *save-cache # ------------------------------------------------------------------------------ linux-clang4-sanitize-thread: @@ -484,12 +484,13 @@ jobs: - *build-linux - *build-benchmark - *build-test + - *show-ccache-stats + - *save-cache - *run-unit-tests - run: name: Upload coverage results to coveralls command: | platform/linux/scripts/coveralls.sh - - *save-cache # ------------------------------------------------------------------------------ linux-gcc5-release-qt4: @@ -510,13 +511,13 @@ jobs: - *build-qt-app - *build-qt-test - *show-ccache-stats + - *save-cache - run: name: Run memory-load tests command: | xvfb-run --server-args="-screen 0 1024x768x24" \ make run-qt-test-Memory.*:*.Load scripts/log_memory_benchmarks.sh test_detail.xml "Platform=Linux,Compiler=${_CC},Arch=$(uname -m)" - - *save-cache # ------------------------------------------------------------------------------ linux-gcc5-release-qt5: @@ -539,6 +540,7 @@ jobs: name: Build qt-docs command: make qt-docs - *show-ccache-stats + - *save-cache - run: name: Run valgrind-backed tests environment: @@ -546,4 +548,3 @@ jobs: command: | xvfb-run --server-args="-screen 0 1024x768x24" \ scripts/valgrind.sh build/qt-linux-x86_64/Release/mbgl-test --gtest_filter=-*.Load --gtest_filter=-Memory.Vector - - *save-cache -- cgit v1.2.1 From 86682f2507a9ce4b3101a8287f5e7e1bf53d0ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Thu, 13 Jul 2017 16:31:47 +0200 Subject: [core] fix undefined access for HTTP responses that don't contain a body --- platform/default/mbgl/storage/offline_database.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/default/mbgl/storage/offline_database.cpp b/platform/default/mbgl/storage/offline_database.cpp index 02736f10a4..bad4ccdbf1 100644 --- a/platform/default/mbgl/storage/offline_database.cpp +++ b/platform/default/mbgl/storage/offline_database.cpp @@ -188,11 +188,11 @@ std::pair OfflineDatabase::putInternal(const Resource& resource, if (resource.kind == Resource::Kind::Tile) { assert(resource.tileData); inserted = putTile(*resource.tileData, response, - compressed ? compressedData : *response.data, + compressed ? compressedData : response.data ? *response.data : "", compressed); } else { inserted = putResource(resource, response, - compressed ? compressedData : *response.data, + compressed ? compressedData : response.data ? *response.data : "", compressed); } -- cgit v1.2.1 From 13d6920661432afcbfbd6c956708964efc366dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Thu, 13 Jul 2017 16:57:31 +0200 Subject: [core] fix division by zero when defaultFadeDuration is 0 --- src/mbgl/renderer/cross_faded_property_evaluator.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mbgl/renderer/cross_faded_property_evaluator.cpp b/src/mbgl/renderer/cross_faded_property_evaluator.cpp index ee3c86614f..4dff9dbf12 100644 --- a/src/mbgl/renderer/cross_faded_property_evaluator.cpp +++ b/src/mbgl/renderer/cross_faded_property_evaluator.cpp @@ -27,7 +27,10 @@ Faded CrossFadedPropertyEvaluator::calculate(const T& min, const T& mid, c const float z = parameters.z; const float fraction = z - std::floor(z); const std::chrono::duration d = parameters.defaultFadeDuration; - const float t = std::min((parameters.now - parameters.zoomHistory.lastIntegerZoomTime) / d, 1.0f); + const float t = + d != std::chrono::duration::zero() + ? std::min((parameters.now - parameters.zoomHistory.lastIntegerZoomTime) / d, 1.0f) + : 1.0f; return z > parameters.zoomHistory.lastIntegerZoom ? Faded { min, mid, 2.0f, 1.0f, fraction + (1.0f - fraction) * t } -- cgit v1.2.1 From 04fba1e01f61865f5af516cf433ab618df55737c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Thu, 13 Jul 2017 16:22:14 +0200 Subject: [core] add unused default template parameter to keep Xcode 9's Clang from crashing --- test/algorithm/update_renderables.test.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/algorithm/update_renderables.test.cpp b/test/algorithm/update_renderables.test.cpp index 26b7cf7f72..d23e1cc1ac 100644 --- a/test/algorithm/update_renderables.test.cpp +++ b/test/algorithm/update_renderables.test.cpp @@ -100,12 +100,18 @@ auto createTileDataFn(ActionLog& log, T& dataTiles) { }; } +// Unused template argument to fix Clang crash +// See https://github.com/mapbox/mapbox-gl-native/pull/9501 +template auto retainTileDataFn(ActionLog& log) { return [&](auto& tileData, Resource::Necessity necessity) { log.emplace_back(RetainTileDataAction{ tileData.tileID, necessity }); }; } +// Unused template argument to fix Clang crash +// See https://github.com/mapbox/mapbox-gl-native/pull/9501 +template auto renderTileFn(ActionLog& log) { return [&](const auto& id, auto& tileData) { log.emplace_back(RenderTileAction{ id, tileData }); -- cgit v1.2.1 From 3b26177e9d3d9ed87f96ac33e7ed74bc7653f661 Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Thu, 13 Jul 2017 11:43:48 -0700 Subject: [test] Fix undefined behavior warning: quads.test.cpp used a bin with unsupported x/y coordinates. Issue #9499. --- test/text/quads.test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/text/quads.test.cpp b/test/text/quads.test.cpp index f24b01ca87..682ba9d795 100644 --- a/test/text/quads.test.cpp +++ b/test/text/quads.test.cpp @@ -13,7 +13,7 @@ TEST(getIconQuads, normal) { SymbolLayoutProperties::Evaluated layout; Anchor anchor(2.0, 3.0, 0.0, 0.5f, 0); ImagePosition image = { - mapbox::Bin(-1, 15, 11, 0, 0), + mapbox::Bin(-1, 15, 11, 0, 0, 0, 0), style::Image::Impl("test", PremultipliedImage({1,1}), 1.0) }; @@ -38,7 +38,7 @@ TEST(getIconQuads, normal) { TEST(getIconQuads, style) { Anchor anchor(0.0, 0.0, 0.0, 0.5f, 0); ImagePosition image = { - mapbox::Bin(-1, 20, 20, 0, 0), + mapbox::Bin(-1, 20, 20, 0, 0, 0, 0), style::Image::Impl("test", PremultipliedImage({1,1}), 1.0) }; -- cgit v1.2.1 From 48ddfef89ff4daa2e26d3338dbfc20c4f4cc7d21 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Thu, 13 Jul 2017 16:38:42 +0300 Subject: [core] Make sure ThreadLocal will not own the pointer it is managing ThreadLocal should not own the pointer it is managing because the use case in Mapbox GL is to keep a pointer to a stack allocated object, like: ``` MyObject foo; threadLocal.set(&foo); ``` To keep consistency, it is required that we clear the managed object before ThreadLocal gets destroyed by setting it to `nullptr`. --- platform/default/thread_local.cpp | 6 +++++- platform/qt/src/thread_local.cpp | 7 ++++++- scripts/valgrind.sup | 8 -------- test/util/thread_local.test.cpp | 28 ++++++++++++++++++---------- 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/platform/default/thread_local.cpp b/platform/default/thread_local.cpp index b754a04b7d..6fdb1e6dc1 100644 --- a/platform/default/thread_local.cpp +++ b/platform/default/thread_local.cpp @@ -29,7 +29,11 @@ ThreadLocal::ThreadLocal() : impl(std::make_unique()) { template ThreadLocal::~ThreadLocal() { - delete get(); + // ThreadLocal will not take ownership + // of the pointer it is managing. The pointer + // needs to be explicitly cleared before we + // destroy this object. + assert(!get()); if (pthread_key_delete(impl->key)) { Log::Error(Event::General, "Failed to delete local storage key."); diff --git a/platform/qt/src/thread_local.cpp b/platform/qt/src/thread_local.cpp index e48a9d6e74..e835a680e2 100644 --- a/platform/qt/src/thread_local.cpp +++ b/platform/qt/src/thread_local.cpp @@ -4,6 +4,7 @@ #include #include +#include #include @@ -23,7 +24,11 @@ ThreadLocal::ThreadLocal() : impl(std::make_unique()) { template ThreadLocal::~ThreadLocal() { - delete get(); + // ThreadLocal will not take ownership + // of the pointer it is managing. The pointer + // needs to be explicitly cleared before we + // destroy this object. + assert(!get()); } template diff --git a/scripts/valgrind.sup b/scripts/valgrind.sup index f659122dc1..09e2f6685c 100644 --- a/scripts/valgrind.sup +++ b/scripts/valgrind.sup @@ -76,11 +76,3 @@ fun:_ZN4mbgl4util10write_fileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_ ... } -{ - Qt5 ThreadStorage - Memcheck:Leak - match-leak-kinds: definite - fun:_Znwm - fun:_Z24qThreadStorage_localDataISt5arrayIPiLm1EEERT_R18QThreadStorageDataPS3_.isra.5 - ... -} diff --git a/test/util/thread_local.test.cpp b/test/util/thread_local.test.cpp index 12a19ab59b..7142697f48 100644 --- a/test/util/thread_local.test.cpp +++ b/test/util/thread_local.test.cpp @@ -71,30 +71,38 @@ TEST(ThreadLocalStorage, NotSetReturnsNull) { namespace { -class TestThreadReclaim { +class TestThreadDataOwnership { public: - TestThreadReclaim(mbgl::ActorRef, int* data_) { + TestThreadDataOwnership(mbgl::ActorRef, int* data_) { data.set(data_); } + ~TestThreadDataOwnership() { + data.set(nullptr); + } + private: - ThreadLocal data; + static ThreadLocal data; }; +ThreadLocal TestThreadDataOwnership::data; + } // namespace -TEST(ThreadLocalStorage, AutoReclaim) { +TEST(ThreadLocalStorage, ShouldNotTakeOwnership) { RunLoop loop; - auto data1 = new int; - auto data2 = new int; + auto data1 = std::make_unique(10); + auto data2 = std::make_unique(20); - auto thread1 = std::make_unique>("Test", data1); - auto thread2 = std::make_unique>("Test", data2); + auto thread1 = std::make_unique>("Test", data1.get()); + auto thread2 = std::make_unique>("Test", data2.get()); thread1.reset(); thread2.reset(); - // Should not leak, valgrind will - // let us know. + // Will crash if ThreadLocal destroys + // the pointer it is managing. + ASSERT_EQ(*data1, 10); + ASSERT_EQ(*data2, 20); } -- cgit v1.2.1 From 460643b21310d4ce40b355cc9e365da4e7cba8e3 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Thu, 13 Jul 2017 14:54:09 +0300 Subject: [build] Publish node packages with RelWithDebInfo --- CMakeLists.txt | 3 ++- Makefile | 3 ++- circle.yml | 4 ++-- mapbox-gl-js | 2 +- platform/node/bitrise.yml | 2 +- platform/node/scripts/after_success.sh | 9 ++++++--- 6 files changed, 14 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a4a6e4d8c9..d709f1117c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,7 +68,7 @@ if(WITH_COVERAGE) set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --coverage") endif(WITH_COVERAGE) -set(CMAKE_CONFIGURATION_TYPES Debug Release Sanitize) +set(CMAKE_CONFIGURATION_TYPES Debug Release RelWithDebugInfo Sanitize) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -ftemplate-depth=1024 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Werror -Wno-variadic-macros -Wno-unknown-pragmas") if(APPLE AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") @@ -76,6 +76,7 @@ if(APPLE AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=unused-command-line-argument") endif() set(CMAKE_CXX_FLAGS_RELEASE "-Os -DNDEBUG") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -DNDEBUG") set(CMAKE_CXX_FLAGS_SANITIZE "-O1 -g -fno-omit-frame-pointer -fno-optimize-sibling-calls") diff --git a/Makefile b/Makefile index b6e4b608fa..dfa5c8b640 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,11 @@ export BUILDTYPE ?= Debug export WITH_CXX11ABI ?= $(shell scripts/check-cxx11abi.sh) ifeq ($(BUILDTYPE), Release) +else ifeq ($(BUILDTYPE), RelWithDebInfo) else ifeq ($(BUILDTYPE), Sanitize) else ifeq ($(BUILDTYPE), Debug) else - $(error BUILDTYPE must be Debug, Sanitize or Release) + $(error BUILDTYPE must be Debug, Sanitize, Release or RelWithDebInfo) endif buildtype := $(shell echo "$(BUILDTYPE)" | tr "[A-Z]" "[a-z]") diff --git a/circle.yml b/circle.yml index 81826102e5..221ddd2f08 100644 --- a/circle.yml +++ b/circle.yml @@ -265,7 +265,7 @@ jobs: environment: LIBSYSCONFCPUS: 4 JOBS: 4 - BUILDTYPE: Release + BUILDTYPE: RelWithDebInfo WITH_EGL: 1 PACKAGE_JSON_VERSION: $(node -e "console.log(require('./package.json').version)") PUBLISH: $([[ "${CIRCLE_BRANCH}" == "node-v${PACKAGE_JSON_VERSION}" ]] && echo true) @@ -289,7 +289,7 @@ jobs: environment: LIBSYSCONFCPUS: 4 JOBS: 4 - BUILDTYPE: Release + BUILDTYPE: RelWithDebInfo WITH_EGL: 1 PACKAGE_JSON_VERSION: $(node -e "console.log(require('./package.json').version)") PUBLISH: $([[ "${CIRCLE_BRANCH}" == "node-v${PACKAGE_JSON_VERSION}" ]] && echo true) diff --git a/mapbox-gl-js b/mapbox-gl-js index 4c1ce2d2c1..f27666813d 160000 --- a/mapbox-gl-js +++ b/mapbox-gl-js @@ -1 +1 @@ -Subproject commit 4c1ce2d2c1a504a1984073672d15288f92302b4d +Subproject commit f27666813dd8e3d738a3962b3d86d0ec799b6fc7 diff --git a/platform/node/bitrise.yml b/platform/node/bitrise.yml index 00005f0f36..fab3093d6e 100644 --- a/platform/node/bitrise.yml +++ b/platform/node/bitrise.yml @@ -64,7 +64,7 @@ workflows: brew install cmake awscli node@4 node@6 brew link node@4 --force gem install xcpretty --no-rdoc --no-ri - export BUILDTYPE=Release + export BUILDTYPE=RelWithDebInfo export PUBLISH=true make test-node && ./platform/node/scripts/after_success.sh brew unlink node@4 diff --git a/platform/node/scripts/after_success.sh b/platform/node/scripts/after_success.sh index a050dbce07..d761d4110f 100755 --- a/platform/node/scripts/after_success.sh +++ b/platform/node/scripts/after_success.sh @@ -3,10 +3,13 @@ set -e set -o pipefail -if [[ "${PUBLISH:-}" == "true" ]]; then - if [[ "${BUILDTYPE}" == "Release" ]]; then +if [[ -n ${PUBLISH:-} ]]; then + if [[ "${BUILDTYPE}" == "RelWithDebInfo" ]]; then ./node_modules/.bin/node-pre-gyp package publish info - else + elif [[ "${BUILDTYPE}" == "Debug" ]]; then ./node_modules/.bin/node-pre-gyp package publish info --debug + else + echo "error: must provide either Debug or RelWithDebInfo for BUILDTYPE" + exit 1 fi fi -- cgit v1.2.1 From a019f26d99449d6b9fb9a03471c90443f8d033b7 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Fri, 14 Jul 2017 14:15:33 +0300 Subject: [node] Bump version to 3.5.5 --- package.json | 2 +- platform/node/CHANGELOG.md | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index e428a0db43..0cd6b450c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mapbox/mapbox-gl-native", - "version": "3.5.4", + "version": "3.5.5", "description": "Renders map tiles with Mapbox GL", "keywords": [ "mapbox", diff --git a/platform/node/CHANGELOG.md b/platform/node/CHANGELOG.md index dee001c426..bdcad8c0e0 100644 --- a/platform/node/CHANGELOG.md +++ b/platform/node/CHANGELOG.md @@ -1,3 +1,6 @@ +# 3.5.5 - July 14, 2017 +- Provide debuggable release builds for node packages [#9497](https://github.com/mapbox/mapbox-gl-native/pull/9497) + # 3.5.4 - June 6, 2017 - Add support for ImageSource [#8968](https://github.com/mapbox/mapbox-gl-native/pull/8968) - Fixed an issue with `map.addImage()` which would cause added images to randomly be replaced with images found the style's sprite sheet ([#9119](https://github.com/mapbox/mapbox-gl-native/pull/9119)) -- cgit v1.2.1 From 3c6a6c53b4413d7758ac38c92b5416407d031025 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Mon, 17 Jul 2017 09:12:19 +0200 Subject: [android] - rewire gesture handling and telemetry event push (#9494) --- .../mapbox/mapboxsdk/maps/MapGestureDetector.java | 121 ++++++++++----------- 1 file changed, 57 insertions(+), 64 deletions(-) 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 330e09cf32..675d7cc5c5 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 @@ -50,13 +50,12 @@ final class MapGestureDetector { private PointF focalPoint; - private boolean twoTap = false; - private boolean zoomStarted = false; - private boolean dragStarted = false; - private boolean quickZoom = false; - private boolean scrollInProgress = false; - private boolean scaleGestureOccurred = false; - private boolean recentScaleGestureOccurred = false; + private boolean twoTap; + private boolean quickZoom; + private boolean tiltGestureOccurred; + private boolean scrollGestureOccurred; + private boolean scaleGestureOccurred; + private boolean recentScaleGestureOccurred; MapGestureDetector(Context context, Transform transform, Projection projection, UiSettings uiSettings, TrackingSettings trackingSettings, AnnotationManager annotationManager, @@ -193,10 +192,10 @@ final class MapGestureDetector { } // Scroll / Pan Has Stopped - if (scrollInProgress) { + if (scrollGestureOccurred) { MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapDragEndEvent( getLocationFromGesture(event.getX(), event.getY()), transform)); - scrollInProgress = false; + scrollGestureOccurred = false; cameraChangeDispatcher.onCameraIdle(); } @@ -393,20 +392,18 @@ final class MapGestureDetector { return false; } - if (dragStarted) { + if (tiltGestureOccurred) { return false; } - if (scaleGestureOccurred) { - return false; - } - - if (!scrollInProgress) { - scrollInProgress = true; + if (!scrollGestureOccurred) { + scrollGestureOccurred = true; // Cancel any animation - transform.cancelTransitions(); - cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); + if (!scaleGestureOccurred) { + transform.cancelTransitions(); + cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); + } MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapClickEvent( getLocationFromGesture(e1.getX(), e1.getY()), @@ -456,7 +453,6 @@ final class MapGestureDetector { scaleGestureOccurred = false; beginTime = 0; scaleFactor = 1.0f; - zoomStarted = false; cameraChangeDispatcher.onCameraIdle(); } @@ -468,27 +464,27 @@ final class MapGestureDetector { return super.onScale(detector); } - // If scale is large enough ignore a tap - scaleFactor *= detector.getScaleFactor(); - if ((scaleFactor > 1.05f) || (scaleFactor < 0.95f)) { - // notify camera change listener - cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); - zoomStarted = true; + if (tiltGestureOccurred) { + return false; } // Ignore short touches in case it is a tap // Also ignore small scales long time = detector.getEventTime(); long interval = time - beginTime; - if (!zoomStarted && (interval <= ViewConfiguration.getTapTimeout())) { + if (!scaleGestureOccurred && (interval <= ViewConfiguration.getTapTimeout())) { return false; } - if (!zoomStarted) { - return false; + // If scale is large enough ignore a tap + scaleFactor *= detector.getScaleFactor(); + if ((scaleFactor > 1.05f) || (scaleFactor < 0.95f)) { + // notify camera change listener + cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); + scaleGestureOccurred = true; } - if (dragStarted) { + if (!scaleGestureOccurred) { return false; } @@ -506,7 +502,7 @@ final class MapGestureDetector { // Scale the map if (focalPoint != null) { // arround user provided focal point - transform.zoomBy(Math.log(detector.getScaleFactor()) / Math.log(2), focalPoint.x, focalPoint.y); + transform.zoomBy(Math.log(detector.getScaleFactor()) / Math.log(Math.PI / 2), focalPoint.x, focalPoint.y); } else if (quickZoom) { cameraChangeDispatcher.onCameraMove(); // clamp scale factors we feed to core #7514 @@ -514,10 +510,12 @@ final class MapGestureDetector { MapboxConstants.MINIMUM_SCALE_FACTOR_CLAMP, MapboxConstants.MAXIMUM_SCALE_FACTOR_CLAMP); // around center map - transform.zoomBy(Math.log(scaleFactor) / Math.log(2), uiSettings.getWidth() / 2, uiSettings.getHeight() / 2); + transform.zoomBy(Math.log(scaleFactor) / Math.log(Math.PI / 2), + uiSettings.getWidth() / 2, uiSettings.getHeight() / 2); } else { // around gesture - transform.zoomBy(Math.log(detector.getScaleFactor()) / Math.log(2), detector.getFocusX(), detector.getFocusY()); + transform.zoomBy(Math.log(detector.getScaleFactor()) / Math.log(Math.PI / 2), + detector.getFocusX(), detector.getFocusY()); } return true; @@ -544,9 +542,6 @@ final class MapGestureDetector { cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); beginTime = detector.getEventTime(); - MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapClickEvent( - getLocationFromGesture(detector.getFocusX(), detector.getFocusY()), - MapboxEvent.GESTURE_ROTATION_START, transform)); return true; } @@ -563,17 +558,10 @@ final class MapGestureDetector { // Called for rotation @Override public boolean onRotate(RotateGestureDetector detector) { - if (!trackingSettings.isRotateGestureCurrentlyEnabled() || dragStarted) { + if (!trackingSettings.isRotateGestureCurrentlyEnabled() || tiltGestureOccurred) { return false; } - // If rotate is large enough ignore a tap - // Also is zoom already started, don't rotate - totalAngle += detector.getRotationDegreesDelta(); - if (totalAngle > 20.0f || totalAngle < -20.0f) { - started = true; - } - // Ignore short touches in case it is a tap // Also ignore small rotate long time = detector.getEventTime(); @@ -582,6 +570,16 @@ final class MapGestureDetector { return false; } + // If rotate is large enough ignore a tap + // Also is zoom already started, don't rotate + totalAngle += detector.getRotationDegreesDelta(); + if (totalAngle > 35.0f || totalAngle < -35.0f) { + MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapClickEvent( + getLocationFromGesture(detector.getFocusX(), detector.getFocusY()), + MapboxEvent.GESTURE_ROTATION_START, transform)); + started = true; + } + if (!started) { return false; } @@ -610,9 +608,8 @@ final class MapGestureDetector { */ private class ShoveGestureListener implements ShoveGestureDetector.OnShoveGestureListener { - long beginTime = 0; - float totalDelta = 0.0f; - boolean started = false; + private long beginTime = 0; + private float totalDelta = 0.0f; @Override public boolean onShoveBegin(ShoveGestureDetector detector) { @@ -622,10 +619,6 @@ final class MapGestureDetector { // notify camera change listener cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); - beginTime = detector.getEventTime(); - MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapClickEvent( - getLocationFromGesture(detector.getFocusX(), detector.getFocusY()), - MapboxEvent.GESTURE_PITCH_START, transform)); return true; } @@ -633,8 +626,7 @@ final class MapGestureDetector { public void onShoveEnd(ShoveGestureDetector detector) { beginTime = 0; totalDelta = 0.0f; - started = false; - dragStarted = false; + tiltGestureOccurred = false; } @Override @@ -643,22 +635,26 @@ final class MapGestureDetector { return false; } - // If tilt is large enough ignore a tap - // Also if zoom already started, don't tilt - totalDelta += detector.getShovePixelsDelta(); - if (!zoomStarted && ((totalDelta > 10.0f) || (totalDelta < -10.0f))) { - started = true; - } - // Ignore short touches in case it is a tap // Also ignore small tilt long time = detector.getEventTime(); long interval = time - beginTime; - if (!started && (interval <= ViewConfiguration.getTapTimeout())) { + if (!tiltGestureOccurred && (interval <= ViewConfiguration.getTapTimeout())) { return false; } - if (!started) { + // If tilt is large enough ignore a tap + // Also if zoom already started, don't tilt + totalDelta += detector.getShovePixelsDelta(); + if (!tiltGestureOccurred && ((totalDelta > 10.0f) || (totalDelta < -10.0f))) { + tiltGestureOccurred = true; + beginTime = detector.getEventTime(); + MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapClickEvent( + getLocationFromGesture(detector.getFocusX(), detector.getFocusY()), + MapboxEvent.GESTURE_PITCH_START, transform)); + } + + if (!tiltGestureOccurred) { return false; } @@ -669,9 +665,6 @@ final class MapGestureDetector { // Tilt the map transform.setTilt(pitch); - - dragStarted = true; - return true; } } -- cgit v1.2.1 From 00dbd033a27ff0a70196449ce7f293ff7c454f5d Mon Sep 17 00:00:00 2001 From: Tobrun Date: Mon, 17 Jul 2017 09:13:21 +0200 Subject: [android] - feature - location accuracy indicator threshold (#9472) --- .../mapbox/mapboxsdk/maps/MapboxMapOptions.java | 30 ++++++++++++++++++++++ .../mapboxsdk/maps/widgets/MyLocationView.java | 16 ++++++++++-- .../maps/widgets/MyLocationViewSettings.java | 21 +++++++++++++++ .../src/main/res/values/attrs.xml | 1 + 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java index 80b25bf0de..e2f4123e95 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java @@ -79,6 +79,7 @@ public class MapboxMapOptions implements Parcelable { private int[] myLocationBackgroundPadding; private int myLocationAccuracyTintColor; private int myLocationAccuracyAlpha; + private float myLocationAccuracyThreshold; private String apiBaseUrl; @@ -148,6 +149,7 @@ public class MapboxMapOptions implements Parcelable { myLocationBackgroundPadding = in.createIntArray(); myLocationAccuracyAlpha = in.readInt(); myLocationAccuracyTintColor = in.readInt(); + myLocationAccuracyThreshold = in.readFloat(); style = in.readString(); apiBaseUrl = in.readString(); @@ -291,6 +293,8 @@ public class MapboxMapOptions implements Parcelable { mapboxMapOptions.myLocationAccuracyTint( typedArray.getColor(R.styleable.mapbox_MapView_mapbox_myLocationAccuracyTintColor, ColorUtils.getPrimaryColor(context))); + mapboxMapOptions.myLocationAccuracyThreshold( + typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_myLocationAccuracyThreshold, 0)); mapboxMapOptions.textureMode( typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_renderTextureMode, false)); } finally { @@ -680,6 +684,17 @@ public class MapboxMapOptions implements Parcelable { return this; } + /** + * Set accuracy circle threshold. Circle won't be displayed if accuracy is below set value. + * + * @param myLocationAccuracyThreshold Value of accuracy (in meters), below which circle won't be displayed + * @return This + */ + public MapboxMapOptions myLocationAccuracyThreshold(float myLocationAccuracyThreshold) { + this.myLocationAccuracyThreshold = myLocationAccuracyThreshold; + return this; + } + /** * Enable TextureView as rendered surface. *

      @@ -987,6 +1002,15 @@ public class MapboxMapOptions implements Parcelable { return myLocationAccuracyAlpha; } + /** + * Returns current accuracy threshold value (in meters). + * + * @return Value of accuracy threshold (in meters), below which circle won't be displayed + */ + public float getMyLocationAccuracyThreshold() { + return myLocationAccuracyThreshold; + } + /** * Get the current configured debug state for a map view. * @@ -1065,6 +1089,7 @@ public class MapboxMapOptions implements Parcelable { dest.writeIntArray(myLocationBackgroundPadding); dest.writeInt(myLocationAccuracyAlpha); dest.writeInt(myLocationAccuracyTintColor); + dest.writeFloat(myLocationAccuracyThreshold); dest.writeString(style); dest.writeString(apiBaseUrl); @@ -1153,6 +1178,9 @@ public class MapboxMapOptions implements Parcelable { if (myLocationAccuracyAlpha != options.myLocationAccuracyAlpha) { return false; } + if (myLocationAccuracyThreshold != options.myLocationAccuracyThreshold) { + return false; + } if (cameraPosition != null ? !cameraPosition.equals(options.cameraPosition) : options.cameraPosition != null) { return false; } @@ -1230,6 +1258,8 @@ public class MapboxMapOptions implements Parcelable { result = 31 * result + Arrays.hashCode(myLocationBackgroundPadding); result = 31 * result + myLocationAccuracyTintColor; result = 31 * result + myLocationAccuracyAlpha; + result = 31 * result + (myLocationAccuracyThreshold != +0.0f + ? Float.floatToIntBits(myLocationAccuracyThreshold) : 0); result = 31 * result + (apiBaseUrl != null ? apiBaseUrl.hashCode() : 0); result = 31 * result + (textureMode ? 1 : 0); result = 31 * result + (style != null ? style.hashCode() : 0); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java index 24da59bb7e..017fdb353a 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java @@ -71,6 +71,7 @@ public class MyLocationView extends View { private float accuracy; private Paint accuracyPaint; + private float accuracyThreshold; private ValueAnimator locationChangeAnimator; private ValueAnimator accuracyAnimator; @@ -591,6 +592,16 @@ public class MyLocationView extends View { this.locationChangeAnimationEnabled = locationChangeAnimationEnabled; } + /** + * Set accuracy circle threshold. Circle won't be displayed if accuracy is below set value. + * For internal use only. + * + * @param accuracyThreshold Value below which circle won't be displayed + */ + public void setAccuracyThreshold(float accuracyThreshold) { + this.accuracyThreshold = accuracyThreshold; + } + /** * Set the bearing tracking mode, for internal use only. * @@ -928,10 +939,11 @@ public class MyLocationView extends View { accuracyAnimator.end(); } - accuracyAnimator = ValueAnimator.ofFloat(accuracy, location.getAccuracy()); + float newAccuracy = location.getAccuracy() >= accuracyThreshold ? location.getAccuracy() : 0f; + accuracyAnimator = ValueAnimator.ofFloat(accuracy, newAccuracy); accuracyAnimator.setDuration(750); accuracyAnimator.start(); - accuracy = location.getAccuracy(); + accuracy = newAccuracy; } abstract void invalidate(); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java index fe2f18e4dd..ea74bc57aa 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java @@ -51,6 +51,7 @@ public class MyLocationViewSettings { // private int accuracyAlpha; + private float accuracyThreshold = 0f; @ColorInt private int accuracyTintColor; @@ -93,6 +94,7 @@ public class MyLocationViewSettings { setBackgroundTintColor(options.getMyLocationBackgroundTintColor()); setAccuracyAlpha(options.getMyLocationAccuracyAlpha()); setAccuracyTintColor(options.getMyLocationAccuracyTintColor()); + setAccuracyThreshold(options.getMyLocationAccuracyThreshold()); } /** @@ -293,6 +295,25 @@ public class MyLocationViewSettings { myLocationView.setAccuracyTint(accuracyTintColor); } + /** + * Returns current accuracy threshold value (in meters). + * + * @return Value of accuracy threshold (in meters), below which circle won't be displayed + */ + public float getAccuracyThreshold() { + return accuracyThreshold; + } + + /** + * Set accuracy circle threshold. Circle won't be displayed if accuracy is below set value. + * + * @param accuracyThreshold Value of accuracy (in meters), below which circle won't be displayed + */ + public void setAccuracyThreshold(float accuracyThreshold) { + this.accuracyThreshold = accuracyThreshold; + myLocationView.setAccuracyThreshold(accuracyThreshold); + } + public void setTilt(double tilt) { myLocationView.setTilt(tilt); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml index e17f01d075..e20b640d9e 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml +++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml @@ -40,6 +40,7 @@ + -- cgit v1.2.1 From fef873f68f6cbe7970d0530b6927ed743495af75 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Fri, 14 Jul 2017 19:53:32 +0300 Subject: [build] Fix node package publish logic --- platform/node/scripts/after_success.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/node/scripts/after_success.sh b/platform/node/scripts/after_success.sh index d761d4110f..18e00a4f0d 100755 --- a/platform/node/scripts/after_success.sh +++ b/platform/node/scripts/after_success.sh @@ -3,7 +3,7 @@ set -e set -o pipefail -if [[ -n ${PUBLISH:-} ]]; then +if [[ "${PUBLISH:-}" == true ]]; then if [[ "${BUILDTYPE}" == "RelWithDebInfo" ]]; then ./node_modules/.bin/node-pre-gyp package publish info elif [[ "${BUILDTYPE}" == "Debug" ]]; then -- cgit v1.2.1 From 6b954677c0e57b1c1b8201210aa31d956d79c9f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Fri, 14 Jul 2017 12:00:53 +0200 Subject: [core] fix undefined behavior for division through 0 --- src/mbgl/text/collision_feature.cpp | 2 +- src/mbgl/text/collision_tile.cpp | 25 ++++++++++++++++--------- src/mbgl/util/math.hpp | 13 +++++++++++++ 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/mbgl/text/collision_feature.cpp b/src/mbgl/text/collision_feature.cpp index 022ee50644..3eb08da8d1 100644 --- a/src/mbgl/text/collision_feature.cpp +++ b/src/mbgl/text/collision_feature.cpp @@ -135,7 +135,7 @@ void CollisionFeature::bboxifyLabel(const GeometryCoordinates& line, GeometryCoo // This makes our calculation spot-on at scale=2, and on the conservative side for // lower scales const float distanceToInnerEdge = std::max(std::fabs(boxDistanceToAnchor - firstBoxOffset) - step / 2, 0.0f); - float maxScale = labelLength / 2 / distanceToInnerEdge; + float maxScale = util::division(labelLength / 2, distanceToInnerEdge, std::numeric_limits::infinity()); // The box maxScale calculations are designed to be conservative on collisions in the scale range // [1,2]. At scale=1, each box has 50% overlap, and at scale=2, the boxes are lined up edge diff --git a/src/mbgl/text/collision_tile.cpp b/src/mbgl/text/collision_tile.cpp index b3fbe6f8a3..cc9b602f08 100644 --- a/src/mbgl/text/collision_tile.cpp +++ b/src/mbgl/text/collision_tile.cpp @@ -20,7 +20,11 @@ CollisionTile::CollisionTile(PlacementConfig config_) : config(std::move(config_ rotationMatrix = { { angle_cos, -angle_sin, angle_sin, angle_cos } }; reverseRotationMatrix = { { angle_cos, angle_sin, -angle_sin, angle_cos } }; - perspectiveRatio = 1.0f + 0.5f * ((config.cameraToTileDistance / config.cameraToCenterDistance) - 1.0f); + perspectiveRatio = + 1.0f + + 0.5f * (util::division(config.cameraToTileDistance, config.cameraToCenterDistance, 1.0f) - + 1.0f); + minScale /= perspectiveRatio; maxScale /= perspectiveRatio; @@ -30,22 +34,25 @@ CollisionTile::CollisionTile(PlacementConfig config_) : config(std::move(config_ // purposes, but we still want to use the yStretch approximation // here because we can't adjust the aspect ratio of the collision // boxes at render time. - yStretch = util::max(1.0f, config.cameraToTileDistance / (config.cameraToCenterDistance * std::cos(config.pitch))); + yStretch = util::max( + 1.0f, util::division(config.cameraToTileDistance, + config.cameraToCenterDistance * std::cos(config.pitch), 1.0f)); } - float CollisionTile::findPlacementScale(const Point& anchor, const CollisionBox& box, const float boxMaxScale, const Point& blockingAnchor, const CollisionBox& blocking) { float minPlacementScale = minScale; // Find the lowest scale at which the two boxes can fit side by side without overlapping. // Original algorithm: - float s1 = (blocking.x1 - box.x2) / (anchor.x - blockingAnchor.x); // scale at which new box is to the left of old box - float s2 = (blocking.x2 - box.x1) / (anchor.x - blockingAnchor.x); // scale at which new box is to the right of old box - float s3 = (blocking.y1 - box.y2) * yStretch / (anchor.y - blockingAnchor.y); // scale at which new box is to the top of old box - float s4 = (blocking.y2 - box.y1) * yStretch / (anchor.y - blockingAnchor.y); // scale at which new box is to the bottom of old box - if (std::isnan(s1) || std::isnan(s2)) s1 = s2 = 1; - if (std::isnan(s3) || std::isnan(s4)) s3 = s4 = 1; + const float s1 = util::division(blocking.x1 - box.x2, anchor.x - blockingAnchor.x, + 1.0f); // scale at which new box is to the left of old box + const float s2 = util::division(blocking.x2 - box.x1, anchor.x - blockingAnchor.x, + 1.0f); // scale at which new box is to the right of old box + const float s3 = util::division((blocking.y1 - box.y2) * yStretch, anchor.y - blockingAnchor.y, + 1.0f); // scale at which new box is to the top of old box + const float s4 = util::division((blocking.y2 - box.y1) * yStretch, anchor.y - blockingAnchor.y, + 1.0f); // scale at which new box is to the bottom of old box float collisionFreeScale = util::min(util::max(s1, s2), util::max(s3, s4)); diff --git a/src/mbgl/util/math.hpp b/src/mbgl/util/math.hpp index f969ecaedd..eb3c7d0fde 100644 --- a/src/mbgl/util/math.hpp +++ b/src/mbgl/util/math.hpp @@ -106,5 +106,18 @@ T smoothstep(T edge0, T edge1, T x) { return t * t * (T(3) - T(2) * t); } +template +inline T division(const T dividend, const T divisor, const T nan) { + if (divisor == 0) { + if (dividend == 0) { + return nan; + } else { + return std::copysign(std::numeric_limits::infinity(), dividend); + } + } else { + return dividend / divisor; + } +} + } // namespace util } // namespace mbgl -- cgit v1.2.1 From fdfd5f91f51f7185f731783ad8b2b4ff9c3e2f90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Fri, 14 Jul 2017 15:30:27 +0200 Subject: [core] abort early when the dimension is 0 --- src/mbgl/map/transform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp index 50f979437d..ab10b21cc1 100644 --- a/src/mbgl/map/transform.cpp +++ b/src/mbgl/map/transform.cpp @@ -168,7 +168,7 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima double angle = camera.angle.value_or(getAngle()); double pitch = camera.pitch.value_or(getPitch()); - if (std::isnan(zoom)) { + if (std::isnan(zoom) || state.size.isEmpty()) { return; } -- cgit v1.2.1 From d9ad09ca364df52a316f644f908b7bb493093b48 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Fri, 14 Jul 2017 16:39:42 +0300 Subject: [Qt] Align database creation behavior with the default implementation Qt doesn't throw a Exception::Code::CANTOPEN when trying to open a database that doesn't exist without the Create flag. --- platform/qt/src/sqlite3.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/platform/qt/src/sqlite3.cpp b/platform/qt/src/sqlite3.cpp index 8df279c25d..6ed55c541f 100644 --- a/platform/qt/src/sqlite3.cpp +++ b/platform/qt/src/sqlite3.cpp @@ -50,6 +50,15 @@ void checkDatabaseError(const QSqlDatabase &db) { } } +void checkDatabaseOpenError(const QSqlDatabase &db) { + // Assume every error when opening the data as CANTOPEN. Qt + // always returns -1 for `nativeErrorCode()` on database errors. + QSqlError lastError = db.lastError(); + if (lastError.type() != QSqlError::NoError) { + throw Exception { Exception::Code::CANTOPEN, "Error opening the database." }; + } +} + class DatabaseImpl { public: DatabaseImpl(const char* filename, int flags) { @@ -77,7 +86,7 @@ public: db->setDatabaseName(QString(filename)); if (!db->open()) { - checkDatabaseError(*db); + checkDatabaseOpenError(*db); } } @@ -143,7 +152,7 @@ void Database::setBusyTimeout(std::chrono::milliseconds timeout) { } impl->db->setConnectOptions(connectOptions); if (!impl->db->open()) { - checkDatabaseError(*impl->db); + checkDatabaseOpenError(*impl->db); } } -- cgit v1.2.1 From 544d875445d80ae34317c13e31a33d9e80385b8f Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Fri, 14 Jul 2017 16:52:48 +0300 Subject: [tests] Add test to enforce database not found behavior Make sure all the implementations, currently Qt and Default, throw an exception with error code CANTOPEN when opening a database that doesn't exist without the CREATE flag. --- test/storage/sqlite.test.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/storage/sqlite.test.cpp b/test/storage/sqlite.test.cpp index dbd7a09868..36715a2fd0 100644 --- a/test/storage/sqlite.test.cpp +++ b/test/storage/sqlite.test.cpp @@ -25,3 +25,14 @@ TEST(SQLite, Statement) { ASSERT_EQ(stmt2.lastInsertRowId(), 2); ASSERT_EQ(stmt2.changes(), 1u); } + +TEST(SQLite, TEST_REQUIRES_WRITE(CantOpenException)) { + try { + // Should throw a CANTOPEN when the database doesn't exist, + // make sure all the backends behave the same way. + mapbox::sqlite::Database("test/fixtures/offline_database/foobar123.db", mapbox::sqlite::ReadOnly); + FAIL(); + } catch (mapbox::sqlite::Exception& ex) { + ASSERT_EQ(ex.code, mapbox::sqlite::Exception::Code::CANTOPEN); + } +} -- cgit v1.2.1 From ccb525553786e11fbb76af2caf931ba539713761 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 13 Jun 2017 16:04:13 -0700 Subject: [core] Don't use "current" icon/text-size when binding The current value is not passed to `SymbolSizeBinder::uniformValues`, so we shouldn't check `currentValue.isConstant()` in `SymbolSizeBinder::attributeBindings`. If it were true, then we might end up using attribute bindings that are appropriate only for a constant property, but uniform bindings that are appropriate only for a source or composite function. Instead, just wait for a new bucket to be generated. This will happen automatically, since icon/text-size are layout properties. --- src/mbgl/programs/symbol_program.hpp | 21 +++++---------------- src/mbgl/renderer/painter_symbol.cpp | 1 - 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index 01e95f456d..abcba1d033 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -107,7 +107,7 @@ public: const style::DataDrivenPropertyValue& sizeProperty, const float defaultValue); - virtual SymbolSizeAttributes::Bindings attributeBindings(const PossiblyEvaluatedPropertyValue currentValue) const = 0; + virtual SymbolSizeAttributes::Bindings attributeBindings() const = 0; virtual void populateVertexVector(const GeometryTileFeature& feature) = 0; virtual UniformValues uniformValues(float currentZoom) const = 0; virtual void upload(gl::Context&) = 0; @@ -133,8 +133,6 @@ Range getCoveringStops(Stops s, float lowerZoom, float upperZoom) { class ConstantSymbolSizeBinder final : public SymbolSizeBinder { public: - using PropertyValue = variant>; - ConstantSymbolSizeBinder(const float /*tileZoom*/, const float& size, const float /*defaultValue*/) : layoutSize(size) {} @@ -157,7 +155,7 @@ public: ); } - SymbolSizeAttributes::Bindings attributeBindings(const PossiblyEvaluatedPropertyValue) const override { + SymbolSizeAttributes::Bindings attributeBindings() const override { return SymbolSizeAttributes::Bindings { SymbolSizeAttributes::Attribute::ConstantBinding {{{0, 0, 0}}} }; } void upload(gl::Context&) override {} @@ -211,11 +209,7 @@ public: defaultValue(defaultValue_) { } - SymbolSizeAttributes::Bindings attributeBindings(const PossiblyEvaluatedPropertyValue currentValue) const override { - if (currentValue.isConstant()) { - return SymbolSizeAttributes::Bindings { SymbolSizeAttributes::Attribute::ConstantBinding {{{0, 0, 0}}} }; - } - + SymbolSizeAttributes::Bindings attributeBindings() const override { return SymbolSizeAttributes::Bindings { SymbolSizeAttributes::Attribute::variableBinding(*buffer, 0, 1) }; } @@ -268,11 +262,7 @@ public: return getCoveringStops(stops, tileZoom, tileZoom + 1); })) {} - SymbolSizeAttributes::Bindings attributeBindings(const PossiblyEvaluatedPropertyValue currentValue) const override { - if (currentValue.isConstant()) { - return SymbolSizeAttributes::Bindings { SymbolSizeAttributes::Attribute::ConstantBinding {{{0, 0, 0}}} }; - } - + SymbolSizeAttributes::Bindings attributeBindings() const override { return SymbolSizeAttributes::Bindings { SymbolSizeAttributes::Attribute::variableBinding(*buffer, 0) }; } @@ -364,7 +354,6 @@ public: UniformValues&& uniformValues, const gl::VertexBuffer& layoutVertexBuffer, const SymbolSizeBinder& symbolSizeBinder, - const PossiblyEvaluatedPropertyValue& currentSizeValue, const gl::IndexBuffer& indexBuffer, const gl::SegmentVector& segments, const PaintPropertyBinders& paintPropertyBinders, @@ -380,7 +369,7 @@ public: .concat(symbolSizeBinder.uniformValues(currentZoom)) .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)), LayoutAttributes::allVariableBindings(layoutVertexBuffer) - .concat(symbolSizeBinder.attributeBindings(currentSizeValue)) + .concat(symbolSizeBinder.attributeBindings()) .concat(paintPropertyBinders.attributeBindings(currentProperties)), indexBuffer, segments diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp index 86b2146b9f..c9ed8cc570 100644 --- a/src/mbgl/renderer/painter_symbol.cpp +++ b/src/mbgl/renderer/painter_symbol.cpp @@ -54,7 +54,6 @@ void Painter::renderSymbol(PaintParameters& parameters, std::move(uniformValues), *buffers.vertexBuffer, *symbolSizeBinder, - values_.layoutSize, *buffers.indexBuffer, buffers.segments, binders, -- cgit v1.2.1 From 874244a65680c4f99b1b549b979e511f37c1542b Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 13 Jun 2017 16:45:12 -0700 Subject: [core] Eliminate constant attribute bindings Rather than binding constant attributes that will never be used, just disable the attribute. --- src/mbgl/gl/attribute.cpp | 176 ++++------------------------ src/mbgl/gl/attribute.hpp | 89 ++++++-------- src/mbgl/gl/segment.hpp | 6 +- src/mbgl/programs/program.hpp | 2 +- src/mbgl/programs/symbol_program.hpp | 11 +- src/mbgl/renderer/paint_property_binder.hpp | 21 +--- 6 files changed, 76 insertions(+), 229 deletions(-) diff --git a/src/mbgl/gl/attribute.cpp b/src/mbgl/gl/attribute.cpp index 8c52121f6e..e05ca75866 100644 --- a/src/mbgl/gl/attribute.cpp +++ b/src/mbgl/gl/attribute.cpp @@ -10,6 +10,10 @@ AttributeLocation bindAttributeLocation(ProgramID id, AttributeLocation location return location; } +void DisabledAttribute::bind(Context&, AttributeLocation location, std::size_t) const { + MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); +} + template DataType DataTypeOf = static_cast(0); template <> DataType DataTypeOf< int8_t> = DataType::Byte; template <> DataType DataTypeOf = DataType::UnsignedByte; @@ -20,16 +24,9 @@ template <> DataType DataTypeOf = DataType::UnsignedInteger; template <> DataType DataTypeOf = DataType::Float; template -void VariableAttributeBinding::bind(Context& context, - AttributeLocation location, - optional>& oldBinding, - std::size_t vertexOffset) const { - if (oldBinding == *this) { - return; - } +void AttributeBinding::bind(Context& context, AttributeLocation location, std::size_t vertexOffset) const { context.vertexBuffer = vertexBuffer; MBGL_CHECK_ERROR(glEnableVertexAttribArray(location)); - oldBinding = *this; MBGL_CHECK_ERROR(glVertexAttribPointer( location, static_cast(attributeSize), @@ -39,156 +36,25 @@ void VariableAttributeBinding::bind(Context& context, reinterpret_cast(attributeOffset + (vertexSize * vertexOffset)))); } -template class VariableAttributeBinding; -template class VariableAttributeBinding; -template class VariableAttributeBinding; -template class VariableAttributeBinding; - -template class VariableAttributeBinding; -template class VariableAttributeBinding; -template class VariableAttributeBinding; -template class VariableAttributeBinding; - -template class VariableAttributeBinding; -template class VariableAttributeBinding; -template class VariableAttributeBinding; -template class VariableAttributeBinding; - -template class VariableAttributeBinding; -template class VariableAttributeBinding; -template class VariableAttributeBinding; -template class VariableAttributeBinding; - -template <> -void ConstantAttributeBinding::bind(Context&, AttributeLocation location, optional>& oldBinding, std::size_t) const { - assert(location != 0); - oldBinding = {}; - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttrib1f(location, value[0])); -} - -template <> -void ConstantAttributeBinding::bind(Context&, AttributeLocation location, optional>& oldBinding, std::size_t) const { - assert(location != 0); - oldBinding = {}; - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttrib2f(location, value[0], value[1])); -} - -template <> -void ConstantAttributeBinding::bind(Context&, AttributeLocation location, optional>& oldBinding, std::size_t) const { - assert(location != 0); - oldBinding = {}; - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttrib3f(location, value[0], value[1], value[2])); -} - -template <> -void ConstantAttributeBinding::bind(Context&, AttributeLocation location, optional>& oldBinding, std::size_t) const { - assert(location != 0); - oldBinding = {}; - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttrib4f(location, value[0], value[1], value[2], value[3])); -} - - -template <> -void ConstantAttributeBinding::bind(Context&, AttributeLocation location, optional>& oldBinding, std::size_t) const { - assert(location != 0); - oldBinding = {}; - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttrib1f(location, value[0])); -} - -template <> -void ConstantAttributeBinding::bind(Context&, AttributeLocation location, optional>& oldBinding, std::size_t) const { - assert(location != 0); - oldBinding = {}; - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttrib2f(location, value[0], value[1])); -} - -template <> -void ConstantAttributeBinding::bind(Context&, AttributeLocation location, optional>& oldBinding, std::size_t) const { - assert(location != 0); - oldBinding = {}; - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttrib3f(location, value[0], value[1], value[2])); -} - -template <> -void ConstantAttributeBinding::bind(Context&, AttributeLocation location, optional>& oldBinding, std::size_t) const { - assert(location != 0); - oldBinding = {}; - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttrib4f(location, value[0], value[1], value[2], value[3])); -} - - -template <> -void ConstantAttributeBinding::bind(Context&, AttributeLocation location, optional>& oldBinding, std::size_t) const { - assert(location != 0); - oldBinding = {}; - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttrib1f(location, value[0])); -} +template class AttributeBinding; +template class AttributeBinding; +template class AttributeBinding; +template class AttributeBinding; -template <> -void ConstantAttributeBinding::bind(Context&, AttributeLocation location, optional>& oldBinding, std::size_t) const { - assert(location != 0); - oldBinding = {}; - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttrib2f(location, value[0], value[1])); -} +template class AttributeBinding; +template class AttributeBinding; +template class AttributeBinding; +template class AttributeBinding; -template <> -void ConstantAttributeBinding::bind(Context&, AttributeLocation location, optional>& oldBinding, std::size_t) const { - assert(location != 0); - oldBinding = {}; - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttrib3f(location, value[0], value[1], value[2])); -} +template class AttributeBinding; +template class AttributeBinding; +template class AttributeBinding; +template class AttributeBinding; -template <> -void ConstantAttributeBinding::bind(Context&, AttributeLocation location, optional>& oldBinding, std::size_t) const { - assert(location != 0); - oldBinding = {}; - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttrib4f(location, value[0], value[1], value[2], value[3])); -} - - -template <> -void ConstantAttributeBinding::bind(Context&, AttributeLocation location, optional>& oldBinding, std::size_t) const { - assert(location != 0); - oldBinding = {}; - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttrib1f(location, value[0])); -} - -template <> -void ConstantAttributeBinding::bind(Context&, AttributeLocation location, optional>& oldBinding, std::size_t) const { - assert(location != 0); - oldBinding = {}; - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttrib2f(location, value[0], value[1])); -} - -template <> -void ConstantAttributeBinding::bind(Context&, AttributeLocation location, optional>& oldBinding, std::size_t) const { - assert(location != 0); - oldBinding = {}; - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttrib3f(location, value[0], value[1], value[2])); -} - -template <> -void ConstantAttributeBinding::bind(Context&, AttributeLocation location, optional>& oldBinding, std::size_t) const { - assert(location != 0); - oldBinding = {}; - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttrib4f(location, value[0], value[1], value[2], value[3])); -} +template class AttributeBinding; +template class AttributeBinding; +template class AttributeBinding; +template class AttributeBinding; } // namespace gl } // namespace mbgl diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp index d5e8edfc70..48222146fa 100644 --- a/src/mbgl/gl/attribute.hpp +++ b/src/mbgl/gl/attribute.hpp @@ -13,23 +13,33 @@ namespace mbgl { namespace gl { +class DisabledAttribute { +public: + void bind(Context&, AttributeLocation, std::size_t vertexOffset) const; + + friend bool operator==(const DisabledAttribute&, + const DisabledAttribute&) { + return true; + } +}; + template -class VariableAttributeBinding { +class AttributeBinding { public: - VariableAttributeBinding(BufferID vertexBuffer_, - std::size_t vertexSize_, - std::size_t attributeOffset_, - std::size_t attributeSize_ = N) + AttributeBinding(BufferID vertexBuffer_, + std::size_t vertexSize_, + std::size_t attributeOffset_, + std::size_t attributeSize_ = N) : vertexBuffer(vertexBuffer_), vertexSize(vertexSize_), attributeOffset(attributeOffset_), attributeSize(attributeSize_) {} - void bind(Context&, AttributeLocation, optional>&, std::size_t vertexOffset) const; + void bind(Context&, AttributeLocation, std::size_t vertexOffset) const; - friend bool operator==(const VariableAttributeBinding& lhs, - const VariableAttributeBinding& rhs) { + friend bool operator==(const AttributeBinding& lhs, + const AttributeBinding& rhs) { return lhs.vertexBuffer == rhs.vertexBuffer && lhs.vertexSize == rhs.vertexSize && lhs.attributeOffset == rhs.attributeOffset @@ -43,28 +53,8 @@ private: std::size_t attributeSize; }; -template -class ConstantAttributeBinding { -public: - ConstantAttributeBinding() { value.fill(T()); } - - explicit ConstantAttributeBinding(std::array value_) - : value(std::move(value_)) - {} - - void bind(Context&, AttributeLocation, optional>&, std::size_t) const; - - friend bool operator==(const ConstantAttributeBinding& lhs, - const ConstantAttributeBinding& rhs) { - return lhs.value == rhs.value; - } - -private: - std::array value; -}; - /* - gl::Attribute manages the binding of a constant value or vertex buffer to a GL program attribute. + gl::Attribute manages the binding of a vertex buffer to a GL program attribute. - T is the underlying primitive type (exposed as Attribute::ValueType) - N is the number of components in the attribute declared in the shader (exposed as Attribute::Dimensions) */ @@ -75,27 +65,23 @@ public: static constexpr size_t Dimensions = N; using Value = std::array; - using VariableBinding = VariableAttributeBinding; - using ConstantBinding = ConstantAttributeBinding; - using Location = AttributeLocation; using Binding = variant< - ConstantBinding, - VariableBinding>; + DisabledAttribute, + AttributeBinding>; /* - Create a variable (i.e. data-driven) binding for this attribute. The `attributeSize` - parameter may be used to override the number of components available in the buffer for - each vertex. Thus, a buffer with only one float for each vertex can be bound to a - `vec2` attribute + Create a binding for this attribute. The `attributeSize` parameter may be used to + override the number of components available in the buffer for each vertex. Thus, + a buffer with only one float for each vertex can be bound to a `vec2` attribute */ template - static VariableBinding variableBinding(const VertexBuffer& buffer, - std::size_t attributeIndex, - std::size_t attributeSize = N) { + static Binding binding(const VertexBuffer& buffer, + std::size_t attributeIndex, + std::size_t attributeSize = N) { static_assert(std::is_standard_layout::value, "vertex type must use standard layout"); - return VariableBinding { + return AttributeBinding { buffer.buffer, sizeof(Vertex), Vertex::attributeOffsets[attributeIndex], @@ -105,12 +91,18 @@ public: static void bind(Context& context, const Location& location, - optional& oldBinding, + Binding& oldBinding, const Binding& newBinding, std::size_t vertexOffset) { + if (oldBinding == newBinding) { + return; + } + Binding::visit(newBinding, [&] (const auto& binding) { - binding.bind(context, location, oldBinding, vertexOffset); + binding.bind(context, location, vertexOffset); }); + + oldBinding = newBinding; } }; @@ -242,9 +234,6 @@ public: using Bindings = IndexedTuple< TypeList, TypeList>; - using VariableBindings = IndexedTuple< - TypeList, - TypeList...>>; using NamedLocations = std::vector>; using Vertex = detail::Vertex; @@ -266,13 +255,13 @@ public: } template - static Bindings allVariableBindings(const VertexBuffer& buffer) { - return Bindings { As::Type::variableBinding(buffer, Index)... }; + static Bindings bindings(const VertexBuffer& buffer) { + return Bindings { As::Type::binding(buffer, Index)... }; } static void bind(Context& context, const Locations& locations, - VariableBindings& oldBindings, + Bindings& oldBindings, const Bindings& newBindings, std::size_t vertexOffset) { util::ignore({ (As::Type::bind(context, diff --git a/src/mbgl/gl/segment.hpp b/src/mbgl/gl/segment.hpp index 45c81973f2..fe0658bf8e 100644 --- a/src/mbgl/gl/segment.hpp +++ b/src/mbgl/gl/segment.hpp @@ -47,12 +47,12 @@ public: } else { // No VAO support. Force attributes to be rebound. context.elementBuffer = indexBuffer_; - variableBindings = {}; + attributeBindings = {}; } Attributes::bind(context, attributeLocations, - variableBindings, + attributeBindings, attributeBindings_, vertexOffset); } @@ -60,7 +60,7 @@ public: private: mutable optional vao; mutable optional indexBuffer; - mutable typename Attributes::VariableBindings variableBindings; + mutable typename Attributes::Bindings attributeBindings; }; template diff --git a/src/mbgl/programs/program.hpp b/src/mbgl/programs/program.hpp index bbe4885745..65f17e5bdc 100644 --- a/src/mbgl/programs/program.hpp +++ b/src/mbgl/programs/program.hpp @@ -66,7 +66,7 @@ public: std::move(colorMode), uniformValues .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)), - LayoutAttributes::allVariableBindings(layoutVertexBuffer) + LayoutAttributes::bindings(layoutVertexBuffer) .concat(paintPropertyBinders.attributeBindings(currentProperties)), indexBuffer, segments diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index abcba1d033..47d92f912c 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -156,8 +156,9 @@ public: } SymbolSizeAttributes::Bindings attributeBindings() const override { - return SymbolSizeAttributes::Bindings { SymbolSizeAttributes::Attribute::ConstantBinding {{{0, 0, 0}}} }; + return SymbolSizeAttributes::Bindings { gl::DisabledAttribute() }; } + void upload(gl::Context&) override {} void populateVertexVector(const GeometryTileFeature&) override {}; @@ -210,9 +211,9 @@ public: } SymbolSizeAttributes::Bindings attributeBindings() const override { - return SymbolSizeAttributes::Bindings { SymbolSizeAttributes::Attribute::variableBinding(*buffer, 0, 1) }; + return SymbolSizeAttributes::Bindings { SymbolSizeAttributes::Attribute::binding(*buffer, 0, 1) }; } - + void populateVertexVector(const GeometryTileFeature& feature) override { const auto sizeVertex = Vertex { {{ @@ -263,7 +264,7 @@ public: {} SymbolSizeAttributes::Bindings attributeBindings() const override { - return SymbolSizeAttributes::Bindings { SymbolSizeAttributes::Attribute::variableBinding(*buffer, 0) }; + return SymbolSizeAttributes::Bindings { SymbolSizeAttributes::Attribute::binding(*buffer, 0) }; } void populateVertexVector(const GeometryTileFeature& feature) override { @@ -368,7 +369,7 @@ public: uniformValues .concat(symbolSizeBinder.uniformValues(currentZoom)) .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)), - LayoutAttributes::allVariableBindings(layoutVertexBuffer) + LayoutAttributes::bindings(layoutVertexBuffer) .concat(symbolSizeBinder.attributeBindings()) .concat(paintPropertyBinders.attributeBindings(currentProperties)), indexBuffer, diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp index bcbc7c287d..906a2ea07b 100644 --- a/src/mbgl/renderer/paint_property_binder.hpp +++ b/src/mbgl/renderer/paint_property_binder.hpp @@ -102,11 +102,8 @@ public: void populateVertexVector(const GeometryTileFeature&, std::size_t) override {} void upload(gl::Context&) override {} - AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const override { - auto value = attributeValue(currentValue.constantOr(constant)); - return typename Attribute::ConstantBinding { - zoomInterpolatedAttributeValue(value, value) - }; + AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue&) const override { + return gl::DisabledAttribute(); } float interpolationFactor(float) const override { @@ -151,12 +148,9 @@ public: AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const override { if (currentValue.isConstant()) { - BaseAttributeValue value = attributeValue(*currentValue.constant()); - return typename Attribute::ConstantBinding { - zoomInterpolatedAttributeValue(value, value) - }; + return gl::DisabledAttribute(); } else { - return Attribute::variableBinding(*vertexBuffer, 0, BaseAttribute::Dimensions); + return Attribute::binding(*vertexBuffer, 0, BaseAttribute::Dimensions); } } @@ -215,12 +209,9 @@ public: AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const override { if (currentValue.isConstant()) { - BaseAttributeValue value = attributeValue(*currentValue.constant()); - return typename Attribute::ConstantBinding { - zoomInterpolatedAttributeValue(value, value) - }; + return gl::DisabledAttribute(); } else { - return Attribute::variableBinding(*vertexBuffer, 0); + return Attribute::binding(*vertexBuffer, 0); } } -- cgit v1.2.1 From e8272ebdbb6e4788e82e4c4555f8ef8225d4013c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Wed, 14 Jun 2017 13:07:32 +0200 Subject: [core] rename a_gap_width => a_gapwidth, u_gap_width => u_gapwidth to reflect naming in the shader not sure how this ever worked --- src/mbgl/programs/attributes.hpp | 2 +- src/mbgl/programs/uniforms.hpp | 2 +- src/mbgl/style/layers/line_layer_properties.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mbgl/programs/attributes.hpp b/src/mbgl/programs/attributes.hpp index cfd6a629de..a0b2b93e16 100644 --- a/src/mbgl/programs/attributes.hpp +++ b/src/mbgl/programs/attributes.hpp @@ -106,7 +106,7 @@ struct a_base { using Type = gl::Attribute; }; -struct a_gap_width { +struct a_gapwidth { static auto name() { return "a_gapwidth"; } using Type = gl::Attribute; }; diff --git a/src/mbgl/programs/uniforms.hpp b/src/mbgl/programs/uniforms.hpp index 60a50a7cb2..32d857a94e 100644 --- a/src/mbgl/programs/uniforms.hpp +++ b/src/mbgl/programs/uniforms.hpp @@ -27,7 +27,7 @@ MBGL_DEFINE_UNIFORM_SCALAR(float, u_halo_blur); MBGL_DEFINE_UNIFORM_SCALAR(Color, u_outline_color); MBGL_DEFINE_UNIFORM_SCALAR(float, u_height); MBGL_DEFINE_UNIFORM_SCALAR(float, u_base); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_gap_width); +MBGL_DEFINE_UNIFORM_SCALAR(float, u_gapwidth); MBGL_DEFINE_UNIFORM_SCALAR(float, u_offset); MBGL_DEFINE_UNIFORM_SCALAR(Size, u_world); diff --git a/src/mbgl/style/layers/line_layer_properties.hpp b/src/mbgl/style/layers/line_layer_properties.hpp index 0b234921ad..6c301e6a0e 100644 --- a/src/mbgl/style/layers/line_layer_properties.hpp +++ b/src/mbgl/style/layers/line_layer_properties.hpp @@ -51,7 +51,7 @@ struct LineWidth : PaintProperty { static float defaultValue() { return 1; } }; -struct LineGapWidth : DataDrivenPaintProperty { +struct LineGapWidth : DataDrivenPaintProperty { static float defaultValue() { return 0; } }; -- cgit v1.2.1 From eed89fcf9d099266aa793375ad63493e880f8a80 Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Thu, 29 Jun 2017 11:29:48 -0700 Subject: [core] Bind only active attributes in order to avoid exceeding attribute limits (#9373) Introducing two new attributes to enable property functions for line-width (#9250) pushed the attribute count over GL_MAX_VERTEX_ATTRIBS on some devices. Now we selectively bind only attributes that are used, making it unlikely to surpass GL_MAX_VERTEX_ATTRIBS. --- src/mbgl/gl/attribute.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/mbgl/gl/attribute.hpp | 12 +++++++++++- src/mbgl/gl/program.hpp | 12 +++++++----- 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/src/mbgl/gl/attribute.cpp b/src/mbgl/gl/attribute.cpp index e05ca75866..4e6f78e689 100644 --- a/src/mbgl/gl/attribute.cpp +++ b/src/mbgl/gl/attribute.cpp @@ -2,14 +2,55 @@ #include #include +#include + namespace mbgl { namespace gl { AttributeLocation bindAttributeLocation(ProgramID id, AttributeLocation location, const char* name) { + assert(location < 8); MBGL_CHECK_ERROR(glBindAttribLocation(id, location, name)); return location; } +int32_t getActiveAttributeCount(ProgramID id) { + GLint numAttributes; + MBGL_CHECK_ERROR(glGetProgramiv(id, GL_ACTIVE_ATTRIBUTES, &numAttributes)); + return numAttributes; +} + +int32_t getMaxAttributeNameLength(ProgramID id) { + GLint nameLength; + MBGL_CHECK_ERROR(glGetProgramiv(id, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &nameLength)); + return nameLength; +} + +std::string getAttributeName(ProgramID id, int32_t maxLength, AttributeLocation location) { + std::string attributeName; + attributeName.resize(maxLength); + GLsizei actualLength; + GLint size; + GLenum type; + MBGL_CHECK_ERROR(glGetActiveAttrib(id, static_cast(location), + static_cast(maxLength), &actualLength, &size, &type, + const_cast(attributeName.data()))); + attributeName.resize(actualLength); + return attributeName; +} + +std::set getActiveAttributes(ProgramID id) { + std::set activeAttributes; + + GLint attributeCount = getActiveAttributeCount(id); + GLint maxAttributeLength = getMaxAttributeNameLength(id); + + for (int32_t i = 0; i < attributeCount; i++) { + activeAttributes.emplace(getAttributeName(id, maxAttributeLength, i)); + } + + return activeAttributes; +} + void DisabledAttribute::bind(Context&, AttributeLocation location, std::size_t) const { MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); } @@ -25,6 +66,11 @@ template <> DataType DataTypeOf = DataType::Float; template void AttributeBinding::bind(Context& context, AttributeLocation location, std::size_t vertexOffset) const { + // FillProgram will attempt to bind at location -1 because it includes + // a fill-outline-color paint property but does not use it or have an + // a_outline_color shader attribute - in this case, we have nothing to bind. + if (location == -1) return; + context.vertexBuffer = vertexBuffer; MBGL_CHECK_ERROR(glEnableVertexAttribArray(location)); MBGL_CHECK_ERROR(glVertexAttribPointer( diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp index 48222146fa..f018a1d261 100644 --- a/src/mbgl/gl/attribute.hpp +++ b/src/mbgl/gl/attribute.hpp @@ -8,6 +8,7 @@ #include #include +#include #include namespace mbgl { @@ -223,6 +224,7 @@ const std::size_t Vertex::attributeOffsets[5] = { } // namespace detail AttributeLocation bindAttributeLocation(ProgramID, AttributeLocation, const char * name); +std::set getActiveAttributes(ProgramID); template class Attributes { @@ -242,7 +244,15 @@ public: static constexpr std::size_t Index = TypeIndex::value; static Locations bindLocations(const ProgramID& id) { - return Locations { bindAttributeLocation(id, Index, As::name())... }; + std::set activeAttributes = getActiveAttributes(id); + + AttributeLocation location = -1; + auto bindAndIncrement = [&](const char* name) { + location++; + return bindAttributeLocation(id, location, name); + }; + return Locations{ (activeAttributes.count(As::name()) ? bindAndIncrement(As::name()) + : -1)... }; } template diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp index 47ad39de7c..583d53e4ec 100644 --- a/src/mbgl/gl/program.hpp +++ b/src/mbgl/gl/program.hpp @@ -33,15 +33,17 @@ public: : program( context.createProgram(context.createShader(ShaderType::Vertex, vertexSource), context.createShader(ShaderType::Fragment, fragmentSource))), - attributeLocations(Attributes::bindLocations(program)), - uniformsState((context.linkProgram(program), Uniforms::bindLocations(program))) { + uniformsState((context.linkProgram(program), Uniforms::bindLocations(program))), + attributeLocations(Attributes::bindLocations(program)) { + // Re-link program after manually binding only active attributes in Attributes::bindLocations + context.linkProgram(program); } template Program(Context& context, const BinaryProgram& binaryProgram) : program(context.createProgram(binaryProgram.format(), binaryProgram.code())), - attributeLocations(Attributes::loadNamedLocations(binaryProgram)), - uniformsState(Uniforms::loadNamedLocations(binaryProgram)) { + uniformsState(Uniforms::loadNamedLocations(binaryProgram)), + attributeLocations(Attributes::loadNamedLocations(binaryProgram)) { } static Program createProgram(gl::Context& context, @@ -144,8 +146,8 @@ public: private: UniqueProgram program; - typename Attributes::Locations attributeLocations; typename Uniforms::State uniformsState; + typename Attributes::Locations attributeLocations; }; } // namespace gl -- cgit v1.2.1 From f9fe0de806a29cae4e7a2071940949ebffaf3140 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Thu, 6 Jul 2017 13:45:52 -0700 Subject: [core] Include what you use --- src/mbgl/gl/program.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp index 583d53e4ec..ce2b5a335b 100644 --- a/src/mbgl/gl/program.hpp +++ b/src/mbgl/gl/program.hpp @@ -9,11 +9,11 @@ #include #include +#include #include #include #include - #include namespace mbgl { -- cgit v1.2.1 From fbd437689901d725ce5e8df056abab3dc6c104ec Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 3 Jul 2017 14:05:12 -0700 Subject: [core] Inline getActiveAttributes details --- src/mbgl/gl/attribute.cpp | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/src/mbgl/gl/attribute.cpp b/src/mbgl/gl/attribute.cpp index 4e6f78e689..2f817cdcd8 100644 --- a/src/mbgl/gl/attribute.cpp +++ b/src/mbgl/gl/attribute.cpp @@ -13,39 +13,25 @@ AttributeLocation bindAttributeLocation(ProgramID id, AttributeLocation location return location; } -int32_t getActiveAttributeCount(ProgramID id) { - GLint numAttributes; - MBGL_CHECK_ERROR(glGetProgramiv(id, GL_ACTIVE_ATTRIBUTES, &numAttributes)); - return numAttributes; -} +std::set getActiveAttributes(ProgramID id) { + std::set activeAttributes; -int32_t getMaxAttributeNameLength(ProgramID id) { - GLint nameLength; - MBGL_CHECK_ERROR(glGetProgramiv(id, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &nameLength)); - return nameLength; -} + GLint attributeCount; + MBGL_CHECK_ERROR(glGetProgramiv(id, GL_ACTIVE_ATTRIBUTES, &attributeCount)); + + GLint maxAttributeLength; + MBGL_CHECK_ERROR(glGetProgramiv(id, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttributeLength)); -std::string getAttributeName(ProgramID id, int32_t maxLength, AttributeLocation location) { std::string attributeName; - attributeName.resize(maxLength); + attributeName.resize(maxAttributeLength); + GLsizei actualLength; GLint size; GLenum type; - MBGL_CHECK_ERROR(glGetActiveAttrib(id, static_cast(location), - static_cast(maxLength), &actualLength, &size, &type, - const_cast(attributeName.data()))); - attributeName.resize(actualLength); - return attributeName; -} - -std::set getActiveAttributes(ProgramID id) { - std::set activeAttributes; - - GLint attributeCount = getActiveAttributeCount(id); - GLint maxAttributeLength = getMaxAttributeNameLength(id); for (int32_t i = 0; i < attributeCount; i++) { - activeAttributes.emplace(getAttributeName(id, maxAttributeLength, i)); + MBGL_CHECK_ERROR(glGetActiveAttrib(id, i, maxAttributeLength, &actualLength, &size, &type, &attributeName[0])); + activeAttributes.emplace(std::string(attributeName, 0, actualLength)); } return activeAttributes; -- cgit v1.2.1 From d7bdc7a60d330094dd8af8431e0b1d6f588d9f07 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 3 Jul 2017 14:05:12 -0700 Subject: [core] Rework attribute binding (again) These changes are necessary for programs whose set of active attributes is not fixed at compile time by a template parameter pack, but rather varies based on the generated shader text at runtime. In such cases, the attribute location of a given named attribute may vary between instances of the same Program. Previously, attribute bindings were implicitly associated with a location based on template parameter order, and -1 was used to indicate an inactive attribute. This left us unable to disable the appropriate attribute when it went from active to inactive. Now, the state tracker for bindings explicitly associates locations and state, and an empty optional is used to indicate an inactive attribute. In addition, a gl::VertexArray class is now exposed, allowing more flexibility in the relationship between Programs, Segments, and attribute bindings. In this commit, that relationship does not change, but the subsequent commit adjusts it to match gl-js, reduce rebinds, and work around buggy VAO implementations. VertexArray uses a pimpl idiom in order to support implementations that lack the VAO extension. In that case, all VertexArrays share global binding state, reflecting the platform reality in the absence of VAOs, while still providing a uniform API. --- cmake/core-files.cmake | 6 +- src/mbgl/gl/attribute.cpp | 61 +---------- src/mbgl/gl/attribute.hpp | 150 +++++++++++++++------------- src/mbgl/gl/context.cpp | 31 +++--- src/mbgl/gl/context.hpp | 12 ++- src/mbgl/gl/object.cpp | 4 +- src/mbgl/gl/program.hpp | 26 ++--- src/mbgl/gl/segment.cpp | 7 -- src/mbgl/gl/segment.hpp | 73 -------------- src/mbgl/gl/types.hpp | 2 +- src/mbgl/gl/uniform.hpp | 2 +- src/mbgl/gl/value.cpp | 18 ++++ src/mbgl/gl/value.hpp | 7 ++ src/mbgl/gl/vertex_array.cpp | 18 ++++ src/mbgl/gl/vertex_array.hpp | 58 +++++++++++ src/mbgl/programs/binary_program.cpp | 4 +- src/mbgl/programs/binary_program.hpp | 4 +- src/mbgl/programs/program.hpp | 42 +++++--- src/mbgl/programs/segment.cpp | 7 ++ src/mbgl/programs/segment.hpp | 40 ++++++++ src/mbgl/programs/symbol_program.hpp | 48 +++++---- src/mbgl/renderer/circle_bucket.hpp | 4 +- src/mbgl/renderer/debug_bucket.hpp | 2 +- src/mbgl/renderer/fill_bucket.hpp | 6 +- src/mbgl/renderer/fill_extrusion_bucket.hpp | 4 +- src/mbgl/renderer/line_bucket.hpp | 4 +- src/mbgl/renderer/paint_property_binder.hpp | 15 +-- src/mbgl/renderer/painter.cpp | 4 +- src/mbgl/renderer/painter.hpp | 8 +- src/mbgl/renderer/symbol_bucket.hpp | 8 +- test/programs/binary_program.test.cpp | 16 +-- 31 files changed, 375 insertions(+), 316 deletions(-) delete mode 100644 src/mbgl/gl/segment.cpp delete mode 100644 src/mbgl/gl/segment.hpp create mode 100644 src/mbgl/gl/vertex_array.cpp create mode 100644 src/mbgl/gl/vertex_array.hpp create mode 100644 src/mbgl/programs/segment.cpp create mode 100644 src/mbgl/programs/segment.hpp diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index 069b6cb4c9..8a3c42a1f4 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -76,8 +76,6 @@ set(MBGL_CORE_FILES src/mbgl/gl/program.hpp src/mbgl/gl/program_binary_extension.hpp src/mbgl/gl/renderbuffer.hpp - src/mbgl/gl/segment.cpp - src/mbgl/gl/segment.hpp src/mbgl/gl/state.hpp src/mbgl/gl/stencil_mode.cpp src/mbgl/gl/stencil_mode.hpp @@ -87,6 +85,8 @@ set(MBGL_CORE_FILES src/mbgl/gl/uniform.hpp src/mbgl/gl/value.cpp src/mbgl/gl/value.hpp + src/mbgl/gl/vertex_array.cpp + src/mbgl/gl/vertex_array.hpp src/mbgl/gl/vertex_array_extension.hpp src/mbgl/gl/vertex_buffer.hpp @@ -155,6 +155,8 @@ set(MBGL_CORE_FILES src/mbgl/programs/programs.hpp src/mbgl/programs/raster_program.cpp src/mbgl/programs/raster_program.hpp + src/mbgl/programs/segment.cpp + src/mbgl/programs/segment.hpp src/mbgl/programs/symbol_program.cpp src/mbgl/programs/symbol_program.hpp src/mbgl/programs/uniforms.hpp diff --git a/src/mbgl/gl/attribute.cpp b/src/mbgl/gl/attribute.cpp index 2f817cdcd8..bb5b2ddc34 100644 --- a/src/mbgl/gl/attribute.cpp +++ b/src/mbgl/gl/attribute.cpp @@ -1,16 +1,14 @@ #include -#include #include -#include - namespace mbgl { namespace gl { -AttributeLocation bindAttributeLocation(ProgramID id, AttributeLocation location, const char* name) { - assert(location < 8); +void bindAttributeLocation(ProgramID id, AttributeLocation location, const char* name) { + if (location >= MAX_ATTRIBUTES) { + throw gl::Error("too many vertex attributes"); + } MBGL_CHECK_ERROR(glBindAttribLocation(id, location, name)); - return location; } std::set getActiveAttributes(ProgramID id) { @@ -37,56 +35,5 @@ std::set getActiveAttributes(ProgramID id) { return activeAttributes; } -void DisabledAttribute::bind(Context&, AttributeLocation location, std::size_t) const { - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); -} - -template DataType DataTypeOf = static_cast(0); -template <> DataType DataTypeOf< int8_t> = DataType::Byte; -template <> DataType DataTypeOf = DataType::UnsignedByte; -template <> DataType DataTypeOf< int16_t> = DataType::Short; -template <> DataType DataTypeOf = DataType::UnsignedShort; -template <> DataType DataTypeOf< int32_t> = DataType::Integer; -template <> DataType DataTypeOf = DataType::UnsignedInteger; -template <> DataType DataTypeOf = DataType::Float; - -template -void AttributeBinding::bind(Context& context, AttributeLocation location, std::size_t vertexOffset) const { - // FillProgram will attempt to bind at location -1 because it includes - // a fill-outline-color paint property but does not use it or have an - // a_outline_color shader attribute - in this case, we have nothing to bind. - if (location == -1) return; - - context.vertexBuffer = vertexBuffer; - MBGL_CHECK_ERROR(glEnableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttribPointer( - location, - static_cast(attributeSize), - static_cast(DataTypeOf), - static_cast(false), - static_cast(vertexSize), - reinterpret_cast(attributeOffset + (vertexSize * vertexOffset)))); -} - -template class AttributeBinding; -template class AttributeBinding; -template class AttributeBinding; -template class AttributeBinding; - -template class AttributeBinding; -template class AttributeBinding; -template class AttributeBinding; -template class AttributeBinding; - -template class AttributeBinding; -template class AttributeBinding; -template class AttributeBinding; -template class AttributeBinding; - -template class AttributeBinding; -template class AttributeBinding; -template class AttributeBinding; -template class AttributeBinding; - } // namespace gl } // namespace mbgl diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp index f018a1d261..ed4168c21f 100644 --- a/src/mbgl/gl/attribute.hpp +++ b/src/mbgl/gl/attribute.hpp @@ -1,59 +1,51 @@ #pragma once #include -#include +#include #include #include -#include +#include #include #include #include #include +#include +#include namespace mbgl { namespace gl { -class DisabledAttribute { -public: - void bind(Context&, AttributeLocation, std::size_t vertexOffset) const; +static constexpr std::size_t MAX_ATTRIBUTES = 8; - friend bool operator==(const DisabledAttribute&, - const DisabledAttribute&) { - return true; - } -}; +template struct DataTypeOf; +template <> struct DataTypeOf< int8_t> : std::integral_constant {}; +template <> struct DataTypeOf : std::integral_constant {}; +template <> struct DataTypeOf< int16_t> : std::integral_constant {}; +template <> struct DataTypeOf : std::integral_constant {}; +template <> struct DataTypeOf< int32_t> : std::integral_constant {}; +template <> struct DataTypeOf : std::integral_constant {}; +template <> struct DataTypeOf : std::integral_constant {}; -template class AttributeBinding { public: - AttributeBinding(BufferID vertexBuffer_, - std::size_t vertexSize_, - std::size_t attributeOffset_, - std::size_t attributeSize_ = N) - : vertexBuffer(vertexBuffer_), - vertexSize(vertexSize_), - attributeOffset(attributeOffset_), - attributeSize(attributeSize_) - {} - - void bind(Context&, AttributeLocation, std::size_t vertexOffset) const; + DataType attributeType; + std::size_t attributeSize; + std::size_t attributeOffset; + + BufferID vertexBuffer; + std::size_t vertexSize; + std::size_t vertexOffset; friend bool operator==(const AttributeBinding& lhs, const AttributeBinding& rhs) { - return lhs.vertexBuffer == rhs.vertexBuffer - && lhs.vertexSize == rhs.vertexSize - && lhs.attributeOffset == rhs.attributeOffset - && lhs.attributeSize == rhs.attributeSize; + return std::tie(lhs.attributeType, lhs.attributeSize, lhs.attributeOffset, lhs.vertexBuffer, lhs.vertexSize, lhs.vertexOffset) + == std::tie(rhs.attributeType, rhs.attributeSize, rhs.attributeOffset, rhs.vertexBuffer, rhs.vertexSize, rhs.vertexOffset); } - -private: - BufferID vertexBuffer; - std::size_t vertexSize; - std::size_t attributeOffset; - std::size_t attributeSize; }; +using AttributeBindingArray = std::array, MAX_ATTRIBUTES>; + /* gl::Attribute manages the binding of a vertex buffer to a GL program attribute. - T is the underlying primitive type (exposed as Attribute::ValueType) @@ -67,10 +59,7 @@ public: using Value = std::array; using Location = AttributeLocation; - - using Binding = variant< - DisabledAttribute, - AttributeBinding>; + using Binding = AttributeBinding; /* Create a binding for this attribute. The `attributeSize` parameter may be used to @@ -82,28 +71,24 @@ public: std::size_t attributeIndex, std::size_t attributeSize = N) { static_assert(std::is_standard_layout::value, "vertex type must use standard layout"); - return AttributeBinding { + return AttributeBinding { + DataTypeOf::value, + attributeSize, + Vertex::attributeOffsets[attributeIndex], buffer.buffer, sizeof(Vertex), - Vertex::attributeOffsets[attributeIndex], - attributeSize + 0, }; } - static void bind(Context& context, - const Location& location, - Binding& oldBinding, - const Binding& newBinding, - std::size_t vertexOffset) { - if (oldBinding == newBinding) { - return; + static optional offsetBinding(const optional& binding, std::size_t vertexOffset) { + if (binding) { + AttributeBinding result = *binding; + result.vertexOffset = vertexOffset; + return result; + } else { + return binding; } - - Binding::visit(newBinding, [&] (const auto& binding) { - binding.bind(context, location, vertexOffset); - }); - - oldBinding = newBinding; } }; @@ -223,7 +208,7 @@ const std::size_t Vertex::attributeOffsets[5] = { } // namespace detail -AttributeLocation bindAttributeLocation(ProgramID, AttributeLocation, const char * name); +void bindAttributeLocation(ProgramID, AttributeLocation, const char * name); std::set getActiveAttributes(ProgramID); template @@ -232,10 +217,10 @@ public: using Types = TypeList; using Locations = IndexedTuple< TypeList, - TypeList>; + TypeList...>>; using Bindings = IndexedTuple< TypeList, - TypeList>; + TypeList...>>; using NamedLocations = std::vector>; using Vertex = detail::Vertex; @@ -246,13 +231,17 @@ public: static Locations bindLocations(const ProgramID& id) { std::set activeAttributes = getActiveAttributes(id); - AttributeLocation location = -1; - auto bindAndIncrement = [&](const char* name) { - location++; - return bindAttributeLocation(id, location, name); + AttributeLocation location = 0; + auto maybeBindLocation = [&](const char* name) -> optional { + if (activeAttributes.count(name)) { + bindAttributeLocation(id, location, name); + return location++; + } else { + return {}; + } }; - return Locations{ (activeAttributes.count(As::name()) ? bindAndIncrement(As::name()) - : -1)... }; + + return Locations { maybeBindLocation(As::name())... }; } template @@ -261,7 +250,17 @@ public: } static NamedLocations getNamedLocations(const Locations& locations) { - return NamedLocations{ { As::name(), locations.template get() }... }; + NamedLocations result; + + auto maybeAddLocation = [&] (const std::string& name, const optional& location) { + if (location) { + result.emplace_back(name, *location); + } + }; + + util::ignore({ (maybeAddLocation(As::name(), locations.template get()), 0)... }); + + return result; } template @@ -269,16 +268,23 @@ public: return Bindings { As::Type::binding(buffer, Index)... }; } - static void bind(Context& context, - const Locations& locations, - Bindings& oldBindings, - const Bindings& newBindings, - std::size_t vertexOffset) { - util::ignore({ (As::Type::bind(context, - locations.template get(), - oldBindings.template get(), - newBindings.template get(), - vertexOffset), 0)... }); + static Bindings offsetBindings(const Bindings& bindings, std::size_t vertexOffset) { + return Bindings { As::Type::offsetBinding(bindings.template get(), vertexOffset)... }; + } + + static AttributeBindingArray toBindingArray(const Locations& locations, const Bindings& bindings) { + AttributeBindingArray result; + + auto maybeAddBinding = [&] (const optional& location, + const optional& binding) { + if (location) { + result.at(*location) = binding; + } + }; + + util::ignore({ (maybeAddBinding(locations.template get(), bindings.template get()), 0)... }); + + return result; } }; diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index 3ab1260d27..2d7354a64e 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -177,8 +177,8 @@ UniqueBuffer Context::createIndexBuffer(const void* data, std::size_t size) { BufferID id = 0; MBGL_CHECK_ERROR(glGenBuffers(1, &id)); UniqueBuffer result { std::move(id), { this } }; - vertexArrayObject = 0; - elementBuffer = result; + bindVertexArray = 0; + globalVertexArrayState.indexBuffer = result; MBGL_CHECK_ERROR(glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW)); return result; } @@ -229,11 +229,16 @@ optional> Context::getBinaryProgram( } #endif -UniqueVertexArray Context::createVertexArray() { - assert(supportsVertexArrays()); - VertexArrayID id = 0; - MBGL_CHECK_ERROR(vertexArray->genVertexArrays(1, &id)); - return UniqueVertexArray(std::move(id), { this }); +VertexArray Context::createVertexArray() { + if (supportsVertexArrays()) { + VertexArrayID id = 0; + MBGL_CHECK_ERROR(vertexArray->genVertexArrays(1, &id)); + return { std::make_unique(UniqueVertexArray(std::move(id), { this }), *this) }; + } else { + // On GL implementations which do not support vertex arrays, attribute bindings are global state. + // So return a VertexArray which shares our global state tracking and whose deleter is a no-op. + return { UniqueVertexArrayState(&globalVertexArrayState, [] (VertexArrayState*) {}) }; + } } UniqueFramebuffer Context::createFramebuffer() { @@ -502,8 +507,8 @@ void Context::setDirtyState() { tex.setDirty(); } vertexBuffer.setDirty(); - elementBuffer.setDirty(); - vertexArrayObject.setDirty(); + bindVertexArray.setDirty(); + globalVertexArrayState.setDirty(); } void Context::clear(optional color, @@ -622,8 +627,8 @@ void Context::performCleanup() { for (const auto id : abandonedBuffers) { if (vertexBuffer == id) { vertexBuffer.setDirty(); - } else if (elementBuffer == id) { - elementBuffer.setDirty(); + } else if (globalVertexArrayState.indexBuffer == id) { + globalVertexArrayState.indexBuffer.setDirty(); } } MBGL_CHECK_ERROR(glDeleteBuffers(int(abandonedBuffers.size()), abandonedBuffers.data())); @@ -643,8 +648,8 @@ void Context::performCleanup() { if (!abandonedVertexArrays.empty()) { assert(supportsVertexArrays()); for (const auto id : abandonedVertexArrays) { - if (vertexArrayObject == id) { - vertexArrayObject.setDirty(); + if (bindVertexArray == id) { + bindVertexArray.setDirty(); } } MBGL_CHECK_ERROR(vertexArray->deleteVertexArrays(int(abandonedVertexArrays.size()), diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index 56c0618989..8929d24e54 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -53,9 +54,7 @@ public: void verifyProgramLinkage(ProgramID); void linkProgram(ProgramID); UniqueTexture createTexture(); - - bool supportsVertexArrays() const; - UniqueVertexArray createVertexArray(); + VertexArray createVertexArray(); #if MBGL_HAS_BINARY_PROGRAMS bool supportsProgramBinaries() const; @@ -200,10 +199,11 @@ public: State bindFramebuffer; State viewport; std::array, 2> texture; - State vertexArrayObject { *this }; State program; State vertexBuffer; - State elementBuffer; + + State bindVertexArray { *this }; + VertexArrayState globalVertexArrayState { UniqueVertexArray(0, { this }), *this }; #if not MBGL_USE_GLES2 State pixelZoom; @@ -248,6 +248,8 @@ private: void drawPixels(Size size, const void* data, TextureFormat); #endif // MBGL_USE_GLES2 + bool supportsVertexArrays() const; + friend detail::ProgramDeleter; friend detail::ShaderDeleter; friend detail::BufferDeleter; diff --git a/src/mbgl/gl/object.cpp b/src/mbgl/gl/object.cpp index e2d476e0c0..2c5f1bca1f 100644 --- a/src/mbgl/gl/object.cpp +++ b/src/mbgl/gl/object.cpp @@ -33,7 +33,9 @@ void TextureDeleter::operator()(TextureID id) const { void VertexArrayDeleter::operator()(VertexArrayID id) const { assert(context); - context->abandonedVertexArrays.push_back(id); + if (id != 0) { + context->abandonedVertexArrays.push_back(id); + } } void FramebufferDeleter::operator()(FramebufferID id) const { diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp index ce2b5a335b..9d8b0a5b04 100644 --- a/src/mbgl/gl/program.hpp +++ b/src/mbgl/gl/program.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -116,10 +117,12 @@ public: DepthMode depthMode, StencilMode stencilMode, ColorMode colorMode, - UniformValues&& uniformValues, - AttributeBindings&& attributeBindings, + const UniformValues& uniformValues, + VertexArray& vertexArray, + const AttributeBindings& attributeBindings, const IndexBuffer& indexBuffer, - const SegmentVector& segments) { + std::size_t indexOffset, + std::size_t indexLength) { static_assert(std::is_same::value, "incompatible draw mode"); context.setDrawMode(drawMode); @@ -129,18 +132,15 @@ public: context.program = program; - Uniforms::bind(uniformsState, std::move(uniformValues)); + Uniforms::bind(uniformsState, uniformValues); - for (const auto& segment : segments) { - segment.bind(context, - indexBuffer.buffer, - attributeLocations, - attributeBindings); + vertexArray.bind(context, + indexBuffer.buffer, + Attributes::toBindingArray(attributeLocations, attributeBindings)); - context.draw(drawMode.primitiveType, - segment.indexOffset, - segment.indexLength); - } + context.draw(drawMode.primitiveType, + indexOffset, + indexLength); } private: diff --git a/src/mbgl/gl/segment.cpp b/src/mbgl/gl/segment.cpp deleted file mode 100644 index aabdc83cd4..0000000000 --- a/src/mbgl/gl/segment.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include - -namespace mbgl { -namespace gl { - -} // namespace gl -} // namespace mbgl diff --git a/src/mbgl/gl/segment.hpp b/src/mbgl/gl/segment.hpp deleted file mode 100644 index fe0658bf8e..0000000000 --- a/src/mbgl/gl/segment.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include -#include - -namespace mbgl { -namespace gl { - -template -class Segment { -public: - Segment(std::size_t vertexOffset_, - std::size_t indexOffset_, - std::size_t vertexLength_ = 0, - std::size_t indexLength_ = 0) - : vertexOffset(vertexOffset_), - indexOffset(indexOffset_), - vertexLength(vertexLength_), - indexLength(indexLength_) {} - - const std::size_t vertexOffset; - const std::size_t indexOffset; - - std::size_t vertexLength; - std::size_t indexLength; - - void bind(Context& context, - BufferID indexBuffer_, - const typename Attributes::Locations& attributeLocations, - const typename Attributes::Bindings& attributeBindings_) const { - if (context.supportsVertexArrays()) { - if (!vao) { - vao = context.createVertexArray(); - context.vertexBuffer.setDirty(); - } - context.vertexArrayObject = *vao; - if (indexBuffer != indexBuffer_) { - indexBuffer = indexBuffer_; - context.elementBuffer.setDirty(); - context.elementBuffer = indexBuffer_; - } - } else { - // No VAO support. Force attributes to be rebound. - context.elementBuffer = indexBuffer_; - attributeBindings = {}; - } - - Attributes::bind(context, - attributeLocations, - attributeBindings, - attributeBindings_, - vertexOffset); - } - -private: - mutable optional vao; - mutable optional indexBuffer; - mutable typename Attributes::Bindings attributeBindings; -}; - -template -class SegmentVector : public std::vector> { -public: - SegmentVector() = default; -}; - -} // namespace gl -} // namespace mbgl diff --git a/src/mbgl/gl/types.hpp b/src/mbgl/gl/types.hpp index 0595419674..c80399016e 100644 --- a/src/mbgl/gl/types.hpp +++ b/src/mbgl/gl/types.hpp @@ -15,7 +15,7 @@ using VertexArrayID = uint32_t; using FramebufferID = uint32_t; using RenderbufferID = uint32_t; -using AttributeLocation = int32_t; +using AttributeLocation = uint32_t; using UniformLocation = int32_t; using TextureUnit = uint8_t; diff --git a/src/mbgl/gl/uniform.hpp b/src/mbgl/gl/uniform.hpp index bb3453b2d8..3cac09c526 100644 --- a/src/mbgl/gl/uniform.hpp +++ b/src/mbgl/gl/uniform.hpp @@ -82,7 +82,7 @@ public: return NamedLocations{ { Us::name(), state.template get().location }... }; } - static void bind(State& state, Values&& values) { + static void bind(State& state, const Values& values) { util::ignore({ (state.template get() = values.template get(), 0)... }); } }; diff --git a/src/mbgl/gl/value.cpp b/src/mbgl/gl/value.cpp index c081c941f5..10818e8499 100644 --- a/src/mbgl/gl/value.cpp +++ b/src/mbgl/gl/value.cpp @@ -353,6 +353,24 @@ BindVertexArray::Type BindVertexArray::Get(const Context& context) { return binding; } +const optional VertexAttribute::Default {}; + +void VertexAttribute::Set(const optional& binding, Context& context, AttributeLocation location) { + if (binding) { + context.vertexBuffer = binding->vertexBuffer; + MBGL_CHECK_ERROR(glEnableVertexAttribArray(location)); + MBGL_CHECK_ERROR(glVertexAttribPointer( + location, + static_cast(binding->attributeSize), + static_cast(binding->attributeType), + static_cast(false), + static_cast(binding->vertexSize), + reinterpret_cast(binding->attributeOffset + (binding->vertexSize * binding->vertexOffset)))); + } else { + MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); + } +} + #if not MBGL_USE_GLES2 const constexpr PointSize::Type PointSize::Default; diff --git a/src/mbgl/gl/value.hpp b/src/mbgl/gl/value.hpp index aa5cca6fec..62fe88a2f4 100644 --- a/src/mbgl/gl/value.hpp +++ b/src/mbgl/gl/value.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -232,6 +233,12 @@ struct BindVertexArray { static Type Get(const Context&); }; +struct VertexAttribute { + using Type = optional; + static const Type Default; + static void Set(const Type&, Context&, AttributeLocation); +}; + #if not MBGL_USE_GLES2 struct PointSize { diff --git a/src/mbgl/gl/vertex_array.cpp b/src/mbgl/gl/vertex_array.cpp new file mode 100644 index 0000000000..68a500ac45 --- /dev/null +++ b/src/mbgl/gl/vertex_array.cpp @@ -0,0 +1,18 @@ +#include +#include +#include + +namespace mbgl { +namespace gl { + +void VertexArray::bind(Context& context, BufferID indexBuffer, const AttributeBindingArray& bindings) { + context.bindVertexArray = state->vertexArray; + state->indexBuffer = indexBuffer; + + for (AttributeLocation location = 0; location < MAX_ATTRIBUTES; ++location) { + state->bindings[location] = bindings[location]; + } +} + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/gl/vertex_array.hpp b/src/mbgl/gl/vertex_array.hpp new file mode 100644 index 0000000000..9ccf48d9bd --- /dev/null +++ b/src/mbgl/gl/vertex_array.hpp @@ -0,0 +1,58 @@ +#pragma once + +#include +#include +#include +#include + +#include +#include + +namespace mbgl { +namespace gl { + +class Context; + +class VertexArrayState { +public: + VertexArrayState(UniqueVertexArray vertexArray_, Context& context) + : vertexArray(std::move(vertexArray_)), + bindings(makeBindings(context, std::make_index_sequence())) { + } + + void setDirty() { + indexBuffer.setDirty(); + for (auto& binding : bindings) { + binding.setDirty(); + } + } + + UniqueVertexArray vertexArray; + State indexBuffer; + + using AttributeState = State; + std::array bindings; + +private: + template + std::array makeBindings(Context& context, std::index_sequence) { + return {{ AttributeState { context, I }... }}; + } +}; + +using UniqueVertexArrayState = std::unique_ptr>; + +class VertexArray { +public: + VertexArray(UniqueVertexArrayState state_) + : state(std::move(state_)) { + } + + void bind(Context&, BufferID indexBuffer, const AttributeBindingArray&); + +private: + UniqueVertexArrayState state; +}; + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/programs/binary_program.cpp b/src/mbgl/programs/binary_program.cpp index 3b37cfa442..1cad0a2693 100644 --- a/src/mbgl/programs/binary_program.cpp +++ b/src/mbgl/programs/binary_program.cpp @@ -96,7 +96,7 @@ std::string BinaryProgram::serialize() const { return data; } -gl::AttributeLocation BinaryProgram::attributeLocation(const std::string& name) const { +optional BinaryProgram::attributeLocation(const std::string& name) const { for (const auto& pair : attributes) { if (pair.first == name) { return pair.second; @@ -111,7 +111,7 @@ gl::UniformLocation BinaryProgram::uniformLocation(const std::string& name) cons return pair.second; } } - return {}; + return -1; } } // namespace mbgl diff --git a/src/mbgl/programs/binary_program.hpp b/src/mbgl/programs/binary_program.hpp index 8ff3863dc1..2806f4fb3e 100644 --- a/src/mbgl/programs/binary_program.hpp +++ b/src/mbgl/programs/binary_program.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -29,7 +30,8 @@ public: const std::string& identifier() const { return binaryIdentifier; } - gl::AttributeLocation attributeLocation(const std::string& name) const; + + optional attributeLocation(const std::string& name) const; gl::UniformLocation uniformLocation(const std::string& name) const; private: diff --git a/src/mbgl/programs/program.hpp b/src/mbgl/programs/program.hpp index 65f17e5bdc..3ff6e59c6b 100644 --- a/src/mbgl/programs/program.hpp +++ b/src/mbgl/programs/program.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -51,26 +52,37 @@ public: gl::DepthMode depthMode, gl::StencilMode stencilMode, gl::ColorMode colorMode, - UniformValues&& uniformValues, + const UniformValues& uniformValues, const gl::VertexBuffer& layoutVertexBuffer, const gl::IndexBuffer& indexBuffer, - const gl::SegmentVector& segments, + const SegmentVector& segments, const PaintPropertyBinders& paintPropertyBinders, const typename PaintProperties::Evaluated& currentProperties, float currentZoom) { - program.draw( - context, - std::move(drawMode), - std::move(depthMode), - std::move(stencilMode), - std::move(colorMode), - uniformValues - .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)), - LayoutAttributes::bindings(layoutVertexBuffer) - .concat(paintPropertyBinders.attributeBindings(currentProperties)), - indexBuffer, - segments - ); + typename AllUniforms::Values allUniformValues = uniformValues + .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)); + + typename Attributes::Bindings allAttributeBindings = LayoutAttributes::bindings(layoutVertexBuffer) + .concat(paintPropertyBinders.attributeBindings(currentProperties)); + + for (auto& segment : segments) { + if (!segment.vertexArray) { + segment.vertexArray = context.createVertexArray(); + } + + program.draw( + context, + std::move(drawMode), + std::move(depthMode), + std::move(stencilMode), + std::move(colorMode), + allUniformValues, + *segment.vertexArray, + Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset), + indexBuffer, + segment.indexOffset, + segment.indexLength); + } } }; diff --git a/src/mbgl/programs/segment.cpp b/src/mbgl/programs/segment.cpp new file mode 100644 index 0000000000..bb09843e21 --- /dev/null +++ b/src/mbgl/programs/segment.cpp @@ -0,0 +1,7 @@ +#include + +namespace mbgl { +namespace gl { + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/programs/segment.hpp b/src/mbgl/programs/segment.hpp new file mode 100644 index 0000000000..d8cc9679d7 --- /dev/null +++ b/src/mbgl/programs/segment.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include + +namespace mbgl { + +template +class Segment { +public: + Segment(std::size_t vertexOffset_, + std::size_t indexOffset_, + std::size_t vertexLength_ = 0, + std::size_t indexLength_ = 0) + : vertexOffset(vertexOffset_), + indexOffset(indexOffset_), + vertexLength(vertexLength_), + indexLength(indexLength_) {} + + const std::size_t vertexOffset; + const std::size_t indexOffset; + + std::size_t vertexLength; + std::size_t indexLength; + + mutable optional vertexArray; +}; + +template +class SegmentVector : public std::vector> { +public: + SegmentVector() = default; +}; + +} // namespace mbgl diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index 47d92f912c..2fddebde09 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -156,7 +157,7 @@ public: } SymbolSizeAttributes::Bindings attributeBindings() const override { - return SymbolSizeAttributes::Bindings { gl::DisabledAttribute() }; + return SymbolSizeAttributes::Bindings { {} }; } void upload(gl::Context&) override {} @@ -352,29 +353,40 @@ public: gl::DepthMode depthMode, gl::StencilMode stencilMode, gl::ColorMode colorMode, - UniformValues&& uniformValues, + const UniformValues& uniformValues, const gl::VertexBuffer& layoutVertexBuffer, const SymbolSizeBinder& symbolSizeBinder, const gl::IndexBuffer& indexBuffer, - const gl::SegmentVector& segments, + const SegmentVector& segments, const PaintPropertyBinders& paintPropertyBinders, const typename PaintProperties::Evaluated& currentProperties, float currentZoom) { - program.draw( - context, - std::move(drawMode), - std::move(depthMode), - std::move(stencilMode), - std::move(colorMode), - uniformValues - .concat(symbolSizeBinder.uniformValues(currentZoom)) - .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)), - LayoutAttributes::bindings(layoutVertexBuffer) - .concat(symbolSizeBinder.attributeBindings()) - .concat(paintPropertyBinders.attributeBindings(currentProperties)), - indexBuffer, - segments - ); + typename AllUniforms::Values allUniformValues = uniformValues + .concat(symbolSizeBinder.uniformValues(currentZoom)) + .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)); + + typename Attributes::Bindings allAttributeBindings = LayoutAttributes::bindings(layoutVertexBuffer) + .concat(symbolSizeBinder.attributeBindings()) + .concat(paintPropertyBinders.attributeBindings(currentProperties)); + + for (auto& segment : segments) { + if (!segment.vertexArray) { + segment.vertexArray = context.createVertexArray(); + } + + program.draw( + context, + std::move(drawMode), + std::move(depthMode), + std::move(stencilMode), + std::move(colorMode), + allUniformValues, + *segment.vertexArray, + Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset), + indexBuffer, + segment.indexOffset, + segment.indexLength); + } } }; diff --git a/src/mbgl/renderer/circle_bucket.hpp b/src/mbgl/renderer/circle_bucket.hpp index b048fd7675..0f27e2a7e3 100644 --- a/src/mbgl/renderer/circle_bucket.hpp +++ b/src/mbgl/renderer/circle_bucket.hpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include @@ -29,7 +29,7 @@ public: gl::VertexVector vertices; gl::IndexVector triangles; - gl::SegmentVector segments; + SegmentVector segments; optional> vertexBuffer; optional> indexBuffer; diff --git a/src/mbgl/renderer/debug_bucket.hpp b/src/mbgl/renderer/debug_bucket.hpp index 756e58a6de..fc3128e944 100644 --- a/src/mbgl/renderer/debug_bucket.hpp +++ b/src/mbgl/renderer/debug_bucket.hpp @@ -33,7 +33,7 @@ public: const optional expires; const MapDebugOptions debugMode; - gl::SegmentVector segments; + SegmentVector segments; optional> vertexBuffer; optional> indexBuffer; }; diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp index 421d8b332b..d3cd92d451 100644 --- a/src/mbgl/renderer/fill_bucket.hpp +++ b/src/mbgl/renderer/fill_bucket.hpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include @@ -30,8 +30,8 @@ public: gl::VertexVector vertices; gl::IndexVector lines; gl::IndexVector triangles; - gl::SegmentVector lineSegments; - gl::SegmentVector triangleSegments; + SegmentVector lineSegments; + SegmentVector triangleSegments; optional> vertexBuffer; optional> lineIndexBuffer; diff --git a/src/mbgl/renderer/fill_extrusion_bucket.hpp b/src/mbgl/renderer/fill_extrusion_bucket.hpp index c54805d743..d1e695c5a3 100644 --- a/src/mbgl/renderer/fill_extrusion_bucket.hpp +++ b/src/mbgl/renderer/fill_extrusion_bucket.hpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include @@ -27,7 +27,7 @@ public: gl::VertexVector vertices; gl::IndexVector triangles; - gl::SegmentVector triangleSegments; + SegmentVector triangleSegments; optional> vertexBuffer; optional> indexBuffer; diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp index c319548714..95ef2f9a6f 100644 --- a/src/mbgl/renderer/line_bucket.hpp +++ b/src/mbgl/renderer/line_bucket.hpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include @@ -34,7 +34,7 @@ public: gl::VertexVector vertices; gl::IndexVector triangles; - gl::SegmentVector segments; + SegmentVector segments; optional> vertexBuffer; optional> indexBuffer; diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp index 906a2ea07b..36d2e98082 100644 --- a/src/mbgl/renderer/paint_property_binder.hpp +++ b/src/mbgl/renderer/paint_property_binder.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -80,7 +81,7 @@ public: virtual void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) = 0; virtual void upload(gl::Context& context) = 0; - virtual AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const = 0; + virtual optional attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const = 0; virtual float interpolationFactor(float currentZoom) const = 0; virtual T uniformValue(const PossiblyEvaluatedPropertyValue& currentValue) const = 0; @@ -102,8 +103,8 @@ public: void populateVertexVector(const GeometryTileFeature&, std::size_t) override {} void upload(gl::Context&) override {} - AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue&) const override { - return gl::DisabledAttribute(); + optional attributeBinding(const PossiblyEvaluatedPropertyValue&) const override { + return {}; } float interpolationFactor(float) const override { @@ -146,9 +147,9 @@ public: vertexBuffer = context.createVertexBuffer(std::move(vertexVector)); } - AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const override { + optional attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const override { if (currentValue.isConstant()) { - return gl::DisabledAttribute(); + return {}; } else { return Attribute::binding(*vertexBuffer, 0, BaseAttribute::Dimensions); } @@ -207,9 +208,9 @@ public: vertexBuffer = context.createVertexBuffer(std::move(vertexVector)); } - AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const override { + optional attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const override { if (currentValue.isConstant()) { - return gl::DisabledAttribute(); + return {}; } else { return Attribute::binding(*vertexBuffer, 0); } diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index da4903864b..da3268ed76 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -278,7 +278,7 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp context.activeTexture = 0; context.texture[0] = 0; - context.vertexArrayObject = 0; + context.bindVertexArray = 0; } } @@ -312,7 +312,7 @@ void Painter::renderPass(PaintParameters& parameters, MBGL_DEBUG_GROUP(context, layer.baseImpl.id + " - custom"); // Reset GL state to a known state so the CustomLayer always has a clean slate. - context.vertexArrayObject = 0; + context.bindVertexArray = 0; context.setDepthMode(depthModeForSublayer(0, gl::DepthMode::ReadOnly)); context.setStencilMode(gl::StencilMode::disabled()); context.setColorMode(colorModeForRenderPass()); diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp index 4658f0c206..1919ad924e 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -177,10 +177,10 @@ private: gl::IndexBuffer quadTriangleIndexBuffer; gl::IndexBuffer tileBorderIndexBuffer; - gl::SegmentVector tileTriangleSegments; - gl::SegmentVector tileBorderSegments; - gl::SegmentVector rasterSegments; - gl::SegmentVector extrusionTextureSegments; + SegmentVector tileTriangleSegments; + SegmentVector tileBorderSegments; + SegmentVector rasterSegments; + SegmentVector extrusionTextureSegments; }; } // namespace mbgl diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp index f7e4bcfa20..a9bc868db0 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include #include @@ -45,7 +45,7 @@ public: struct TextBuffer { gl::VertexVector vertices; gl::IndexVector triangles; - gl::SegmentVector segments; + SegmentVector segments; optional> vertexBuffer; optional> indexBuffer; @@ -56,7 +56,7 @@ public: struct IconBuffer { gl::VertexVector vertices; gl::IndexVector triangles; - gl::SegmentVector segments; + SegmentVector segments; optional> vertexBuffer; optional> indexBuffer; @@ -65,7 +65,7 @@ public: struct CollisionBoxBuffer { gl::VertexVector vertices; gl::IndexVector lines; - gl::SegmentVector segments; + SegmentVector segments; optional> vertexBuffer; optional> indexBuffer; diff --git a/test/programs/binary_program.test.cpp b/test/programs/binary_program.test.cpp index ce544e7652..a5cf7b6e39 100644 --- a/test/programs/binary_program.test.cpp +++ b/test/programs/binary_program.test.cpp @@ -14,12 +14,12 @@ TEST(BinaryProgram, ObtainValues) { EXPECT_EQ(42u, binaryProgram.format()); EXPECT_EQ("binary code", binaryProgram.code()); EXPECT_EQ("identifier", binaryProgram.identifier()); - EXPECT_EQ(1, binaryProgram.attributeLocation("a_pos")); - EXPECT_EQ(0, binaryProgram.attributeLocation("u_world")); - EXPECT_EQ(4, binaryProgram.attributeLocation("a_data")); + EXPECT_EQ(1u, binaryProgram.attributeLocation("a_pos")); + EXPECT_FALSE(binaryProgram.attributeLocation("u_world")); + EXPECT_EQ(4u, binaryProgram.attributeLocation("a_data")); EXPECT_EQ(1, binaryProgram.uniformLocation("u_world")); EXPECT_EQ(3, binaryProgram.uniformLocation("u_ratio")); - EXPECT_EQ(0, binaryProgram.uniformLocation("a_data")); + EXPECT_EQ(-1, binaryProgram.uniformLocation("a_data")); auto serialized = binaryProgram.serialize(); @@ -28,12 +28,12 @@ TEST(BinaryProgram, ObtainValues) { EXPECT_EQ(42u, binaryProgram2.format()); EXPECT_EQ("binary code", binaryProgram2.code()); EXPECT_EQ("identifier", binaryProgram2.identifier()); - EXPECT_EQ(1, binaryProgram2.attributeLocation("a_pos")); - EXPECT_EQ(0, binaryProgram2.attributeLocation("u_world")); - EXPECT_EQ(4, binaryProgram2.attributeLocation("a_data")); + EXPECT_EQ(1u, binaryProgram2.attributeLocation("a_pos")); + EXPECT_FALSE(binaryProgram2.attributeLocation("u_world")); + EXPECT_EQ(4u, binaryProgram2.attributeLocation("a_data")); EXPECT_EQ(1, binaryProgram2.uniformLocation("u_world")); EXPECT_EQ(3, binaryProgram2.uniformLocation("u_ratio")); - EXPECT_EQ(0, binaryProgram2.uniformLocation("a_data")); + EXPECT_EQ(-1, binaryProgram2.uniformLocation("a_data")); EXPECT_THROW(BinaryProgram(""), std::runtime_error); } -- cgit v1.2.1 From de91e68090a8b246eb161cc8dfdc5b0f40e5bdc0 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Thu, 6 Jul 2017 08:06:12 -0700 Subject: [core] Per-segment-per-layer vertex arrays Reduces rebinding, matches gl-js, and works around the buggy VAO implementation on PowerVR SGX544 GPUs. --- src/mbgl/programs/program.hpp | 11 +++++++---- src/mbgl/programs/segment.hpp | 9 ++++++++- src/mbgl/programs/symbol_program.hpp | 11 +++++++---- src/mbgl/renderer/painter.cpp | 15 +++++++++++---- src/mbgl/renderer/painter_background.cpp | 6 ++++-- src/mbgl/renderer/painter_circle.cpp | 3 ++- src/mbgl/renderer/painter_clipping.cpp | 3 ++- src/mbgl/renderer/painter_debug.cpp | 3 ++- src/mbgl/renderer/painter_fill.cpp | 6 ++++-- src/mbgl/renderer/painter_fill_extrusion.cpp | 6 ++++-- src/mbgl/renderer/painter_line.cpp | 3 ++- src/mbgl/renderer/painter_raster.cpp | 3 ++- src/mbgl/renderer/painter_symbol.cpp | 6 ++++-- 13 files changed, 59 insertions(+), 26 deletions(-) diff --git a/src/mbgl/programs/program.hpp b/src/mbgl/programs/program.hpp index 3ff6e59c6b..8cd6c07322 100644 --- a/src/mbgl/programs/program.hpp +++ b/src/mbgl/programs/program.hpp @@ -58,7 +58,8 @@ public: const SegmentVector& segments, const PaintPropertyBinders& paintPropertyBinders, const typename PaintProperties::Evaluated& currentProperties, - float currentZoom) { + float currentZoom, + const std::string& layerID) { typename AllUniforms::Values allUniformValues = uniformValues .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)); @@ -66,8 +67,10 @@ public: .concat(paintPropertyBinders.attributeBindings(currentProperties)); for (auto& segment : segments) { - if (!segment.vertexArray) { - segment.vertexArray = context.createVertexArray(); + optional& vertexArray = segment.vertexArrays[layerID]; + + if (!vertexArray) { + vertexArray = context.createVertexArray(); } program.draw( @@ -77,7 +80,7 @@ public: std::move(stencilMode), std::move(colorMode), allUniformValues, - *segment.vertexArray, + *vertexArray, Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset), indexBuffer, segment.indexOffset, diff --git a/src/mbgl/programs/segment.hpp b/src/mbgl/programs/segment.hpp index d8cc9679d7..74bf4a75c5 100644 --- a/src/mbgl/programs/segment.hpp +++ b/src/mbgl/programs/segment.hpp @@ -28,7 +28,14 @@ public: std::size_t vertexLength; std::size_t indexLength; - mutable optional vertexArray; + // One VertexArray per layer ID. This minimizes rebinding in cases where + // several layers share buckets but have different sets of active attributes. + // This can happen: + // * when two layers have the same layout properties, but differing + // data-driven paint properties + // * when two fill layers have the same layout properties, but one + // uses fill-color and the other uses fill-pattern + mutable std::map> vertexArrays; }; template diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index 2fddebde09..3bf82009e2 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -360,7 +360,8 @@ public: const SegmentVector& segments, const PaintPropertyBinders& paintPropertyBinders, const typename PaintProperties::Evaluated& currentProperties, - float currentZoom) { + float currentZoom, + const std::string& layerID) { typename AllUniforms::Values allUniformValues = uniformValues .concat(symbolSizeBinder.uniformValues(currentZoom)) .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)); @@ -370,8 +371,10 @@ public: .concat(paintPropertyBinders.attributeBindings(currentProperties)); for (auto& segment : segments) { - if (!segment.vertexArray) { - segment.vertexArray = context.createVertexArray(); + optional& vertexArray = segment.vertexArrays[layerID]; + + if (!vertexArray) { + vertexArray = context.createVertexArray(); } program.draw( @@ -381,7 +384,7 @@ public: std::move(stencilMode), std::move(colorMode), allUniformValues, - *segment.vertexArray, + *vertexArray, Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset), indexBuffer, segment.indexOffset, diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index da3268ed76..fbaf40d5c0 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -353,16 +353,23 @@ void Painter::renderPass(PaintParameters& parameters, const PaintProperties<>::Evaluated properties{}; parameters.programs.extrusionTexture.draw( - context, gl::Triangles(), gl::DepthMode::disabled(), gl::StencilMode::disabled(), + context, + gl::Triangles(), + gl::DepthMode::disabled(), + gl::StencilMode::disabled(), colorModeForRenderPass(), ExtrusionTextureProgram::UniformValues{ uniforms::u_matrix::Value{ viewportMat }, uniforms::u_world::Value{ size }, uniforms::u_image::Value{ 0 }, uniforms::u_opacity::Value{ layer.as() ->evaluated.get() } }, - extrusionTextureVertexBuffer, quadTriangleIndexBuffer, extrusionTextureSegments, - ExtrusionTextureProgram::PaintPropertyBinders{ properties, 0 }, properties, - state.getZoom()); + extrusionTextureVertexBuffer, + quadTriangleIndexBuffer, + extrusionTextureSegments, + ExtrusionTextureProgram::PaintPropertyBinders{ properties, 0 }, + properties, + state.getZoom(), + layer.getID()); } else { for (auto& tileRef : item.tiles) { auto& tile = tileRef.get(); diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp index d01696ee3e..9bd9431082 100644 --- a/src/mbgl/renderer/painter_background.cpp +++ b/src/mbgl/renderer/painter_background.cpp @@ -53,7 +53,8 @@ void Painter::renderBackground(PaintParameters& parameters, const RenderBackgrou tileTriangleSegments, paintAttibuteData, properties, - state.getZoom() + state.getZoom(), + layer.getID() ); } } else { @@ -73,7 +74,8 @@ void Painter::renderBackground(PaintParameters& parameters, const RenderBackgrou tileTriangleSegments, paintAttibuteData, properties, - state.getZoom() + state.getZoom(), + layer.getID() ); } } diff --git a/src/mbgl/renderer/painter_circle.cpp b/src/mbgl/renderer/painter_circle.cpp index 13acb5f7fe..ecd7598de9 100644 --- a/src/mbgl/renderer/painter_circle.cpp +++ b/src/mbgl/renderer/painter_circle.cpp @@ -50,7 +50,8 @@ void Painter::renderCircle(PaintParameters& parameters, bucket.segments, bucket.paintPropertyBinders.at(layer.getID()), properties, - state.getZoom() + state.getZoom(), + layer.getID() ); } diff --git a/src/mbgl/renderer/painter_clipping.cpp b/src/mbgl/renderer/painter_clipping.cpp index b3a2d77b1a..162f3b1d96 100644 --- a/src/mbgl/renderer/painter_clipping.cpp +++ b/src/mbgl/renderer/painter_clipping.cpp @@ -30,7 +30,8 @@ void Painter::renderClippingMask(const UnwrappedTileID& tileID, const ClipID& cl tileTriangleSegments, paintAttibuteData, properties, - state.getZoom() + state.getZoom(), + "clipping" ); } diff --git a/src/mbgl/renderer/painter_debug.cpp b/src/mbgl/renderer/painter_debug.cpp index 37fa3bcb12..9a24ab5422 100644 --- a/src/mbgl/renderer/painter_debug.cpp +++ b/src/mbgl/renderer/painter_debug.cpp @@ -39,7 +39,8 @@ void Painter::renderTileDebug(const RenderTile& renderTile) { segments, paintAttibuteData, properties, - state.getZoom() + state.getZoom(), + "debug" ); }; diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp index e1b59d8839..cad76ace4f 100644 --- a/src/mbgl/renderer/painter_fill.cpp +++ b/src/mbgl/renderer/painter_fill.cpp @@ -60,7 +60,8 @@ void Painter::renderFill(PaintParameters& parameters, segments, bucket.paintPropertyBinders.at(layer.getID()), properties, - state.getZoom() + state.getZoom(), + layer.getID() ); }; @@ -104,7 +105,8 @@ void Painter::renderFill(PaintParameters& parameters, segments, bucket.paintPropertyBinders.at(layer.getID()), properties, - state.getZoom() + state.getZoom(), + layer.getID() ); }; diff --git a/src/mbgl/renderer/painter_fill_extrusion.cpp b/src/mbgl/renderer/painter_fill_extrusion.cpp index 95617525c7..5581cfe983 100644 --- a/src/mbgl/renderer/painter_fill_extrusion.cpp +++ b/src/mbgl/renderer/painter_fill_extrusion.cpp @@ -59,7 +59,8 @@ void Painter::renderFillExtrusion(PaintParameters& parameters, bucket.triangleSegments, bucket.paintPropertyBinders.at(layer.getID()), properties, - state.getZoom()); + state.getZoom(), + layer.getID()); } else { parameters.programs.fillExtrusion.get(properties).draw( @@ -80,7 +81,8 @@ void Painter::renderFillExtrusion(PaintParameters& parameters, bucket.triangleSegments, bucket.paintPropertyBinders.at(layer.getID()), properties, - state.getZoom()); + state.getZoom(), + layer.getID()); }; } diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp index 9152ac8512..209b1447d0 100644 --- a/src/mbgl/renderer/painter_line.cpp +++ b/src/mbgl/renderer/painter_line.cpp @@ -36,7 +36,8 @@ void Painter::renderLine(PaintParameters& parameters, bucket.segments, bucket.paintPropertyBinders.at(layer.getID()), properties, - state.getZoom() + state.getZoom(), + layer.getID() ); }; diff --git a/src/mbgl/renderer/painter_raster.cpp b/src/mbgl/renderer/painter_raster.cpp index fbe025b5b0..f0e5399f4a 100644 --- a/src/mbgl/renderer/painter_raster.cpp +++ b/src/mbgl/renderer/painter_raster.cpp @@ -81,7 +81,8 @@ void Painter::renderRaster(PaintParameters& parameters, rasterSegments, paintAttributeData, properties, - state.getZoom() + state.getZoom(), + layer.getID() ); } diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp index c9ed8cc570..6462eebdcc 100644 --- a/src/mbgl/renderer/painter_symbol.cpp +++ b/src/mbgl/renderer/painter_symbol.cpp @@ -58,7 +58,8 @@ void Painter::renderSymbol(PaintParameters& parameters, buffers.segments, binders, paintProperties, - state.getZoom() + state.getZoom(), + layer.getID() ); }; @@ -156,7 +157,8 @@ void Painter::renderSymbol(PaintParameters& parameters, bucket.collisionBox.segments, paintAttributeData, properties, - state.getZoom() + state.getZoom(), + layer.getID() ); } } -- cgit v1.2.1 From cf83f117f0e3e338454ba1bc0e5a13b3b9565228 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 10 Jul 2017 12:19:23 -0700 Subject: [core] Reduce memory requirements of VertexArrays --- src/mbgl/gl/attribute.hpp | 22 ++++++++++++++-------- src/mbgl/gl/context.cpp | 5 +++-- src/mbgl/gl/types.hpp | 2 +- src/mbgl/gl/vertex_array.hpp | 17 ++++++++++++++++- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp index ed4168c21f..a85b49c6a5 100644 --- a/src/mbgl/gl/attribute.hpp +++ b/src/mbgl/gl/attribute.hpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace mbgl { namespace gl { @@ -30,12 +31,12 @@ template <> struct DataTypeOf : std::integral_constant::value, "vertex type must use standard layout"); + assert(attributeSize >= 1); + assert(attributeSize <= 4); + assert(Vertex::attributeOffsets[attributeIndex] <= std::numeric_limits::max()); + static_assert(sizeof(Vertex) <= std::numeric_limits::max(), "vertex too large"); return AttributeBinding { DataTypeOf::value, - attributeSize, - Vertex::attributeOffsets[attributeIndex], + static_cast(attributeSize), + static_cast(Vertex::attributeOffsets[attributeIndex]), buffer.buffer, - sizeof(Vertex), + static_cast(sizeof(Vertex)), 0, }; } static optional offsetBinding(const optional& binding, std::size_t vertexOffset) { + assert(vertexOffset <= std::numeric_limits::max()); if (binding) { AttributeBinding result = *binding; - result.vertexOffset = vertexOffset; + result.vertexOffset = static_cast(vertexOffset); return result; } else { return binding; diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index 2d7354a64e..19ea9a514f 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -233,11 +233,12 @@ VertexArray Context::createVertexArray() { if (supportsVertexArrays()) { VertexArrayID id = 0; MBGL_CHECK_ERROR(vertexArray->genVertexArrays(1, &id)); - return { std::make_unique(UniqueVertexArray(std::move(id), { this }), *this) }; + UniqueVertexArray vao(std::move(id), { this }); + return { UniqueVertexArrayState(new VertexArrayState(std::move(vao), *this), VertexArrayStateDeleter { true })}; } else { // On GL implementations which do not support vertex arrays, attribute bindings are global state. // So return a VertexArray which shares our global state tracking and whose deleter is a no-op. - return { UniqueVertexArrayState(&globalVertexArrayState, [] (VertexArrayState*) {}) }; + return { UniqueVertexArrayState(&globalVertexArrayState, VertexArrayStateDeleter { false }) }; } } diff --git a/src/mbgl/gl/types.hpp b/src/mbgl/gl/types.hpp index c80399016e..e7d2ca449a 100644 --- a/src/mbgl/gl/types.hpp +++ b/src/mbgl/gl/types.hpp @@ -24,7 +24,7 @@ enum class ShaderType : uint32_t { Fragment = 0x8B30 }; -enum class DataType : uint32_t { +enum class DataType : uint16_t { Byte = 0x1400, UnsignedByte = 0x1401, Short = 0x1402, diff --git a/src/mbgl/gl/vertex_array.hpp b/src/mbgl/gl/vertex_array.hpp index 9ccf48d9bd..46c67017bb 100644 --- a/src/mbgl/gl/vertex_array.hpp +++ b/src/mbgl/gl/vertex_array.hpp @@ -40,7 +40,22 @@ private: } }; -using UniqueVertexArrayState = std::unique_ptr>; +class VertexArrayStateDeleter { +public: + VertexArrayStateDeleter(bool destroy_) + : destroy(destroy_) {} + + void operator()(VertexArrayState* ptr) const { + if (destroy) { + delete ptr; + } + } + +private: + bool destroy; +}; + +using UniqueVertexArrayState = std::unique_ptr; class VertexArray { public: -- cgit v1.2.1 From 902d9442da0f2f2c74530a4b770c9ff05f5d4d1e Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 10 Jul 2017 12:31:46 -0700 Subject: [core] No need for optional in map of VertexArrays --- src/mbgl/programs/program.hpp | 8 ++++---- src/mbgl/programs/segment.hpp | 3 +-- src/mbgl/programs/symbol_program.hpp | 8 ++++---- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/mbgl/programs/program.hpp b/src/mbgl/programs/program.hpp index 8cd6c07322..ca8434cf0a 100644 --- a/src/mbgl/programs/program.hpp +++ b/src/mbgl/programs/program.hpp @@ -67,10 +67,10 @@ public: .concat(paintPropertyBinders.attributeBindings(currentProperties)); for (auto& segment : segments) { - optional& vertexArray = segment.vertexArrays[layerID]; + auto vertexArrayIt = segment.vertexArrays.find(layerID); - if (!vertexArray) { - vertexArray = context.createVertexArray(); + if (vertexArrayIt == segment.vertexArrays.end()) { + vertexArrayIt = segment.vertexArrays.emplace(layerID, context.createVertexArray()).first; } program.draw( @@ -80,7 +80,7 @@ public: std::move(stencilMode), std::move(colorMode), allUniformValues, - *vertexArray, + vertexArrayIt->second, Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset), indexBuffer, segment.indexOffset, diff --git a/src/mbgl/programs/segment.hpp b/src/mbgl/programs/segment.hpp index 74bf4a75c5..937df4dece 100644 --- a/src/mbgl/programs/segment.hpp +++ b/src/mbgl/programs/segment.hpp @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -35,7 +34,7 @@ public: // data-driven paint properties // * when two fill layers have the same layout properties, but one // uses fill-color and the other uses fill-pattern - mutable std::map> vertexArrays; + mutable std::map vertexArrays; }; template diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index 3bf82009e2..5fb0c4f15f 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -371,10 +371,10 @@ public: .concat(paintPropertyBinders.attributeBindings(currentProperties)); for (auto& segment : segments) { - optional& vertexArray = segment.vertexArrays[layerID]; + auto vertexArrayIt = segment.vertexArrays.find(layerID); - if (!vertexArray) { - vertexArray = context.createVertexArray(); + if (vertexArrayIt == segment.vertexArrays.end()) { + vertexArrayIt = segment.vertexArrays.emplace(layerID, context.createVertexArray()).first; } program.draw( @@ -384,7 +384,7 @@ public: std::move(stencilMode), std::move(colorMode), allUniformValues, - *vertexArray, + vertexArrayIt->second, Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset), indexBuffer, segment.indexOffset, -- cgit v1.2.1 From 550da70cf78e700deea4d298e90afe134fda27e2 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 11 Jul 2017 14:11:59 -0700 Subject: [core] Pass correct sources to programIdentifier --- src/mbgl/gl/program.hpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp index 9d8b0a5b04..3b54ec194a 100644 --- a/src/mbgl/gl/program.hpp +++ b/src/mbgl/gl/program.hpp @@ -52,15 +52,13 @@ public: const char* name, const char* vertexSource_, const char* fragmentSource_) { + const std::string vertexSource = shaders::vertexSource(programParameters, vertexSource_); + const std::string fragmentSource = shaders::fragmentSource(programParameters, fragmentSource_); + #if MBGL_HAS_BINARY_PROGRAMS optional cachePath = programParameters.cachePath(name); if (cachePath && context.supportsProgramBinaries()) { - const std::string vertexSource = - shaders::vertexSource(programParameters, vertexSource_); - const std::string fragmentSource = - shaders::fragmentSource(programParameters, fragmentSource_); - const std::string identifier = - shaders::programIdentifier(vertexSource, fragmentSource_); + const std::string identifier = shaders::programIdentifier(vertexSource, fragmentSource); try { if (auto cachedBinaryProgram = util::readFile(*cachePath)) { @@ -94,11 +92,9 @@ public: return std::move(result); } #endif + (void)name; - return Program { - context, shaders::vertexSource(programParameters, vertexSource_), - shaders::fragmentSource(programParameters, fragmentSource_) - }; + return Program { context, vertexSource, fragmentSource }; } template -- cgit v1.2.1 From 2d147470a5f982afb0c1a63ff632497f85ea85bf Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 11 Jul 2017 14:11:02 -0700 Subject: [android] Force previously cached program binaries to be regenerated --- src/mbgl/shaders/shaders.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mbgl/shaders/shaders.cpp b/src/mbgl/shaders/shaders.cpp index 31ff405f02..2e5a318024 100644 --- a/src/mbgl/shaders/shaders.cpp +++ b/src/mbgl/shaders/shaders.cpp @@ -22,6 +22,7 @@ std::string programIdentifier(const std::string& vertexSource, const std::string ss << std::setfill('0') << std::setw(sizeof(size_t) * 2) << std::hex; ss << std::hash()(vertexSource); ss << std::hash()(fragmentSource); + ss << "v2"; return ss.str(); } -- cgit v1.2.1 From b69f8338bbd18573b2a2a4282c4736f257526d03 Mon Sep 17 00:00:00 2001 From: Asheem Mamoowala Date: Tue, 11 Jul 2017 14:31:05 -0700 Subject: [macos] Use [NSImage CGImageForProposedRect:context:hints:] instead of drawing into a bitmap representation --- platform/macos/src/NSImage+MGLAdditions.mm | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/platform/macos/src/NSImage+MGLAdditions.mm b/platform/macos/src/NSImage+MGLAdditions.mm index 6abe53e9ae..7500a8a207 100644 --- a/platform/macos/src/NSImage+MGLAdditions.mm +++ b/platform/macos/src/NSImage+MGLAdditions.mm @@ -42,15 +42,8 @@ } - (mbgl::PremultipliedImage)mgl_premultipliedImage { - // Create a bitmap image representation from the image, respecting backing - // scale factor and any resizing done on the image at runtime. - // http://www.cocoabuilder.com/archive/cocoa/82430-nsimage-getting-raw-bitmap-data.html#82431 - [self lockFocus]; - NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:{ NSZeroPoint, self.size }]; - [self unlockFocus]; - - mbgl::PremultipliedImage cPremultipliedImage({ static_cast(rep.pixelsWide), static_cast(rep.pixelsHigh) }); - std::copy(rep.bitmapData, rep.bitmapData + cPremultipliedImage.bytes(), cPremultipliedImage.data.get()); - return cPremultipliedImage; + CGImageRef ref = [self CGImageForProposedRect:nullptr context:nullptr hints:nullptr]; + return MGLPremultipliedImageFromCGImage(ref); } + @end -- cgit v1.2.1 From 1d15ed64dcf78daa9459247127857513608c18ad Mon Sep 17 00:00:00 2001 From: Asheem Mamoowala Date: Tue, 20 Jun 2017 11:09:19 -0700 Subject: [core] Use shared pointer to manage Image source raster data and speed up change detection --- src/mbgl/renderer/buckets/raster_bucket.cpp | 19 +++++- src/mbgl/renderer/buckets/raster_bucket.hpp | 5 +- src/mbgl/renderer/sources/render_image_source.cpp | 75 ++++++++++++++--------- src/mbgl/renderer/sources/render_image_source.hpp | 2 +- src/mbgl/style/sources/image_source_impl.cpp | 8 +-- src/mbgl/style/sources/image_source_impl.hpp | 6 +- test/style/source.test.cpp | 2 +- 7 files changed, 75 insertions(+), 42 deletions(-) diff --git a/src/mbgl/renderer/buckets/raster_bucket.cpp b/src/mbgl/renderer/buckets/raster_bucket.cpp index 49ec0065c3..61548ee333 100644 --- a/src/mbgl/renderer/buckets/raster_bucket.cpp +++ b/src/mbgl/renderer/buckets/raster_bucket.cpp @@ -9,12 +9,19 @@ namespace mbgl { using namespace style; -RasterBucket::RasterBucket(UnassociatedImage&& image_) : image(std::move(image_)) { +RasterBucket::RasterBucket(UnassociatedImage&& image_) { + image = std::make_shared(std::move(image_)); } +RasterBucket::RasterBucket(std::shared_ptr image_): image(image_) { + +} void RasterBucket::upload(gl::Context& context) { + if (!hasData()) { + return; + } if (!texture) { - texture = context.createTexture(image); + texture = context.createTexture(*image); } if (!vertices.empty()) { vertexBuffer = context.createVertexBuffer(std::move(vertices)); @@ -32,6 +39,12 @@ void RasterBucket::clear() { uploaded = false; } + +void RasterBucket::setImage(std::shared_ptr image_) { + image = std::move(image_); + texture = {}; + uploaded = false; +} void RasterBucket::render(Painter& painter, PaintParameters& parameters, const RenderLayer& layer, @@ -47,7 +60,7 @@ void RasterBucket::render(Painter& painter, } bool RasterBucket::hasData() const { - return true; + return !!image; } } // namespace mbgl diff --git a/src/mbgl/renderer/buckets/raster_bucket.hpp b/src/mbgl/renderer/buckets/raster_bucket.hpp index 44b9111b81..e92e4b51f7 100644 --- a/src/mbgl/renderer/buckets/raster_bucket.hpp +++ b/src/mbgl/renderer/buckets/raster_bucket.hpp @@ -14,7 +14,7 @@ namespace mbgl { class RasterBucket : public Bucket { public: RasterBucket(UnassociatedImage&&); - + RasterBucket(std::shared_ptr); void upload(gl::Context&) override; void render(Painter&, PaintParameters&, const RenderLayer&, const RenderTile&) override; void render(Painter& painter, @@ -24,7 +24,8 @@ public: bool hasData() const override; void clear(); - UnassociatedImage image; + void setImage(std::shared_ptr); + std::shared_ptr image; optional texture; // Bucket specific vertices are used for Image Sources only diff --git a/src/mbgl/renderer/sources/render_image_source.cpp b/src/mbgl/renderer/sources/render_image_source.cpp index f1860b6b62..a17f97ee2f 100644 --- a/src/mbgl/renderer/sources/render_image_source.cpp +++ b/src/mbgl/renderer/sources/render_image_source.cpp @@ -14,7 +14,7 @@ namespace mbgl { using namespace style; RenderImageSource::RenderImageSource(Immutable impl_) - : RenderSource(impl_), shouldRender(false) { + : RenderSource(impl_) { } RenderImageSource::~RenderImageSource() = default; @@ -42,13 +42,13 @@ void RenderImageSource::startRender(Painter& painter) { matrices.push_back(matrix); } - if (bucket->needsUpload() && shouldRender) { + if (bucket->needsUpload()) { bucket->upload(painter.context); } } void RenderImageSource::finishRender(Painter& painter) { - if (!isLoaded() || !shouldRender) { + if (!isLoaded()) { return; } for (auto matrix : matrices) { @@ -73,15 +73,24 @@ void RenderImageSource::update(Immutable baseImpl_, const bool needsRendering, const bool, const TileParameters& parameters) { - std::swap(baseImpl, baseImpl_); - enabled = needsRendering; + if (!needsRendering) { + return; + } auto transformState = parameters.transformState; - auto size = transformState.getSize(); - double viewportHeight = size.height; + std::swap(baseImpl, baseImpl_); auto coords = impl().getCoordinates(); + std::shared_ptr image = impl().getImage(); + + if (!image || !image->valid()) { + enabled = false; + return; + } + + auto size = transformState.getSize(); + const double viewportHeight = size.height; // Compute the screen coordinates at wrap=0 for the given LatLng ScreenCoordinate nePixel = { -INFINITY, -INFINITY }; @@ -94,38 +103,51 @@ void RenderImageSource::update(Immutable baseImpl_, swPixel.y = std::min(swPixel.y, viewportHeight - pixel.y); nePixel.y = std::max(nePixel.y, viewportHeight - pixel.y); } - double width = nePixel.x - swPixel.x; - double height = nePixel.y - swPixel.y; + const double width = nePixel.x - swPixel.x; + const double height = nePixel.y - swPixel.y; // Don't bother drawing the ImageSource unless it occupies >4 screen pixels - shouldRender = (width * height > 4); - if (!shouldRender) { + enabled = (width * height > 4); + if (!enabled) { return; } // Calculate the optimum zoom level to determine the tile ids to use for transforms double minScale = INFINITY; - if (width > 0 || height > 0) { - double scaleX = double(size.width) / width; - double scaleY = double(size.height) / height; - minScale = util::min(scaleX, scaleY); - } + double scaleX = double(size.width) / width; + double scaleY = double(size.height) / height; + minScale = util::min(scaleX, scaleY); double zoom = transformState.getZoom() + util::log2(minScale); - zoom = util::clamp(zoom, transformState.getMinZoom(), transformState.getMaxZoom()); - + zoom = std::floor(util::clamp(zoom, transformState.getMinZoom(), transformState.getMaxZoom())); auto imageBounds = LatLngBounds::hull(coords[0], coords[1]); imageBounds.extend(coords[2]); imageBounds.extend(coords[3]); - auto tileCover = util::tileCover(imageBounds, ::floor(zoom)); + auto tileCover = util::tileCover(imageBounds, zoom); tileIds.clear(); tileIds.push_back(tileCover[0]); + bool hasVisibleTile = false; // Add additional wrapped tile ids if neccessary auto idealTiles = util::tileCover(transformState, transformState.getZoom()); for (auto tile : idealTiles) { if (tile.wrap != 0 && tileCover[0].canonical.isChildOf(tile.canonical)) { tileIds.push_back({ tile.wrap, tileCover[0].canonical }); + hasVisibleTile = true; } + else if (!hasVisibleTile) { + for (auto coveringTile: tileCover) { + if(coveringTile.canonical == tile.canonical || + coveringTile.canonical.isChildOf(tile.canonical) || + tile.canonical.isChildOf(coveringTile.canonical)) { + hasVisibleTile = true; + } + } + } + } + + enabled = hasVisibleTile; + if (!enabled) { + return; } // Calculate Geometry Coordinates based on tile cover at ideal zoom @@ -135,16 +157,13 @@ void RenderImageSource::update(Immutable baseImpl_, auto gc = TileCoordinate::toGeometryCoordinate(tileIds[0], tc.p); geomCoords.push_back(gc); } - - const UnassociatedImage& image = impl().getImage(); - if (!image.valid()) { - return; - } - - if (!bucket || image != bucket->image) { - bucket = std::make_unique(image.clone()); + if (!bucket) { + bucket = std::make_unique(image); } else { bucket->clear(); + if (image != bucket->image) { + bucket->setImage(image); + } } // Set Bucket Vertices, Indices, and segments @@ -166,7 +185,7 @@ void RenderImageSource::update(Immutable baseImpl_, void RenderImageSource::render(Painter& painter, PaintParameters& parameters, const RenderLayer& layer) { - if (isLoaded() && !bucket->needsUpload() && shouldRender) { + if (isEnabled() && isLoaded() && !bucket->needsUpload()) { for (auto matrix : matrices) { bucket->render(painter, parameters, layer, matrix); } diff --git a/src/mbgl/renderer/sources/render_image_source.hpp b/src/mbgl/renderer/sources/render_image_source.hpp index 41c4bd5483..6389251709 100644 --- a/src/mbgl/renderer/sources/render_image_source.hpp +++ b/src/mbgl/renderer/sources/render_image_source.hpp @@ -8,6 +8,7 @@ namespace mbgl { class RenderLayer; class PaintParameters; class RasterBucket; +class LatLng; namespace gl { class Context; @@ -52,7 +53,6 @@ private: std::vector tileIds; std::unique_ptr bucket; std::vector matrices; - bool shouldRender; }; template <> diff --git a/src/mbgl/style/sources/image_source_impl.cpp b/src/mbgl/style/sources/image_source_impl.cpp index 98f3cc9db9..eb3e2635e5 100644 --- a/src/mbgl/style/sources/image_source_impl.cpp +++ b/src/mbgl/style/sources/image_source_impl.cpp @@ -12,17 +12,17 @@ ImageSource::Impl::Impl(std::string id_, std::array coords_) ImageSource::Impl::Impl(const Impl& other, std::array coords_) : Source::Impl(other), coords(std::move(coords_)), - image(other.image.clone()) { + image(other.image) { } -ImageSource::Impl::Impl(const Impl& rhs, UnassociatedImage image_) +ImageSource::Impl::Impl(const Impl& rhs, UnassociatedImage&& image_) : Source::Impl(rhs), coords(rhs.coords), - image(std::move(image_)) { + image(std::make_shared(std::move(image_))) { } ImageSource::Impl::~Impl() = default; -const UnassociatedImage& ImageSource::Impl::getImage() const { +std::shared_ptr ImageSource::Impl::getImage() const { return image; } diff --git a/src/mbgl/style/sources/image_source_impl.hpp b/src/mbgl/style/sources/image_source_impl.hpp index 5fd41ac6e6..e0999c34a5 100644 --- a/src/mbgl/style/sources/image_source_impl.hpp +++ b/src/mbgl/style/sources/image_source_impl.hpp @@ -13,17 +13,17 @@ class ImageSource::Impl : public Source::Impl { public: Impl(std::string id, std::array coords); Impl(const Impl& rhs, std::array coords); - Impl(const Impl& rhs, UnassociatedImage image); + Impl(const Impl& rhs, UnassociatedImage&& image); ~Impl() final; - const UnassociatedImage& getImage() const; + std::shared_ptr getImage() const; std::array getCoordinates() const; optional getAttribution() const final; private: std::array coords; - UnassociatedImage image; + std::shared_ptr image; }; } // namespace style diff --git a/test/style/source.test.cpp b/test/style/source.test.cpp index 004ba18c5b..d576dc1e4a 100644 --- a/test/style/source.test.cpp +++ b/test/style/source.test.cpp @@ -535,7 +535,7 @@ TEST(Source, ImageSourceImageUpdate) { rgba.data[0] = 255; rgba.data[1] = 254; rgba.data[2] = 253; - rgba.data[3] = 128; + rgba.data[3] = 0; // Schedule an update test.loop.invoke([&] () { -- cgit v1.2.1 From 8ae70105463db78699ef3743fb24503ed8feb054 Mon Sep 17 00:00:00 2001 From: Asheem Mamoowala Date: Tue, 11 Jul 2017 14:31:05 -0700 Subject: [core][ios][android][macos] Use premultiplied image directly for RasterTile and ImageSource, un-premultiply in the shader for blending --- include/mbgl/style/sources/image_source.hpp | 2 +- .../style/AnimatedImageSourceActivity.java | 28 +++++++++++++++++----- .../android/src/style/sources/image_source.cpp | 3 +-- platform/darwin/src/MGLImageSource.mm | 5 ++-- src/mbgl/renderer/buckets/raster_bucket.cpp | 8 +++---- src/mbgl/renderer/buckets/raster_bucket.hpp | 8 +++---- src/mbgl/renderer/sources/render_image_source.cpp | 2 +- src/mbgl/shaders/raster.cpp | 6 +++++ src/mbgl/style/sources/image_source.cpp | 5 ++-- src/mbgl/style/sources/image_source_impl.cpp | 6 ++--- src/mbgl/style/sources/image_source_impl.hpp | 6 ++--- src/mbgl/tile/raster_tile_worker.cpp | 2 +- test/gl/bucket.test.cpp | 2 +- test/style/source.test.cpp | 2 +- test/tile/raster_tile.test.cpp | 2 +- 15 files changed, 53 insertions(+), 34 deletions(-) diff --git a/include/mbgl/style/sources/image_source.hpp b/include/mbgl/style/sources/image_source.hpp index d8a2c45bd8..009764291f 100644 --- a/include/mbgl/style/sources/image_source.hpp +++ b/include/mbgl/style/sources/image_source.hpp @@ -18,7 +18,7 @@ public: optional getURL() const; void setURL(const std::string& url); - void setImage(UnassociatedImage&&); + void setImage(PremultipliedImage&&); void setCoordinates(const std::array&); std::array getCoordinates() const; diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/AnimatedImageSourceActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/AnimatedImageSourceActivity.java index aeb6751b99..1beba632b0 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/AnimatedImageSourceActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/AnimatedImageSourceActivity.java @@ -1,10 +1,16 @@ package com.mapbox.mapboxsdk.testapp.activity.style; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.support.annotation.NonNull; +import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; +import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngQuad; import com.mapbox.mapboxsdk.maps.MapView; @@ -106,17 +112,27 @@ public class AnimatedImageSourceActivity extends AppCompatActivity implements On private MapboxMap mapboxMap; private Handler handler; - private int[] drawables; + private Bitmap[] drawables; private int drawableIndex; + Bitmap getBitmap(int resourceId) { + Context context = Mapbox.getApplicationContext(); + Drawable drawable = ContextCompat.getDrawable(context, resourceId); + if (drawable instanceof BitmapDrawable) { + BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; + return bitmapDrawable.getBitmap(); + } + return null; + } + RefreshImageRunnable(MapboxMap mapboxMap, Handler handler) { this.mapboxMap = mapboxMap; this.handler = handler; - drawables = new int[4]; - drawables[0] = R.drawable.southeast_radar_0; - drawables[1] = R.drawable.southeast_radar_1; - drawables[2] = R.drawable.southeast_radar_2; - drawables[3] = R.drawable.southeast_radar_3; + drawables = new Bitmap[4]; + drawables[0] = getBitmap(R.drawable.southeast_radar_0); + drawables[1] = getBitmap(R.drawable.southeast_radar_1); + drawables[2] = getBitmap(R.drawable.southeast_radar_2); + drawables[3] = getBitmap(R.drawable.southeast_radar_3); drawableIndex = 1; } diff --git a/platform/android/src/style/sources/image_source.cpp b/platform/android/src/style/sources/image_source.cpp index cc7e1e7404..9c37d63d4b 100644 --- a/platform/android/src/style/sources/image_source.cpp +++ b/platform/android/src/style/sources/image_source.cpp @@ -40,8 +40,7 @@ namespace android { } void ImageSource::setImage(jni::JNIEnv& env, jni::Object bitmap) { - UnassociatedImage image = util::unpremultiply(Bitmap::GetImage(env, bitmap)); - source.as()->setImage(std:: move(image)); + source.as()->setImage(Bitmap::GetImage(env, bitmap)); } jni::Class ImageSource::javaClass; diff --git a/platform/darwin/src/MGLImageSource.mm b/platform/darwin/src/MGLImageSource.mm index 0a2dc2713f..351247e901 100644 --- a/platform/darwin/src/MGLImageSource.mm +++ b/platform/darwin/src/MGLImageSource.mm @@ -60,10 +60,9 @@ - (void)setImage:(MGLImage *)image { if (image != nullptr) { - mbgl::UnassociatedImage unassociatedImage = mbgl::util::unpremultiply(image.mgl_premultipliedImage); - self.rawSource->setImage(std::move(unassociatedImage)); + self.rawSource->setImage(image.mgl_premultipliedImage); } else { - self.rawSource->setImage(mbgl::UnassociatedImage({0,0})); + self.rawSource->setImage(mbgl::PremultipliedImage({0,0})); } _image = image; } diff --git a/src/mbgl/renderer/buckets/raster_bucket.cpp b/src/mbgl/renderer/buckets/raster_bucket.cpp index 61548ee333..8a2f1227a5 100644 --- a/src/mbgl/renderer/buckets/raster_bucket.cpp +++ b/src/mbgl/renderer/buckets/raster_bucket.cpp @@ -9,11 +9,11 @@ namespace mbgl { using namespace style; -RasterBucket::RasterBucket(UnassociatedImage&& image_) { - image = std::make_shared(std::move(image_)); +RasterBucket::RasterBucket(PremultipliedImage&& image_) { + image = std::make_shared(std::move(image_)); } -RasterBucket::RasterBucket(std::shared_ptr image_): image(image_) { +RasterBucket::RasterBucket(std::shared_ptr image_): image(image_) { } void RasterBucket::upload(gl::Context& context) { @@ -40,7 +40,7 @@ void RasterBucket::clear() { uploaded = false; } -void RasterBucket::setImage(std::shared_ptr image_) { +void RasterBucket::setImage(std::shared_ptr image_) { image = std::move(image_); texture = {}; uploaded = false; diff --git a/src/mbgl/renderer/buckets/raster_bucket.hpp b/src/mbgl/renderer/buckets/raster_bucket.hpp index e92e4b51f7..1b0d787bcd 100644 --- a/src/mbgl/renderer/buckets/raster_bucket.hpp +++ b/src/mbgl/renderer/buckets/raster_bucket.hpp @@ -13,8 +13,8 @@ namespace mbgl { class RasterBucket : public Bucket { public: - RasterBucket(UnassociatedImage&&); - RasterBucket(std::shared_ptr); + RasterBucket(PremultipliedImage&&); + RasterBucket(std::shared_ptr); void upload(gl::Context&) override; void render(Painter&, PaintParameters&, const RenderLayer&, const RenderTile&) override; void render(Painter& painter, @@ -24,8 +24,8 @@ public: bool hasData() const override; void clear(); - void setImage(std::shared_ptr); - std::shared_ptr image; + void setImage(std::shared_ptr); + std::shared_ptr image; optional texture; // Bucket specific vertices are used for Image Sources only diff --git a/src/mbgl/renderer/sources/render_image_source.cpp b/src/mbgl/renderer/sources/render_image_source.cpp index a17f97ee2f..3ffff5c8c6 100644 --- a/src/mbgl/renderer/sources/render_image_source.cpp +++ b/src/mbgl/renderer/sources/render_image_source.cpp @@ -82,7 +82,7 @@ void RenderImageSource::update(Immutable baseImpl_, std::swap(baseImpl, baseImpl_); auto coords = impl().getCoordinates(); - std::shared_ptr image = impl().getImage(); + std::shared_ptr image = impl().getImage(); if (!image || !image->valid()) { enabled = false; diff --git a/src/mbgl/shaders/raster.cpp b/src/mbgl/shaders/raster.cpp index eb7a2db240..f454078310 100644 --- a/src/mbgl/shaders/raster.cpp +++ b/src/mbgl/shaders/raster.cpp @@ -45,6 +45,12 @@ void main() { // read and cross-fade colors from the main and parent tiles vec4 color0 = texture2D(u_image0, v_pos0); vec4 color1 = texture2D(u_image1, v_pos1); + if (color0.a > 0.0) { + color0.rgb = color0.rgb / color0.a; + } + if (color1.a > 0.0) { + color1.rgb = color1.rgb / color1.a; + } vec4 color = mix(color0, color1, u_fade_t); color.a *= u_opacity; vec3 rgb = color.rgb; diff --git a/src/mbgl/style/sources/image_source.cpp b/src/mbgl/style/sources/image_source.cpp index 9313d8da4a..9b60ba1a48 100644 --- a/src/mbgl/style/sources/image_source.cpp +++ b/src/mbgl/style/sources/image_source.cpp @@ -37,7 +37,7 @@ void ImageSource::setURL(const std::string& url_) { } } -void ImageSource::setImage(UnassociatedImage&& image_) { +void ImageSource::setImage(PremultipliedImage&& image_) { url = {}; if (req) { req.reset(); @@ -70,8 +70,7 @@ void ImageSource::loadDescription(FileSource& fileSource) { observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty image url"))); } else { try { - UnassociatedImage image = util::unpremultiply(decodeImage(*res.data)); - baseImpl = makeMutable(impl(), std::move(image)); + baseImpl = makeMutable(impl(), decodeImage(*res.data)); } catch (...) { observer->onSourceError(*this, std::current_exception()); } diff --git a/src/mbgl/style/sources/image_source_impl.cpp b/src/mbgl/style/sources/image_source_impl.cpp index eb3e2635e5..c1f31dbdc6 100644 --- a/src/mbgl/style/sources/image_source_impl.cpp +++ b/src/mbgl/style/sources/image_source_impl.cpp @@ -15,14 +15,14 @@ ImageSource::Impl::Impl(const Impl& other, std::array coords_) image(other.image) { } -ImageSource::Impl::Impl(const Impl& rhs, UnassociatedImage&& image_) +ImageSource::Impl::Impl(const Impl& rhs, PremultipliedImage&& image_) : Source::Impl(rhs), coords(rhs.coords), - image(std::make_shared(std::move(image_))) { + image(std::make_shared(std::move(image_))) { } ImageSource::Impl::~Impl() = default; -std::shared_ptr ImageSource::Impl::getImage() const { +std::shared_ptr ImageSource::Impl::getImage() const { return image; } diff --git a/src/mbgl/style/sources/image_source_impl.hpp b/src/mbgl/style/sources/image_source_impl.hpp index e0999c34a5..1e1b005a32 100644 --- a/src/mbgl/style/sources/image_source_impl.hpp +++ b/src/mbgl/style/sources/image_source_impl.hpp @@ -13,17 +13,17 @@ class ImageSource::Impl : public Source::Impl { public: Impl(std::string id, std::array coords); Impl(const Impl& rhs, std::array coords); - Impl(const Impl& rhs, UnassociatedImage&& image); + Impl(const Impl& rhs, PremultipliedImage&& image); ~Impl() final; - std::shared_ptr getImage() const; + std::shared_ptr getImage() const; std::array getCoordinates() const; optional getAttribution() const final; private: std::array coords; - std::shared_ptr image; + std::shared_ptr image; }; } // namespace style diff --git a/src/mbgl/tile/raster_tile_worker.cpp b/src/mbgl/tile/raster_tile_worker.cpp index 86fb5f181d..3c8af97b40 100644 --- a/src/mbgl/tile/raster_tile_worker.cpp +++ b/src/mbgl/tile/raster_tile_worker.cpp @@ -17,7 +17,7 @@ void RasterTileWorker::parse(std::shared_ptr data) { } try { - auto bucket = std::make_unique(util::unpremultiply(decodeImage(*data))); + auto bucket = std::make_unique(decodeImage(*data)); parent.invoke(&RasterTile::onParsed, std::move(bucket)); } catch (...) { parent.invoke(&RasterTile::onError, std::current_exception()); diff --git a/test/gl/bucket.test.cpp b/test/gl/bucket.test.cpp index 24bec0bd22..7ff67f40d0 100644 --- a/test/gl/bucket.test.cpp +++ b/test/gl/bucket.test.cpp @@ -101,7 +101,7 @@ TEST(Buckets, SymbolBucket) { TEST(Buckets, RasterBucket) { gl::Context context; - UnassociatedImage rgba({ 1, 1 }); + PremultipliedImage rgba({ 1, 1 }); // RasterBucket::hasData() is always true. RasterBucket bucket = { std::move(rgba) }; diff --git a/test/style/source.test.cpp b/test/style/source.test.cpp index d576dc1e4a..8b9cda1db3 100644 --- a/test/style/source.test.cpp +++ b/test/style/source.test.cpp @@ -531,7 +531,7 @@ TEST(Source, ImageSourceImageUpdate) { // Load initial, so the source state will be loaded=true source.loadDescription(test.fileSource); - UnassociatedImage rgba({ 1, 1 }); + PremultipliedImage rgba({ 1, 1 }); rgba.data[0] = 255; rgba.data[1] = 254; rgba.data[2] = 253; diff --git a/test/tile/raster_tile.test.cpp b/test/tile/raster_tile.test.cpp index 025208c331..4680e7f485 100644 --- a/test/tile/raster_tile.test.cpp +++ b/test/tile/raster_tile.test.cpp @@ -60,7 +60,7 @@ TEST(RasterTile, onError) { TEST(RasterTile, onParsed) { RasterTileTest test; RasterTile tile(OverscaledTileID(0, 0, 0), test.tileParameters, test.tileset); - tile.onParsed(std::make_unique(UnassociatedImage{})); + tile.onParsed(std::make_unique(PremultipliedImage{})); EXPECT_TRUE(tile.isRenderable()); EXPECT_TRUE(tile.isLoaded()); EXPECT_TRUE(tile.isComplete()); -- cgit v1.2.1 From e35cbbae55ab01f33690b1bb2e918c5f8393b854 Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Thu, 22 Jun 2017 14:33:21 -0700 Subject: [core] mutate style on annotation mutations immediately --- src/mbgl/annotation/annotation_manager.cpp | 87 +++++++++++++----------------- src/mbgl/annotation/annotation_manager.hpp | 20 ++++--- src/mbgl/map/map.cpp | 20 ++++--- src/mbgl/map/update.hpp | 1 - test/style/source.test.cpp | 4 +- test/tile/annotation_tile.test.cpp | 8 +-- test/tile/geojson_tile.test.cpp | 4 +- test/tile/raster_tile.test.cpp | 4 +- test/tile/vector_tile.test.cpp | 4 +- 9 files changed, 77 insertions(+), 75 deletions(-) diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp index a69dba1bf2..ec5a360a90 100644 --- a/src/mbgl/annotation/annotation_manager.cpp +++ b/src/mbgl/annotation/annotation_manager.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -18,9 +19,20 @@ using namespace style; const std::string AnnotationManager::SourceID = "com.mapbox.annotations"; const std::string AnnotationManager::PointLayerID = "com.mapbox.annotations.points"; -AnnotationManager::AnnotationManager() = default; +AnnotationManager::AnnotationManager(Style& style_) + : style(style_) { +}; + AnnotationManager::~AnnotationManager() = default; +void AnnotationManager::setStyle(Style& style_) { + style = style_; +} + +void AnnotationManager::onStyleLoaded() { + updateStyle(); +} + AnnotationID AnnotationManager::addAnnotation(const Annotation& annotation, const uint8_t maxZoom) { std::lock_guard lock(mutex); AnnotationID id = nextID++; @@ -51,13 +63,13 @@ void AnnotationManager::add(const AnnotationID& id, const SymbolAnnotation& anno void AnnotationManager::add(const AnnotationID& id, const LineAnnotation& annotation, const uint8_t maxZoom) { ShapeAnnotationImpl& impl = *shapeAnnotations.emplace(id, std::make_unique(id, annotation, maxZoom)).first->second; - obsoleteShapeAnnotationLayers.erase(impl.layerID); + impl.updateStyle(*style.get().impl); } void AnnotationManager::add(const AnnotationID& id, const FillAnnotation& annotation, const uint8_t maxZoom) { ShapeAnnotationImpl& impl = *shapeAnnotations.emplace(id, std::make_unique(id, annotation, maxZoom)).first->second; - obsoleteShapeAnnotationLayers.erase(impl.layerID); + impl.updateStyle(*style.get().impl); } Update AnnotationManager::update(const AnnotationID& id, const SymbolAnnotation& annotation, const uint8_t maxZoom) { @@ -71,16 +83,11 @@ Update AnnotationManager::update(const AnnotationID& id, const SymbolAnnotation& const SymbolAnnotation& existing = it->second->annotation; - if (existing.geometry != annotation.geometry) { + if (existing.geometry != annotation.geometry || existing.icon != annotation.icon) { result |= Update::AnnotationData; - } - - if (existing.icon != annotation.icon) { - result |= Update::AnnotationData | Update::AnnotationStyle; - } - if (result != Update::Nothing) { - removeAndAdd(id, annotation, maxZoom); + remove(id); + add(id, annotation, maxZoom); } return result; @@ -93,8 +100,9 @@ Update AnnotationManager::update(const AnnotationID& id, const LineAnnotation& a return Update::Nothing; } - removeAndAdd(id, annotation, maxZoom); - return Update::AnnotationData | Update::AnnotationStyle; + shapeAnnotations.erase(it); + add(id, annotation, maxZoom); + return Update::AnnotationData; } Update AnnotationManager::update(const AnnotationID& id, const FillAnnotation& annotation, const uint8_t maxZoom) { @@ -104,15 +112,9 @@ Update AnnotationManager::update(const AnnotationID& id, const FillAnnotation& a return Update::Nothing; } - removeAndAdd(id, annotation, maxZoom); - return Update::AnnotationData | Update::AnnotationStyle; -} - -void AnnotationManager::removeAndAdd(const AnnotationID& id, const Annotation& annotation, const uint8_t maxZoom) { - remove(id); - Annotation::visit(annotation, [&] (const auto& annotation_) { - this->add(id, annotation_, maxZoom); - }); + shapeAnnotations.erase(it); + add(id, annotation, maxZoom); + return Update::AnnotationData; } void AnnotationManager::remove(const AnnotationID& id) { @@ -120,8 +122,9 @@ void AnnotationManager::remove(const AnnotationID& id) { symbolTree.remove(symbolAnnotations.at(id)); symbolAnnotations.erase(id); } else if (shapeAnnotations.find(id) != shapeAnnotations.end()) { - obsoleteShapeAnnotationLayers.insert(shapeAnnotations.at(id)->layerID); - shapeAnnotations.erase(id); + auto it = shapeAnnotations.find(id); + *style.get().impl->removeLayer(it->second->layerID); + shapeAnnotations.erase(it); } else { assert(false); // Should never happen } @@ -149,11 +152,11 @@ std::unique_ptr AnnotationManager::getTileData(const Canonic return tileData; } -void AnnotationManager::updateStyle(Style::Impl& style) { +void AnnotationManager::updateStyle() { // Create annotation source, point layer, and point bucket. We do everything via Style::Impl // because we don't want annotation mutations to trigger Style::Impl::styleMutated to be set. - if (!style.getSource(SourceID)) { - style.addSource(std::make_unique()); + if (!style.get().impl->getSource(SourceID)) { + style.get().impl->addSource(std::make_unique()); std::unique_ptr layer = std::make_unique(PointLayerID, SourceID); @@ -162,13 +165,13 @@ void AnnotationManager::updateStyle(Style::Impl& style) { layer->setIconAllowOverlap(true); layer->setIconIgnorePlacement(true); - style.addLayer(std::move(layer)); + style.get().impl->addLayer(std::move(layer)); } std::lock_guard lock(mutex); for (const auto& shape : shapeAnnotations) { - shape.second->updateStyle(style); + shape.second->updateStyle(*style.get().impl); } for (const auto& image : images) { @@ -178,23 +181,8 @@ void AnnotationManager::updateStyle(Style::Impl& style) { // of which images need to be added because we don't know if the style is the same // instance as in the last updateStyle call. If it's a new style, we need to add all // images.) - style.addImage(std::make_unique(image.second)); - } - - for (const auto& layer : obsoleteShapeAnnotationLayers) { - if (style.getLayer(layer)) { - style.removeLayer(layer); - } - } - - for (const auto& image : obsoleteImages) { - if (style.getImage(image)) { - style.removeImage(image); - } + style.get().impl->addImage(std::make_unique(image.second)); } - - obsoleteShapeAnnotationLayers.clear(); - obsoleteImages.clear(); } void AnnotationManager::updateData() { @@ -225,16 +213,17 @@ void AnnotationManager::addImage(std::unique_ptr image) { std::lock_guard lock(mutex); const std::string id = prefixedImageID(image->getID()); images.erase(id); - images.emplace(id, - style::Image(id, image->getImage().clone(), image->getPixelRatio(), image->isSdf())); - obsoleteImages.erase(id); + auto inserted = images.emplace(id, style::Image(id, image->getImage().clone(), + image->getPixelRatio(), image->isSdf())); + + style.get().impl->addImage(std::make_unique(inserted.first->second)); } void AnnotationManager::removeImage(const std::string& id_) { std::lock_guard lock(mutex); const std::string id = prefixedImageID(id_); images.erase(id); - obsoleteImages.insert(id); + style.get().impl->removeImage(id); } double AnnotationManager::getTopOffsetPixelsForImage(const std::string& id_) { diff --git a/src/mbgl/annotation/annotation_manager.hpp b/src/mbgl/annotation/annotation_manager.hpp index 6906791db7..dee823bc0f 100644 --- a/src/mbgl/annotation/annotation_manager.hpp +++ b/src/mbgl/annotation/annotation_manager.hpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include @@ -21,9 +20,13 @@ class AnnotationTileData; class SymbolAnnotationImpl; class ShapeAnnotationImpl; +namespace style { +class Style; +} // namespace style + class AnnotationManager : private util::noncopyable { public: - AnnotationManager(); + AnnotationManager(style::Style&); ~AnnotationManager(); AnnotationID addAnnotation(const Annotation&, const uint8_t maxZoom); @@ -34,7 +37,9 @@ public: void removeImage(const std::string&); double getTopOffsetPixelsForImage(const std::string&); - void updateStyle(style::Style::Impl&); + void setStyle(style::Style&); + void onStyleLoaded(); + void updateData(); void addTile(AnnotationTile&); @@ -52,12 +57,14 @@ private: Update update(const AnnotationID&, const LineAnnotation&, const uint8_t); Update update(const AnnotationID&, const FillAnnotation&, const uint8_t); - void removeAndAdd(const AnnotationID&, const Annotation&, const uint8_t); - void remove(const AnnotationID&); + void updateStyle(); + std::unique_ptr getTileData(const CanonicalTileID&); + std::reference_wrapper style; + std::mutex mutex; AnnotationID nextID = 0; @@ -73,8 +80,7 @@ private: SymbolAnnotationMap symbolAnnotations; ShapeAnnotationMap shapeAnnotations; ImageMap images; - std::unordered_set obsoleteShapeAnnotationLayers; - std::unordered_set obsoleteImages; + std::unordered_set tiles; friend class AnnotationTile; diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 26795f7814..e644f91c4f 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -87,11 +87,12 @@ public: Update updateFlags = Update::Nothing; - AnnotationManager annotationManager; std::unique_ptr painter; std::unique_ptr \ No newline at end of file diff --git a/common/mb-icon-blue-square.png b/common/mb-icon-blue-square.png deleted file mode 100644 index 0a9bc1cdea..0000000000 Binary files a/common/mb-icon-blue-square.png and /dev/null differ diff --git a/common/mb-icon-blue-square.svg b/common/mb-icon-blue-square.svg deleted file mode 100644 index de531b179b..0000000000 --- a/common/mb-icon-blue-square.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - diff --git a/deps/ninja/ninja-linux b/deps/ninja/ninja-linux deleted file mode 100755 index e4a6202d99..0000000000 Binary files a/deps/ninja/ninja-linux and /dev/null differ diff --git a/deps/ninja/ninja-macos b/deps/ninja/ninja-macos deleted file mode 100755 index 64fcacc550..0000000000 Binary files a/deps/ninja/ninja-macos and /dev/null differ diff --git a/deps/run_gyp b/deps/run_gyp deleted file mode 100755 index f25d50a5dd..0000000000 --- a/deps/run_gyp +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env python -import sys -import os.path -sys.path.insert(1, os.path.join(os.path.dirname(sys.argv[0]), 'gyp', 'pylib')) -import gyp - -if __name__ == '__main__': - sys.exit(gyp.script_main()) diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index 64f1ca3c87..0000000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM ubuntu:12.04 - -ENV DEBIAN_FRONTEND noninteractive - -# Add other APT sources and keys -ADD *.list /etc/apt/sources.list.d/ -ADD *.gpg.key /tmp/ -RUN find /tmp/*.gpg.key | xargs -n1 apt-key add - -# Recreate Travis CI environment -RUN apt-get update -y -RUN apt-get install -y git-core python-pip curl automake libtool make cmake pkg-config python-pip \ - libc6 libstdc++6 zlib1g-dev libcurl4-openssl-dev libpng-dev libsqlite3-dev \ - xvfb libglu1-mesa-dev libxrandr-dev libxinerama-dev libxi-dev libxcursor-dev xutils-dev \ - mesa-utils libxxf86vm-dev x11proto-xf86vidmode-dev cmake && \ - pip install awscli diff --git a/docker/bitrise/android/Dockerfile b/docker/bitrise/android/Dockerfile deleted file mode 100644 index 264fa01b98..0000000000 --- a/docker/bitrise/android/Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -FROM bitriseio/android-ndk:latest - -# Install Google Cloud SDK for Firebase -RUN set -eu && \ - (echo "deb http://packages.cloud.google.com/apt cloud-sdk-$(lsb_release -c -s) main" | sudo tee /etc/apt/sources.list.d/google-cloud-sdk.list) && \ - (curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -) && \ - sudo apt-get update && \ - sudo apt-get install -y google-cloud-sdk python-dev python-setuptools ccache && \ - sudo apt-get clean && \ - sudo easy_install -U pip && \ - pip install --no-cache-dir awscli && \ - mkdir -p "${ANDROID_HOME}/licenses" && \ - (echo "8933bad161af4178b1185d1a37fbf41ea5269c55" > "${ANDROID_HOME}/licenses/android-sdk-license") - -RUN set -eu && \ - git clone --depth=1 "https://github.com/mapbox/mapbox-gl-native.git" . && \ - ccache -z && \ - BUILDTYPE=Debug make android-test-lib-arm-v7 && \ - BUILDTYPE=Debug make android-checkstyle && \ - ccache -s && \ - cd .. && rm -rf src && mkdir src diff --git a/docker/build.sh b/docker/build.sh deleted file mode 100755 index c6eb1b110d..0000000000 --- a/docker/build.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -#!/usr/bin/env bash - -set -e -set -o pipefail - -docker build -t mapbox/gl-native:travis docker diff --git a/docker/clang-tidy/Dockerfile b/docker/clang-tidy/Dockerfile deleted file mode 100644 index c880391592..0000000000 --- a/docker/clang-tidy/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -FROM mapbox/gl-native:travis - -# Install compiler -RUN apt-get -y install clang-3.8 lldb-3.8 clang-tidy-3.8 clang-format-3.8 - -RUN useradd -ms /bin/bash mapbox -USER mapbox -ENV HOME /home/mapbox -WORKDIR /home/mapbox diff --git a/docker/clang-tidy/run.sh b/docker/clang-tidy/run.sh deleted file mode 100755 index 421aca9700..0000000000 --- a/docker/clang-tidy/run.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -./docker/build.sh - -docker build -t mapbox/gl-native:clang-tidy docker/clang-tidy - -docker run \ - -i \ - -v `pwd`:/home/mapbox/build \ - -t mapbox/gl-native:clang-tidy \ - build/docker/clang-tidy/tidy.sh diff --git a/docker/clang-tidy/tidy.sh b/docker/clang-tidy/tidy.sh deleted file mode 100755 index 4c1b74595a..0000000000 --- a/docker/clang-tidy/tidy.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash - -# set -e -# set -o pipefail - -export CXX=clang++-3.8 -export BUILDTYPE=Release - -cd build - -# before_install -source ./scripts/travis_helper.sh - -# install -./platform/linux/scripts/install.sh - -export CLANG_TIDY=clang-tidy-3.8 -make tidy diff --git a/docker/george-edison55-precise-backports.gpg.key b/docker/george-edison55-precise-backports.gpg.key deleted file mode 100644 index 69971cfce8..0000000000 --- a/docker/george-edison55-precise-backports.gpg.key +++ /dev/null @@ -1,13 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: SKS 1.1.5 -Comment: Hostname: keyserver.ubuntu.com - -mI0ETFYUegEEAMF062ZPYWxX0blpJpLCz/oEXwvxJoQg1Sz4uD4Fs1FCfRwHMlydwbGvEjEr -QG39OXf1y1+lGVI73BLcuDd/n0yBLN9brycDspZKnQ25VaRB6sl8EDR8XM5tiA/diW1EIygS -Ad/NuwXv236e+1E+zvik6faeoxygJbbj0KN67Hx7ABEBAAG0HUxhdW5jaHBhZCBHZW9yZ2Ug -RWRpc29uJ3MgUFBBiLYEEwECACAFAkxWFHoCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAK -CRAITs/Fgoq3JpJ0A/9RquDizs5oUhyqqT4t4EHEIH9+ckl/3cQj0peN5APA5TOqAS4iVxic -GO3YB7yY4a+v5qQUalOMNAQRUigi3IwCcOSs94Bt5f7lK6xbU7mIO2D5a7cUCjN36FXe+oWp -4s5odz5+9OZrIVzJw/NOdgneLqh2ts5jWGYmOg7POJk9mQ== -=ItbQ ------END PGP PUBLIC KEY BLOCK----- diff --git a/docker/george-edison55-precise-backports.list b/docker/george-edison55-precise-backports.list deleted file mode 100644 index 2bae784dd6..0000000000 --- a/docker/george-edison55-precise-backports.list +++ /dev/null @@ -1,2 +0,0 @@ -deb http://ppa.launchpad.net/george-edison55/precise-backports/ubuntu precise main -deb-src http://ppa.launchpad.net/george-edison55/precise-backports/ubuntu precise main diff --git a/docker/linux/Dockerfile b/docker/linux/Dockerfile deleted file mode 100644 index c797082d93..0000000000 --- a/docker/linux/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM mapbox/gl-native:travis - -# Install compiler -RUN apt-get -y install gdb g++-5 gcc-5 libllvm3.4 - -RUN useradd -ms /bin/bash mapbox -USER mapbox -ENV HOME /home/mapbox -WORKDIR /home/mapbox - -# Node -RUN git clone https://github.com/creationix/nvm.git ~/.nvm && \ - . ~/.nvm/nvm.sh && \ - NVM_DIR=~/.nvm nvm install 4.4.5 diff --git a/docker/linux/run.sh b/docker/linux/run.sh deleted file mode 100755 index 3d41843cf2..0000000000 --- a/docker/linux/run.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -./docker/build.sh - -docker build -t mapbox/gl-native:linux docker/linux - -docker run \ - -i \ - -v `pwd`:/home/mapbox/build \ - -t mapbox/gl-native:linux \ - build/docker/linux/test.sh diff --git a/docker/linux/test.sh b/docker/linux/test.sh deleted file mode 100755 index 207f7679cf..0000000000 --- a/docker/linux/test.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash - -# set -e -# set -o pipefail - -export _CXX=g++-5 -export _CC=gcc-5 -export BUILDTYPE=Release - -# Node -. ~/.nvm/nvm.sh -nvm use 4.4.5 - -# Xvfb -start-stop-daemon --start --pidfile ~/xvfb.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 1024x768x24 -ac +extension GLX +render -noreset - -cd build - -# before_install -source ./scripts/travis_helper.sh -source ./scripts/travis_setup.sh - -make linux -make test diff --git a/docker/ubuntu-toolchain-r.gpg.key b/docker/ubuntu-toolchain-r.gpg.key deleted file mode 100644 index 854eef8520..0000000000 --- a/docker/ubuntu-toolchain-r.gpg.key +++ /dev/null @@ -1,13 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: SKS 1.1.5 -Comment: Hostname: keyserver.ubuntu.com - -mI0ESuBvRwEEAMi4cDba7xlKaaoXjO1n1HX8RKrkW+HEIl79nSOSJyvzysajs7zUow/OzCQp -9NswqrDmNuH1+lPTTRNAGtK8r2ouq2rnXT1mTl23dpgHZ9spseR73s4ZBGw/ag4bpU5dNUSt -vfmHhIjVCuiSpNn7cyy1JSSvSs3N2mxteKjXLBf7ABEBAAG0GkxhdW5jaHBhZCBUb29sY2hh -aW4gYnVpbGRziLYEEwECACAFAkrgb0cCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRAe -k3eiup7yfzGKA/4xzUqNACSlB+k+DxFFHqkwKa/ziFiAlkLQyyhm+iqz80htRZr7Ls/ZRYZl -0aSU56/hLe0V+TviJ1s8qdN2lamkKdXIAFfavA04nOnTzyIBJ82EAUT3Nh45skMxo4z4iZMN -msyaQpNl/m/lNtOLhR64v5ZybofB2EWkMxUzX8D/FQ== -=LcUQ ------END PGP PUBLIC KEY BLOCK----- \ No newline at end of file diff --git a/docker/ubuntu-toolchain-r.list b/docker/ubuntu-toolchain-r.list deleted file mode 100644 index 741f4528e2..0000000000 --- a/docker/ubuntu-toolchain-r.list +++ /dev/null @@ -1,2 +0,0 @@ -deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu precise main -deb-src http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu precise main \ No newline at end of file diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md deleted file mode 100644 index 9832b5da0a..0000000000 --- a/docs/TROUBLESHOOTING.md +++ /dev/null @@ -1,5 +0,0 @@ -# Troubleshooting - -To trigger a complete rebuild, run `make clean`. - -If you are having trouble getting the dependencies right, you can blow away the `mason_packages` directory, or run `make distclean`. This means the `Makefile` and configure script will automatically install the dependencies again on the next try. diff --git a/misc/bench-icon.svg b/misc/bench-icon.svg new file mode 100644 index 0000000000..28df6f600d --- /dev/null +++ b/misc/bench-icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/misc/ca-bundle.crt b/misc/ca-bundle.crt new file mode 100644 index 0000000000..6fd701b72c --- /dev/null +++ b/misc/ca-bundle.crt @@ -0,0 +1,3646 @@ +## +## Bundle of CA Root Certificates +## +## Certificate data from Mozilla as of: Wed Dec 13 12:22:38 2017 GMT +## +## This is a bundle of X.509 certificates of public Certificate Authorities +## (CA). These were automatically extracted from Mozilla's root certificates +## file (certdata.txt). This file can be found in the mozilla source tree: +## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt +## +## It contains the certificates in PEM format and therefore +## can be directly used with curl / libcurl / php_curl, or with +## an Apache+mod_ssl webserver for SSL client authentication. +## Just configure this file as the SSLCACertificateFile. +## +## Conversion done with mk-ca-bundle.pl version 1.27. +## SHA256: 2b2dbe5244e0047e088c597998883a913f6c5fffd1cb5c0fe5a368c8466cb2ec +## + + +GlobalSign Root CA +================== +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx +GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds +b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV +BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD +VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa +DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc +THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb +Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP +c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX +gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF +AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj +Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG +j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH +hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC +X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +GlobalSign Root CA - R2 +======================= +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv +YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh +bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT +aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln +bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6 +ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp +s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN +S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL +TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C +ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i +YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN +BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp +9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu +01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7 +9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- + +Verisign Class 3 Public Primary Certification Authority - G3 +============================================================ +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy +dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1 +EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc +cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw +EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj +055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA +ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f +j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC +/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0 +xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa +t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== +-----END CERTIFICATE----- + +Entrust.net Premium 2048 Secure Server CA +========================================= +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u +ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp +bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV +BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx +NzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3 +d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl +MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u +ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL +Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr +hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW +nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi +VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo0IwQDAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJ +KoZIhvcNAQEFBQADggEBADubj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPy +T/4xmf3IDExoU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5bu/8j72gZyxKT +J1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+bYQLCIt+jerXmCHG8+c8eS9e +nNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/ErfF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- + +Baltimore CyberTrust Root +========================= +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE +ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li +ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC +SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs +dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME +uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB +UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C +G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9 +XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr +l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI +VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB +BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh +cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5 +hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa +Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H +RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +AddTrust External Root +====================== +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD +VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw +NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU +cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg +Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821 ++iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw +Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo +aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy +2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7 +7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL +VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk +VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB +IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl +j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355 +e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u +G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE----- + +Entrust Root Certification Authority +==================================== +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV +BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw +b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG +A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0 +MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu +MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu +Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v +dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz +A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww +Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68 +j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN +rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1 +MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH +hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM +Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa +v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS +W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 +tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +GeoTrust Global CA +================== +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK +Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw +MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j +LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo +BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet +8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc +T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU +vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk +DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q +zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4 +d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2 +mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p +XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm +Mw== +-----END CERTIFICATE----- + +GeoTrust Universal CA +===================== +-----BEGIN CERTIFICATE----- +MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1 +MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu +Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t +JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e +RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs +7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d +8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V +qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga +Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB +Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu +KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08 +ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0 +XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB +hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc +aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2 +qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL +oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK +xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF +KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2 +DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK +xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU +p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI +P/rmMuGNG2+k5o7Y+SlIis5z/iw= +-----END CERTIFICATE----- + +GeoTrust Universal CA 2 +======================= +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0 +MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg +SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0 +DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17 +j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q +JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a +QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2 +WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP +20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn +ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC +SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG +8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2 ++/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E +BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z +dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ +4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+ +mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq +A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg +Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP +pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d +FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp +gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm +X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS +-----END CERTIFICATE----- + +Visa eCommerce Root +=================== +-----BEGIN CERTIFICATE----- +MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG +EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug +QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2 +WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm +VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv +bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL +F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b +RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0 +TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI +/k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs +GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG +MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc +CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW +YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz +zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu +YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt +398znM/jra6O1I7mT1GvFpLgXPYHDw== +-----END CERTIFICATE----- + +Certum Root CA +============== +-----BEGIN CERTIFICATE----- +MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQK +ExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQTAeFw0wMjA2MTExMDQ2Mzla +Fw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8u +by4xEjAQBgNVBAMTCUNlcnR1bSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6x +wS7TT3zNJc4YPk/EjG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdL +kKWoePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GIULdtlkIJ +89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapuOb7kky/ZR6By6/qmW6/K +Uz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUgAKpoC6EahQGcxEZjgoi2IrHu/qpGWX7P +NSzVttpd90gzFFS269lvzs2I1qsb2pY7HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq +hkiG9w0BAQUFAAOCAQEAuI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+ +GXYkHAQaTOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTgxSvg +GrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1qCjqTE5s7FCMTY5w/ +0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5xO/fIR/RpbxXyEV6DHpx8Uq79AtoS +qFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs6GAqm4VKQPNriiTsBhYscw== +-----END CERTIFICATE----- + +Comodo AAA Services root +======================== +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw +MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl +c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV +BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG +C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs +i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW +Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH +Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK +Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f +BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl +cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz +LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm +7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z +8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C +12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +QuoVadis Root CA +================ +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE +ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz +MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp +cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD +EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk +J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL +F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL +YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen +AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w +PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y +ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7 +MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj +YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs +ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW +Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu +BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw +FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6 +tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo +fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul +LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x +gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi +5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi +5nrQNiOKSnQ2+Q== +-----END CERTIFICATE----- + +QuoVadis Root CA 2 +================== +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT +EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx +ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6 +XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk +lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB +lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy +lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt +66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn +wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh +D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy +BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie +J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud +DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU +a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv +Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3 +UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm +VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK ++JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW +IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1 +WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X +f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II +4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8 +VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- + +QuoVadis Root CA 3 +================== +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT +EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx +OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg +DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij +KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K +DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv +BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp +p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8 +nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX +MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM +Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz +uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT +BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj +YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB +BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD +VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4 +ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE +AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV +qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s +hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z +POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2 +Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp +8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC +bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu +g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p +vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr +qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- + +Security Communication Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP +U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw +HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP +U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw +8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM +DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX +5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd +DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2 +JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g +0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a +mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ +s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ +6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi +FL39vmwLAw== +-----END CERTIFICATE----- + +Sonera Class 2 Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG +U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw +NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh +IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3 +/Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT +dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG +f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P +tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH +nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT +XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt +0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI +cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph +Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx +EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH +llpwrN9M +-----END CERTIFICATE----- + +Camerfirma Chambers of Commerce Root +==================================== +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe +QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i +ZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAx +NjEzNDNaFw0zNzA5MzAxNjEzNDRaMH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZp +cm1hIFNBIENJRiBBODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3Jn +MSIwIAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0BAQEFAAOC +AQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtbunXF/KGIJPov7coISjlU +xFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0dBmpAPrMMhe5cG3nCYsS4No41XQEMIwRH +NaqbYE6gZj3LJgqcQKH0XZi/caulAGgq7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jW +DA+wWFjbw2Y3npuRVDM30pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFV +d9oKDMyXroDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIGA1Ud +EwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5jaGFtYmVyc2lnbi5v +cmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p26EpW1eLTXYGduHRooowDgYDVR0P +AQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hh +bWJlcnNpZ24ub3JnMCcGA1UdEgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYD +VR0gBFEwTzBNBgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz +aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEBAAxBl8IahsAi +fJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZdp0AJPaxJRUXcLo0waLIJuvvD +L8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wN +UPf6s+xCX6ndbcj0dc97wXImsQEcXCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/n +ADydb47kMgkdTXg0eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1 +erfutGWaIZDgqtCYvDi1czyL+Nw= +-----END CERTIFICATE----- + +Camerfirma Global Chambersign Root +================================== +-----BEGIN CERTIFICATE----- +MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe +QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i +ZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYx +NDE4WhcNMzcwOTMwMTYxNDE4WjB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJt +YSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEg +MB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUAA4IBDQAw +ggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0Mi+ITaFgCPS3CU6gSS9J +1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/sQJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8O +by4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpVeAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl +6DJWk0aJqCWKZQbua795B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c +8lCrEqWhz0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0TAQH/ +BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1iZXJzaWduLm9yZy9j +aGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4wTcbOX60Qq+UDpfqpFDAOBgNVHQ8B +Af8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAHMCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBj +aGFtYmVyc2lnbi5vcmcwKgYDVR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9y +ZzBbBgNVHSAEVDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh +bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0BAQUFAAOCAQEA +PDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUMbKGKfKX0j//U2K0X1S0E0T9Y +gOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXiryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJ +PJ7oKXqJ1/6v/2j1pReQvayZzKWGVwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4 +IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes +t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== +-----END CERTIFICATE----- + +XRamp Global CA Root +==================== +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE +BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj +dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx +HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg +U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu +IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx +foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE +zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs +AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry +xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap +oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC +AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc +/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n +nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz +8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +Go Daddy Class 2 CA +=================== +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY +VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG +A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g +RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD +ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv +2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32 +qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j +YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY +vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O +BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o +atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu +MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG +A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim +PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt +I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI +Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b +vZ8= +-----END CERTIFICATE----- + +Starfield Class 2 CA +==================== +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc +U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo +MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG +A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG +SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY +bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ +JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm +epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN +F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF +MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f +hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo +bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g +QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs +afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM +PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD +KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3 +QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +StartCom Certification Authority +================================ +-----BEGIN CERTIFICATE----- +MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu +ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 +NjM2WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk +LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg +U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y +o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ +Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d +eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt +2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z +6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ +osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ +untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc +UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT +37uMdBNSSwIDAQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE +FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9jZXJ0LnN0YXJ0 +Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3JsLnN0YXJ0Y29tLm9yZy9zZnNj +YS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFMBgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUH +AgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRw +Oi8vY2VydC5zdGFydGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYg +U3RhcnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlhYmlsaXR5 +LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2YgdGhlIFN0YXJ0Q29tIENl +cnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFpbGFibGUgYXQgaHR0cDovL2NlcnQuc3Rh +cnRjb20ub3JnL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilT +dGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOC +AgEAFmyZ9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8jhvh +3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUWFjgKXlf2Ysd6AgXm +vB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJzewT4F+irsfMuXGRuczE6Eri8sxHk +fY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3 +fsNrarnDy0RLrHiQi+fHLB5LEUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZ +EoalHmdkrQYuL6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq +yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuCO3NJo2pXh5Tl +1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6Vum0ABj6y6koQOdjQK/W/7HW/ +lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkyShNOsF/5oirpt9P/FlUQqmMGqz9IgcgA38coro +g14= +-----END CERTIFICATE----- + +Taiwan GRCA +=========== +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG +EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X +DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv +dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN +w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5 +BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O +1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO +htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov +J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7 +Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t +B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB +O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8 +lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV +HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2 +09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ +TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj +Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2 +Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU +D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz +DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk +Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk +7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ +CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy ++fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS +-----END CERTIFICATE----- + +DigiCert Assured ID Root CA +=========================== +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw +IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx +MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL +ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO +9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy +UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW +/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy +oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf +GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF +66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq +hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc +EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn +SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i +8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +DigiCert Global Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw +HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw +MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 +dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn +TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5 +BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H +4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y +7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB +o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm +8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF +BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr +EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt +tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886 +UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +DigiCert High Assurance EV Root CA +================================== +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw +KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw +MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ +MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu +Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t +Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS +OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3 +MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ +NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe +h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB +Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY +JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ +V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp +myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK +mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K +-----END CERTIFICATE----- + +Certplus Class 2 Primary CA +=========================== +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE +BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN +OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy +dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR +5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ +Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO +YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e +e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME +CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ +YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t +L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD +P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R +TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+ +7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW +//1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 +l7+ijrRU +-----END CERTIFICATE----- + +DST Root CA X3 +============== +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK +ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X +DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1 +cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT +rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9 +UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy +xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d +utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ +MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug +dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE +GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw +RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS +fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----END CERTIFICATE----- + +DST ACES CA X6 +============== +-----BEGIN CERTIFICATE----- +MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QxETAPBgNVBAsTCERTVCBBQ0VT +MRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0wMzExMjAyMTE5NThaFw0xNzExMjAyMTE5NTha +MFsxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UE +CxMIRFNUIEFDRVMxFzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPuktKe1jzI +DZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7gLFViYsx+tC3dr5BPTCa +pCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZHfAjIgrrep4c9oW24MFbCswKBXy314pow +GCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4aahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPy +MjwmR/onJALJfh1biEITajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rkc3Qu +Y29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnRy +dXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMtaW5kZXguaHRtbDAdBgNVHQ4EFgQU +CXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZIhvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V2 +5FYrnJmQ6AgwbN99Pe7lv7UkQIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6t +Fr8hlxCBPeP/h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq +nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpRrscL9yuwNwXs +vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3 +oKfN5XozNmr6mis= +-----END CERTIFICATE----- + +SwissSign Gold CA - G2 +====================== +-----BEGIN CERTIFICATE----- +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw +EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN +MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp +c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq +t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C +jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg +vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF +ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR +AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend +jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO +peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR +7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi +GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64 +OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm +5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr +44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf +Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m +Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp +mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk +vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf +KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br +NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj +viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ +-----END CERTIFICATE----- + +SwissSign Silver CA - G2 +======================== +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT +BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X +DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3 +aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG +9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644 +N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm ++/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH +6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu +MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h +qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5 +FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs +ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc +celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X +CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB +tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P +4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F +kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L +3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx +/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa +DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP +e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu +WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ +DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub +DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority +======================================== +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx +CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ +cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN +b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9 +nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge +RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt +tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI +hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K +Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN +NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa +Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG +1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= +-----END CERTIFICATE----- + +thawte Primary Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE +BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 +aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3 +MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg +SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv +KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT +FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs +oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ +1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc +q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K +aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p +afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF +AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE +uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89 +jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH +z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA== +-----END CERTIFICATE----- + +VeriSign Class 3 Public Primary Certification Authority - G5 +============================================================ +-----BEGIN CERTIFICATE----- +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE +BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO +ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk +IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln +biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh +dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt +YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz +j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD +Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ +Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r +fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv +Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG +SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+ +X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE +KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC +Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE +ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq +-----END CERTIFICATE----- + +SecureTrust CA +============== +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy +dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe +BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX +OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t +DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH +GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b +01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH +ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj +aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ +KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu +SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf +mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ +nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +Secure Global CA +================ +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH +bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg +MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg +Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx +YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ +bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g +8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV +HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi +0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn +oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA +MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+ +OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn +CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5 +3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +COMODO Certification Authority +============================== +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE +BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG +A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb +MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD +T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH ++7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww +xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV +4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA +1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI +rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k +b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC +AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP +OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc +IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN ++8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ== +-----END CERTIFICATE----- + +Network Solutions Certificate Authority +======================================= +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG +EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr +IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx +MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx +jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT +aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT +crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc +/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB +AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv +bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA +A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q +4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/ +GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD +ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- + +COMODO ECC Certification Authority +================================== +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC +R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE +ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix +GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X +4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni +wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG +FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA +U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +Security Communication EV RootCA1 +================================= +-----BEGIN CERTIFICATE----- +MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMhU2VjdXJpdHkgQ29tbXVuaWNh +dGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIzMloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UE +BhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNl +Y3VyaXR5IENvbW11bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSERMqm4miO +/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gOzXppFodEtZDkBp2uoQSX +WHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4z +ZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDFMxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4 +bepJz11sS6/vmsJWXMY1VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK +9U2vP9eCOKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG +SIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HWtWS3irO4G8za+6xm +iEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZq51ihPZRwSzJIxXYKLerJRO1RuGG +Av8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDbEJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnW +mHyojf6GPgcWkuF75x3sM3Z+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEW +T1MKZPlO9L9OVL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490 +-----END CERTIFICATE----- + +OISTE WISeKey Global Root GA CA +=============================== +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE +BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG +A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH +bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD +VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw +IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5 +IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9 +Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg +Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD +d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ +/yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R +LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ +KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm +MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4 ++vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa +hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY +okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0= +-----END CERTIFICATE----- + +Certigna +======== +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw +EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3 +MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI +Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q +XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH +GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p +ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg +DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf +Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ +tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ +BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J +SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA +hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+ +ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu +PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY +1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- + +Deutsche Telekom Root CA 2 +========================== +-----BEGIN CERTIFICATE----- +MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT +RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG +A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5 +MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G +A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS +b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5 +bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI +KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY +AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK +Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV +jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV +HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr +E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy +zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8 +rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G +dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU +Cm26OWMohpLzGITY+9HPBVZkVw== +-----END CERTIFICATE----- + +Cybertrust Global Root +====================== +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li +ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4 +MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD +ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA ++Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW +0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL +AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin +89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT +8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2 +MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G +A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO +lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi +5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2 +hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T +X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW +WL1WMRJOEcgh4LMRkWXbtKaIOM5V +-----END CERTIFICATE----- + +ePKI Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG +EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx +MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq +MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs +IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi +lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv +qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX +12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O +WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+ +ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao +lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/ +vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi +Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi +MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0 +1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq +KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV +xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP +NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r +GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE +xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx +gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy +sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD +BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3 +============================================================================================================================= +-----BEGIN CERTIFICATE----- +MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRSMRgwFgYDVQQH +DA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJpbGltc2VsIHZlIFRla25vbG9q +aWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSwVEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ry +b25payB2ZSBLcmlwdG9sb2ppIEFyYcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNV +BAsMGkthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUg +S8O2ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAeFw0wNzA4 +MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIxGDAWBgNVBAcMD0dlYnpl +IC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmlsaW1zZWwgdmUgVGVrbm9sb2ppayBBcmHF +n3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBUQUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZl +IEtyaXB0b2xvamkgQXJhxZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2Ft +dSBTZXJ0aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7ZrIFNl +cnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4hgb46ezzb8R1Sf1n68yJMlaCQvEhO +Eav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yKO7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1 +xnnRFDDtG1hba+818qEhTsXOfJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR +6Oqeyjh1jmKwlZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL +hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQIDAQABo0IwQDAd +BgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmPNOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4 +N5EY3ATIZJkrGG2AA1nJrvhY0D7twyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLT +y9LQQfMmNkqblWwM7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYh +LBOhgLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5noN+J1q2M +dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI= +-----END CERTIFICATE----- + +certSIGN ROOT CA +================ +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD +VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa +Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE +CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I +JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH +rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2 +ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD +0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943 +AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B +Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB +AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8 +SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0 +x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt +vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz +TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority - G3 +============================================= +-----BEGIN CERTIFICATE----- +MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE +BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0 +IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy +eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz +NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo +YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT +LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j +K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE +c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C +IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu +dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr +2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9 +cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE +Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD +AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s +t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt +-----END CERTIFICATE----- + +thawte Primary Root CA - G2 +=========================== +-----BEGIN CERTIFICATE----- +MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC +VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu +IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg +Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV +MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG +b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt +IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS +LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5 +8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU +mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN +G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K +rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== +-----END CERTIFICATE----- + +thawte Primary Root CA - G3 +=========================== +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE +BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 +aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w +ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh +d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD +VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG +A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At +P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC ++BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY +7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW +vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ +KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK +A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu +t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC +8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm +er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A= +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority - G2 +============================================= +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu +Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1 +OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg +MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl +b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG +BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc +KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+ +EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m +ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2 +npaqBA+K +-----END CERTIFICATE----- + +VeriSign Universal Root Certification Authority +=============================================== +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE +BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO +ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk +IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u +IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj +1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP +MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72 +9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I +AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR +tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G +CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O +a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3 +Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx +Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx +P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P +wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4 +mJO37M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- + +VeriSign Class 3 Public Primary Certification Authority - G4 +============================================================ +-----BEGIN CERTIFICATE----- +MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC +VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3 +b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz +ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU +cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo +b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5 +IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8 +Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz +rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw +HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u +Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD +A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx +AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== +-----END CERTIFICATE----- + +NetLock Arany (Class Gold) Főtanúsítvány +======================================== +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G +A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610 +dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB +cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx +MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO +ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6 +c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu +0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw +/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk +H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw +fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1 +neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW +qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta +YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna +NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu +dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +Staat der Nederlanden Root CA - G2 +================================== +-----BEGIN CERTIFICATE----- +MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE +CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g +Um9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC +TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l +ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ +5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn +vWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj +CwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil +e7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR +OME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI +CT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65 +48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi +trzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737 +qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB +AAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC +ARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA +A4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz ++51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj +f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN +kqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk +CpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF +URmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb +CG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h +oKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV +IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm +66+KAQ== +-----END CERTIFICATE----- + +Hongkong Post Root CA 1 +======================= +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT +DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx +NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n +IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 +ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr +auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh +qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY +V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV +HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i +h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio +l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei +IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps +T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT +c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== +-----END CERTIFICATE----- + +SecureSign RootCA11 +=================== +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi +SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS +b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw +KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1 +cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL +TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO +wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq +g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP +O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA +bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX +t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh +OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r +bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ +Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01 +y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061 +lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +ACEDICOM Root +============= +-----BEGIN CERTIFICATE----- +MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UEAwwNQUNFRElD +T00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMB4XDTA4 +MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEWMBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoG +A1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHk +WLn709gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7XBZXehuD +YAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5PGrjm6gSSrj0RuVFCPYew +MYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAKt0SdE3QrwqXrIhWYENiLxQSfHY9g5QYb +m8+5eaA9oiM/Qj9r+hwDezCNzmzAv+YbX79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbk +HQl/Sog4P75n/TSW9R28MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTT +xKJxqvQUfecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI2Sf2 +3EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyHK9caUPgn6C9D4zq9 +2Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEaeZAwUswdbxcJzbPEHXEUkFDWug/Fq +TYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz +4SsrSbbXc6GqlPUB53NlTKxQMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU +9QHnc2VMrFAwRAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv +bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWImfQwng4/F9tqg +aHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3gvoFNTPhNahXwOf9jU8/kzJP +eGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKeI6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1Pwk +zQSulgUV1qzOMPPKC8W64iLgpq0i5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1 +ThCojz2GuHURwCRiipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oI +KiMnMCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZo5NjEFIq +nxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6zqylfDJKZ0DcMDQj3dcE +I2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacNGHk0vFQYXlPKNFHtRQrmjseCNj6nOGOp +MCwXEGCSn1WHElkQwg9naRHMTh5+Spqtr0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3o +tkYNbn5XOmeUwssfnHdKZ05phkOTOPu220+DkdRgfks+KzgHVZhepA== +-----END CERTIFICATE----- + +Microsec e-Szigno Root CA 2009 +============================== +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER +MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv +c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE +BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt +U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA +fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG +0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA +pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm +1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC +AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf +QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE +FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o +lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX +I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02 +yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi +LXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +GlobalSign Root CA - R3 +======================= +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv +YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh +bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT +aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln +bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt +iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ +0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3 +rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl +OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2 +xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7 +lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8 +EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E +bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18 +YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r +kpeDMdmztcpHWD9f +-----END CERTIFICATE----- + +Autoridad de Certificacion Firmaprofesional CIF A62634068 +========================================================= +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA +BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 +MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw +QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB +NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD +Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P +B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY +7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH +ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI +plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX +MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX +LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK +bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU +vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud +EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH +DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA +bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx +ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx +51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk +R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP +T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f +Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl +osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR +crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR +saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD +KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi +6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- + +Izenpe.com +========== +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG +EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz +MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu +QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ +03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK +ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU ++zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC +PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT +OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK +F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK +0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+ +0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB +leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID +AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+ +SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG +NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O +BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l +Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga +kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q +hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs +g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5 +aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5 +nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC +ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo +Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z +WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- + +Chambers of Commerce Root - 2008 +================================ +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD +MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv +bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu +QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy +Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl +ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF +EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl +cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA +XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj +h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/ +ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk +NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g +D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331 +lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ +0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2 +EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI +G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ +BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh +bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh +bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC +CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH +AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1 +wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH +3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU +RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6 +M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1 +YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF +9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK +zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG +nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ +-----END CERTIFICATE----- + +Global Chambersign Root - 2008 +============================== +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD +MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv +bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu +QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx +NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg +Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ +QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf +VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf +XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0 +ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB +/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA +TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M +H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe +Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF +HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB +AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT +BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE +BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm +aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm +aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp +1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0 +dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG +/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6 +ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s +dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg +9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH +foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du +qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr +P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq +c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----END CERTIFICATE----- + +Go Daddy Root Certificate Authority - G2 +======================================== +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu +MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G +A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq +9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD ++qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd +fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl +NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9 +BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac +vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r +5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV +N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1 +-----END CERTIFICATE----- + +Starfield Root Certificate Authority - G2 +========================================= +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 +eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw +DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg +VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB +dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv +W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs +bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk +N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf +ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU +JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol +TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx +4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw +F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ +c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +Starfield Services Root Certificate Authority - G2 +================================================== +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl +IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT +dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg +Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2 +h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa +hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP +LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB +rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG +SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP +E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy +xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza +YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6 +-----END CERTIFICATE----- + +AffirmTrust Commercial +====================== +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw +MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly +bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb +DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV +C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6 +BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww +MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV +HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG +hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi +qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv +0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh +sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +AffirmTrust Networking +====================== +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw +MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly +bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE +Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI +dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24 +/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb +h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV +HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu +UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6 +12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23 +WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9 +/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +AffirmTrust Premium +=================== +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy +OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy +dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn +BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV +5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs ++7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd +GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R +p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI +S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04 +6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5 +/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo ++Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv +MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC +6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S +L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK ++4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV +BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg +IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60 +g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb +zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw== +-----END CERTIFICATE----- + +AffirmTrust Premium ECC +======================= +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV +BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx +MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U +cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ +N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW +BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK +BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X +57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM +eQ== +-----END CERTIFICATE----- + +Certum Trusted Network CA +========================= +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK +ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy +MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU +ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC +l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J +J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4 +fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0 +cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB +Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw +DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj +jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1 +mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj +Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +Certinomis - Autorité Racine +============================ +-----BEGIN CERTIFICATE----- +MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjETMBEGA1UEChMK +Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAkBgNVBAMMHUNlcnRpbm9taXMg +LSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkG +A1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYw +JAYDVQQDDB1DZXJ0aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jYF1AMnmHa +wE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N8y4oH3DfVS9O7cdxbwly +Lu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWerP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw +2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92N +jMD2AR5vpTESOH2VwnHu7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9q +c1pkIuVC28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6lSTC +lrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1Enn1So2+WLhl+HPNb +xxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB0iSVL1N6aaLwD4ZFjliCK0wi1F6g +530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql095gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna +4NH4+ej9Uji29YnfAgMBAAGjWzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBQNjLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ +KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9sov3/4gbIOZ/x +WqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZMOH8oMDX/nyNTt7buFHAAQCva +R6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40 +nJ+U8/aGH88bc62UeYdocMMzpXDn2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1B +CxMjidPJC+iKunqjo3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjv +JL1vnxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG5ERQL1TE +qkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWqpdEdnV1j6CTmNhTih60b +WfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZbdsLLO7XSAPCjDuGtbkD326C00EauFddE +wk01+dIL8hf2rGbVJLJP0RyZwG71fet0BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/ +vgt2Fl43N+bYdJeimUV5 +-----END CERTIFICATE----- + +TWCA Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ +VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG +EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB +IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx +QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC +oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP +4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r +y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG +9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC +mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW +QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY +T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny +Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +Security Communication RootCA2 +============================== +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh +dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC +SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy +aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++ ++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R +3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV +spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K +EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8 +QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB +CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj +u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk +3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q +tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 +mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +EC-ACC +====== +-----BEGIN CERTIFICATE----- +MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE +BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w +ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD +VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE +CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT +BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7 +MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt +SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl +Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh +cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK +w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT +ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4 +HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a +E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw +0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD +VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0 +Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l +dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ +lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa +Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe +l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2 +E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D +5EI= +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions RootCA 2011 +======================================================= +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT +O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y +aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z +IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT +AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z +IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo +IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI +1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa +71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u +8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH +3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/ +MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8 +MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu +b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt +XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD +/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N +7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----END CERTIFICATE----- + +Actalis Authentication Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM +BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE +AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky +MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz +IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ +wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa +by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6 +zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f +YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2 +oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l +EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7 +hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8 +EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5 +jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY +iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI +WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0 +JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx +K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+ +Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC +4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo +2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz +lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem +OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9 +vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +Trustis FPS Root CA +=================== +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG +EwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290 +IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV +BAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ +RUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk +H5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa +cY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt +o3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA +AaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd +BgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c +GE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC +yinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P +8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV +l/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl +iB6XzCGcKQENZetX2fNXlrtIzYE= +-----END CERTIFICATE----- + +StartCom Certification Authority +================================ +-----BEGIN CERTIFICATE----- +MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu +ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 +NjM3WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk +LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg +U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y +o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ +Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d +eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt +2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z +6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ +osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ +untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc +UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT +37uMdBNSSwIDAQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFulF2mHMMo0aEPQ +Qa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCCATgwLgYIKwYBBQUHAgEWImh0 +dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cu +c3RhcnRzc2wuY29tL2ludGVybWVkaWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENv +bW1lcmNpYWwgKFN0YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0 +aGUgc2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93d3cuc3RhcnRzc2wuY29t +L3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBG +cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5 +fPGFf59Jb2vKXfuM/gTFwWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWm +N3PH/UvSTa0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst0OcN +Org+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNcpRJvkrKTlMeIFw6T +tn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKlCcWw0bdT82AUuoVpaiF8H3VhFyAX +e2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVFP0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA +2MFrLH9ZXF2RsXAiV+uKa0hK1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBs +HvUwyKMQ5bLmKhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE +JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ8dCAWZvLMdib +D4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnmfyWl8kgAwKQB2j8= +-----END CERTIFICATE----- + +StartCom Certification Authority G2 +=================================== +-----BEGIN CERTIFICATE----- +MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +RzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UE +ChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8O +o1XJJZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsDvfOpL9HG +4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnooD/Uefyf3lLE3PbfHkffi +Aez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/Q0kGi4xDuFby2X8hQxfqp0iVAXV16iul +Q5XqFYSdCI0mblWbq9zSOdIxHWDirMxWRST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbs +O+wmETRIjfaAKxojAuuKHDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8H +vKTlXcxNnw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM0D4L +nMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/iUUjXuG+v+E5+M5iS +FGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9Ha90OrInwMEePnWjFqmveiJdnxMa +z6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHgTuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJ +KoZIhvcNAQELBQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K +2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfXUfEpY9Z1zRbk +J4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl6/2o1PXWT6RbdejF0mCy2wl+ +JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG +/+gyRr61M3Z3qAFdlsHB1b6uJcDJHgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTc +nIhT76IxW1hPkWLIwpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/Xld +blhYXzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5lIxKVCCIc +l85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoohdVddLHRDiBYmxOlsGOm +7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulrso8uBtjRkcfGEvRM/TAXw8HaOFvjqerm +obp573PYtlNXLfbQ4ddI +-----END CERTIFICATE----- + +Buypass Class 2 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X +DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1 +g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn +9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b +/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU +CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff +awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI +zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn +Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX +Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs +M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI +osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S +aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd +DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD +LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0 +oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC +wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS +CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN +rJgWVqA= +-----END CERTIFICATE----- + +Buypass Class 3 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X +DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH +sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR +5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh +7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ +ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH +2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV +/afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ +RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA +Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq +j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G +uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG +Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8 +ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2 +KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz +6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug +UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe +eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi +Cp/HuZc= +-----END CERTIFICATE----- + +T-TeleSec GlobalRoot Class 3 +============================ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM +IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU +cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx +MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz +dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD +ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK +9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU +NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF +iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W +0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr +AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb +fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT +ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h +P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw== +-----END CERTIFICATE----- + +EE Certification Centre Root CA +=============================== +-----BEGIN CERTIFICATE----- +MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG +EwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEoMCYGA1UEAwwfRUUgQ2Vy +dGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIw +MTAxMDMwMTAxMDMwWhgPMjAzMDEyMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlB +UyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRy +ZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUyeuuOF0+W2Ap7kaJjbMeM +TC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvObntl8jixwKIy72KyaOBhU8E2lf/slLo2 +rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIwWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw +93X2PaRka9ZP585ArQ/dMtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtN +P2MbRMNE1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/zQas8fElyalL1BSZ +MEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEF +BQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEFBQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+Rj +xY6hUFaTlrg4wCQiZrxTFGGVv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqM +lIpPnTX/dqQGE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u +uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU +3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/vGVCJYMzpJJUPwssd8m92kMfM +dcGWxZ0= +-----END CERTIFICATE----- + +TURKTRUST Certificate Services Provider Root 2007 +================================================= +-----BEGIN CERTIFICATE----- +MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP +MA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg +QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4X +DTA3MTIyNTE4MzcxOVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxl +a3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMCVFIxDzAN +BgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp +bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4gKGMpIEFyYWzEsWsgMjAwNzCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9N +YvDdE3ePYakqtdTyuTFYKTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQv +KUmi8wUG+7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveGHtya +KhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6PIzdezKKqdfcYbwnT +rqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M733WB2+Y8a+xwXrXgTW4qhe04MsC +AwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHkYb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/s +Px+EnWVUXKgWAkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I +aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5mxRZNTZPz/OO +Xl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsaXRik7r4EW5nVcV9VZWRi1aKb +BFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZqxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAK +poRq0Tl9 +-----END CERTIFICATE----- + +D-TRUST Root Class 3 CA 2 2009 +============================== +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTAe +Fw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NThaME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxE +LVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOAD +ER03UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42tSHKXzlA +BF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9RySPocq60vFYJfxLLHLGv +KZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsMlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7z +p+hnUquVH+BGPtikw8paxTGA6Eian5Rp/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUC +AwEAAaOCARowggEWMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ +4PGEMA4GA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVjdG9y +eS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUyMENBJTIwMiUyMDIw +MDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwQ6BBoD+G +PWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAw +OS5jcmwwDQYJKoZIhvcNAQELBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm +2H6NMLVwMeniacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4KzCUqNQT4YJEV +dT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8PIWmawomDeCTmGCufsYkl4ph +X5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3YJohw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +D-TRUST Root Class 3 CA 2 EV 2009 +================================= +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw +OTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUwNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw +OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfS +egpnljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM03TP1YtHh +zRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6ZqQTMFexgaDbtCHu39b+T +7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lRp75mpoo6Kr3HGrHhFPC+Oh25z1uxav60 +sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure35 +11H3a6UCAwEAAaOCASQwggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyv +cop9NteaHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFwOi8v +ZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xhc3MlMjAzJTIwQ0El +MjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRp +b25saXN0MEagRKBChkBodHRwOi8vd3d3LmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xh +c3NfM19jYV8yX2V2XzIwMDkuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+ +PPoeUSbrh/Yp3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNFCSuGdXzfX2lX +ANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7naxpeG0ILD5EJt/rDiZE4OJudA +NCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqXKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVv +w9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +PSCProcert +========== +-----BEGIN CERTIFICATE----- +MIIJhjCCB26gAwIBAgIBCzANBgkqhkiG9w0BAQsFADCCAR4xPjA8BgNVBAMTNUF1dG9yaWRhZCBk +ZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9sYW5vMQswCQYDVQQGEwJWRTEQ +MA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlzdHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lz +dGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBl +cmludGVuZGVuY2lhIGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUw +IwYJKoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyODE2NTEwMFoXDTIw +MTIyNTIzNTk1OVowgdExJjAkBgkqhkiG9w0BCQEWF2NvbnRhY3RvQHByb2NlcnQubmV0LnZlMQ8w +DQYDVQQHEwZDaGFjYW8xEDAOBgNVBAgTB01pcmFuZGExKjAoBgNVBAsTIVByb3ZlZWRvciBkZSBD +ZXJ0aWZpY2Fkb3MgUFJPQ0VSVDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZp +Y2FjaW9uIEVsZWN0cm9uaWNhMQswCQYDVQQGEwJWRTETMBEGA1UEAxMKUFNDUHJvY2VydDCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANW39KOUM6FGqVVhSQ2oh3NekS1wwQYalNo97BVC +wfWMrmoX8Yqt/ICV6oNEolt6Vc5Pp6XVurgfoCfAUFM+jbnADrgV3NZs+J74BCXfgI8Qhd19L3uA +3VcAZCP4bsm+lU/hdezgfl6VzbHvvnpC2Mks0+saGiKLt38GieU89RLAu9MLmV+QfI4tL3czkkoh +RqipCKzx9hEC2ZUWno0vluYC3XXCFCpa1sl9JcLB/KpnheLsvtF8PPqv1W7/U0HU9TI4seJfxPmO +EO8GqQKJ/+MMbpfg353bIdD0PghpbNjU5Db4g7ayNo+c7zo3Fn2/omnXO1ty0K+qP1xmk6wKImG2 +0qCZyFSTXai20b1dCl53lKItwIKOvMoDKjSuc/HUtQy9vmebVOvh+qBa7Dh+PsHMosdEMXXqP+UH +0quhJZb25uSgXTcYOWEAM11G1ADEtMo88aKjPvM6/2kwLkDd9p+cJsmWN63nOaK/6mnbVSKVUyqU +td+tFjiBdWbjxywbk5yqjKPK2Ww8F22c3HxT4CAnQzb5EuE8XL1mv6JpIzi4mWCZDlZTOpx+FIyw +Bm/xhnaQr/2v/pDGj59/i5IjnOcVdo/Vi5QTcmn7K2FjiO/mpF7moxdqWEfLcU8UC17IAggmosvp +r2uKGcfLFFb14dq12fy/czja+eevbqQ34gcnAgMBAAGjggMXMIIDEzASBgNVHRMBAf8ECDAGAQH/ +AgEBMDcGA1UdEgQwMC6CD3N1c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAz +Ni0wMB0GA1UdDgQWBBRBDxk4qpl/Qguk1yeYVKIXTC1RVDCCAVAGA1UdIwSCAUcwggFDgBStuyId +xuDSAaj9dlBSk+2YwU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0b3JpZGFkIGRlIENlcnRp +ZmljYWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xhbm8xCzAJBgNVBAYTAlZFMRAwDgYDVQQH +EwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0cml0byBDYXBpdGFsMTYwNAYDVQQKEy1TaXN0ZW1hIE5h +Y2lvbmFsIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5k +ZW5jaWEgZGUgU2VydmljaW9zIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkqhkiG +9w0BCQEWFmFjcmFpekBzdXNjZXJ0ZS5nb2IudmWCAQowDgYDVR0PAQH/BAQDAgEGME0GA1UdEQRG +MESCDnByb2NlcnQubmV0LnZloBUGBWCGXgIBoAwMClBTQy0wMDAwMDKgGwYFYIZeAgKgEgwQUklG +LUotMzE2MzUzNzMtNzB2BgNVHR8EbzBtMEagRKBChkBodHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52 +ZS9sY3IvQ0VSVElGSUNBRE8tUkFJWi1TSEEzODRDUkxERVIuY3JsMCOgIaAfhh1sZGFwOi8vYWNy +YWl6LnN1c2NlcnRlLmdvYi52ZTA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly9v +Y3NwLnN1c2NlcnRlLmdvYi52ZTBBBgNVHSAEOjA4MDYGBmCGXgMBAjAsMCoGCCsGAQUFBwIBFh5o +dHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9kcGMwDQYJKoZIhvcNAQELBQADggIBACtZ6yKZu4Sq +T96QxtGGcSOeSwORR3C7wJJg7ODU523G0+1ng3dS1fLld6c2suNUvtm7CpsR72H0xpkzmfWvADmN +g7+mvTV+LFwxNG9s2/NkAZiqlCxB3RWGymspThbASfzXg0gTB1GEMVKIu4YXx2sviiCtxQuPcD4q +uxtxj7mkoP3YldmvWb8lK5jpY5MvYB7Eqvh39YtsL+1+LrVPQA3uvFd359m21D+VJzog1eWuq2w1 +n8GhHVnchIHuTQfiSLaeS5UtQbHh6N5+LwUeaO6/u5BlOsju6rEYNxxik6SgMexxbJHmpHmJWhSn +FFAFTKQAVzAswbVhltw+HoSvOULP5dAssSS830DD7X9jSr3hTxJkhpXzsOfIt+FTvZLm8wyWuevo +5pLtp4EJFAv8lXrPj9Y0TzYS3F7RNHXGRoAvlQSMx4bEqCaJqD8Zm4G7UaRKhqsLEQ+xrmNTbSjq +3TNWOByyrYDT13K9mmyZY+gAu0F2BbdbmRiKw7gSXFbPVgx96OLP7bx0R/vu0xdOIk9W/1DzLuY5 +poLWccret9W6aAjtmcz9opLLabid+Qqkpj5PkygqYWwHJgD/ll9ohri4zspV4KuxPX+Y1zMOWj3Y +eMLEYC/HYvBhkdI4sPaeVdtAgAUSM84dkpvRabP/v/GSCmE1P93+hvS84Bpxs2Km +-----END CERTIFICATE----- + +CA Disig Root R1 +================ +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNVBAYTAlNLMRMw +EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp +ZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQyMDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sx +EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp +c2lnIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy +3QRkD2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/oOI7bm+V8 +u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3AfQ+lekLZWnDZv6fXARz2 +m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJeIgpFy4QxTaz+29FHuvlglzmxZcfe+5nk +CiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8noc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTa +YVKvJrT1cU/J19IG32PK/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6 +vpmumwKjrckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD3AjL +LhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE7cderVC6xkGbrPAX +ZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkCyC2fg69naQanMVXVz0tv/wQFx1is +XxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLdqvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ +04IwDQYJKoZIhvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR +xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaASfX8MPWbTx9B +LxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXoHqJPYNcHKfyyo6SdbhWSVhlM +CrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpBemOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5Gfb +VSUZP/3oNn6z4eGBrxEWi1CXYBmCAMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85 +YmLLW1AL14FABZyb7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKS +ds+xDzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvkF7mGnjix +lAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqFa3qdnom2piiZk4hA9z7N +UaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsTQ6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJ +a7+h89n07eLw4+1knj0vllJPgFOL +-----END CERTIFICATE----- + +CA Disig Root R2 +================ +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNVBAYTAlNLMRMw +EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp +ZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQyMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sx +EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp +c2lnIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbC +w3OeNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNHPWSb6Wia +xswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3Ix2ymrdMxp7zo5eFm1tL7 +A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbeQTg06ov80egEFGEtQX6sx3dOy1FU+16S +GBsEWmjGycT6txOgmLcRK7fWV8x8nhfRyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqV +g8NTEQxzHQuyRpDRQjrOQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa +5Beny912H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJQfYE +koopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUDi/ZnWejBBhG93c+A +Ak9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORsnLMOPReisjQS1n6yqEm70XooQL6i +Fh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5u +Qu0wDQYJKoZIhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqfGopTpti72TVV +sRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkblvdhuDvEK7Z4bLQjb/D907Je +dR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W8 +1k/BfDxujRNt+3vrMNDcTa/F1balTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjx +mHHEt38OFdAlab0inSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01 +utI3gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18DrG5gPcFw0 +sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3OszMOl6W8KjptlwlCFtaOg +UxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8xL4ysEr3vQCj8KWefshNPZiTEUxnpHikV +7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +ACCVRAIZ1 +========= +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UEAwwJQUNDVlJB +SVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQswCQYDVQQGEwJFUzAeFw0xMTA1 +MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwH +UEtJQUNDVjENMAsGA1UECgwEQUNDVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCbqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gM +jmoYHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWoG2ioPej0 +RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpAlHPrzg5XPAOBOp0KoVdD +aaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhrIA8wKFSVf+DuzgpmndFALW4ir50awQUZ +0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDG +WuzndN9wrqODJerWx5eHk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs7 +8yM2x/474KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMOm3WR +5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpacXpkatcnYGMN285J +9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPluUsXQA+xtrn13k/c4LOsOxFwYIRK +Q26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYIKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRw +Oi8vd3d3LmFjY3YuZXMvZmlsZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEu +Y3J0MB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeTVfZW6oHlNsyM +Hj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIGCCsGAQUFBwICMIIBFB6CARAA +QQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUAcgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBh +AO0AegAgAGQAZQAgAGwAYQAgAEEAQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUA +YwBuAG8AbABvAGcA7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBj +AHQAcgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAAQwBQAFMA +IABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUAczAwBggrBgEFBQcCARYk +aHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2MuaHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0 +dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRtaW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2 +MV9kZXIuY3JsMA4GA1UdDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZI +hvcNAQEFBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdpD70E +R9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gUJyCpZET/LtZ1qmxN +YEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+mAM/EKXMRNt6GGT6d7hmKG9Ww7Y49 +nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepDvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJ +TS+xJlsndQAJxGJ3KQhfnlmstn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3 +sCPdK6jT2iWH7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szAh1xA2syVP1Xg +Nce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xFd3+YJ5oyXSrjhO7FmGYvliAd +3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2HpPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3p +EfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +TWCA Global Root CA +=================== +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcxEjAQBgNVBAoT +CVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMTVFdDQSBHbG9iYWwgUm9vdCBD +QTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQK +EwlUQUlXQU4tQ0ExEDAOBgNVBAsTB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3Qg +Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2C +nJfF10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz0ALfUPZV +r2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfChMBwqoJimFb3u/Rk28OKR +Q4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbHzIh1HrtsBv+baz4X7GGqcXzGHaL3SekV +tTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1W +KKD+u4ZqyPpcC1jcxkt2yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99 +sy2sbZCilaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYPoA/p +yJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQABDzfuBSO6N+pjWxn +kjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcEqYSjMq+u7msXi7Kx/mzhkIyIqJdI +zshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6g +cFGn90xHNcgL1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WFH6vPNOw/KP4M +8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNoRI2T9GRwoD2dKAXDOXC4Ynsg +/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlg +lPx4mI88k1HtQJAH32RjJMtOcQWh15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryP +A9gK8kxkRr05YuWW6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3m +i4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8 +EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3 +zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0= +-----END CERTIFICATE----- + +TeliaSonera Root CA v1 +====================== +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE +CgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4 +MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW +VGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+ +6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA +3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k +B1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn +Xb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH +oLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3 +F0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ +oWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7 +gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc +TwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB +AAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW +DNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm +zqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW +pb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV +G6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc +c41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT +JsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2 +qReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6 +Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems +WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- + +E-Tugra Certification Authority +=============================== +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w +DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls +ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw +NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx +QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl +cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD +DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd +hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K +CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g +ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ +BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0 +E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz +rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq +jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5 +dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB +/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG +MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK +kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO +XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807 +VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo +a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc +dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV +KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT +Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0 +8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G +C7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- + +T-TeleSec GlobalRoot Class 2 +============================ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM +IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU +cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx +MDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz +dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD +ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ +SBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F +vudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970 +2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV +WOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy +YdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4 +r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf +vNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR +3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg== +-----END CERTIFICATE----- + +Atos TrustedRoot 2011 +===================== +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU +cnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4 +MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG +A1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV +hTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr +54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+ +DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320 +HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR +z3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R +l+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ +bNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB +CwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h +k6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh +TZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9 +61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G +3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- + +QuoVadis Root CA 1 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakE +PBtVwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWerNrwU8lm +PNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF34168Xfuw6cwI2H44g4hWf6 +Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh4Pw5qlPafX7PGglTvF0FBM+hSo+LdoIN +ofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXpUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/l +g6AnhF4EwfWQvTA9xO+oabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV +7qJZjqlc3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/GKubX +9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSthfbZxbGL0eUQMk1f +iyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KOTk0k+17kBL5yG6YnLUlamXrXXAkg +t3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOtzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZI +hvcNAQELBQADggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2cDMT/uFPpiN3 +GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUNqXsCHKnQO18LwIE6PWThv6ct +Tr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP ++V04ikkwj+3x6xn0dxoxGE1nVGwvb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh +3jRJjehZrJ3ydlo28hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fa +wx/kNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNjZgKAvQU6 +O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhpq1467HxpvMc7hU6eFbm0 +FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFtnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOV +hMJKzRwuJIczYOXD +-----END CERTIFICATE----- + +QuoVadis Root CA 2 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFh +ZiFfqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMWn4rjyduY +NM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ymc5GQYaYDFCDy54ejiK2t +oIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+o +MiwMzAkd056OXbxMmO7FGmh77FOm6RQ1o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+l +V0POKa2Mq1W/xPtbAd0jIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZo +L1NesNKqIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz8eQQ +sSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43ehvNURG3YBZwjgQQvD +6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l7ZizlWNof/k19N+IxWA1ksB8aRxh +lRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALGcC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZI +hvcNAQELBQADggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RCroijQ1h5fq7K +pVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0GaW/ZZGYjeVYg3UQt4XAoeo0L9 +x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgz +dWqTHBLmYF5vHX/JHyPLhGGfHoJE+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6X +U/IyAgkwo1jwDQHVcsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+Nw +mNtddbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNgKCLjsZWD +zYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeMHVOyToV7BjjHLPj4sHKN +JeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4WSr2Rz0ZiC3oheGe7IUIarFsNMkd7Egr +O3jtZsSOeWmD3n+M +-----END CERTIFICATE----- + +QuoVadis Root CA 3 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286 +IxSR/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNuFoM7pmRL +Mon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXRU7Ox7sWTaYI+FrUoRqHe +6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+cra1AdHkrAj80//ogaX3T7mH1urPnMNA3 +I4ZyYUUpSFlob3emLoG+B01vr87ERRORFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3U +VDmrJqMz6nWB2i3ND0/kA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f7 +5li59wzweyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634RylsSqi +Md5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBpVzgeAVuNVejH38DM +dyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0QA4XN8f+MFrXBsj6IbGB/kE+V9/Yt +rQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZI +hvcNAQELBQADggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnIFUBhynLWcKzS +t/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5WvvoxXqA/4Ti2Tk08HS6IT7SdEQ +TXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFgu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9Du +DcpmvJRPpq3t/O5jrFc/ZSXPsoaP0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGib +Ih6BJpsQBJFxwAYf3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmD +hPbl8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+DhcI00iX +0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HNPlopNLk9hM6xZdRZkZFW +dSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ywaZWWDYWGWVjUTR939+J399roD1B0y2 +PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- + +DigiCert Assured ID Root G2 +=========================== +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw +IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgw +MTE1MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL +ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSAn61UQbVH +35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4HteccbiJVMWWXvdMX0h5i89vq +bFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9HpEgjAALAcKxHad3A2m67OeYfcgnDmCXRw +VWmvo2ifv922ebPynXApVfSr/5Vh88lAbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OP +YLfykqGxvYmJHzDNw6YuYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+Rn +lTGNAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTO +w0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPIQW5pJ6d1Ee88hjZv +0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I0jJmwYrA8y8678Dj1JGG0VDjA9tz +d29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4GnilmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAW +hsI6yLETcDbYz+70CjTVW0z9B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0M +jomZmWzwPDCvON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- + +DigiCert Assured ID Root G3 +=========================== +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD +VQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 +MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQ +BgcqhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJfZn4f5dwb +RXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17QRSAPWXYQ1qAk8C3eNvJs +KTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgF +UaFNN6KDec6NHSrkhDAKBggqhkjOPQQDAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5Fy +YZ5eEJJZVrmDxxDnOOlYJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy +1vUhZscv6pZjamVFkpUBtA== +-----END CERTIFICATE----- + +DigiCert Global Root G2 +======================= +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw +HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUx +MjAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 +dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI2/Ou8jqJ +kTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx1x7e/dfgy5SDN67sH0NO +3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQq2EGnI/yuum06ZIya7XzV+hdG82MHauV +BJVJ8zUtluNJbd134/tJS7SsVQepj5WztCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyM +UNGPHgm+F6HmIcr9g+UQvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQAB +o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV5uNu +5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY1Yl9PMWLSn/pvtsr +F9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4NeF22d+mQrvHRAiGfzZ0JFrabA0U +WTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NGFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBH +QRFXGU7Aj64GxJUTFy8bJZ918rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/ +iyK5S9kJRaTepLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +DigiCert Global Root G3 +======================= +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYD +VQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAw +MDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k +aWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0C +AQYFK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FGfp4tn+6O +YwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPOZ9wj/wMco+I+o0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNp +Yim8S8YwCgYIKoZIzj0EAwMDaAAwZQIxAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y +3maTD/HMsQmP3Wyr+mt/oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34 +VOKa5Vt8sycX +-----END CERTIFICATE----- + +DigiCert Trusted Root G4 +======================== +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw +HwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 +MTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp +pz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9o +k3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7Fsa +vOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY +QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6 +MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtm +mnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7 +f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFH +dL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8 +oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBhjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY +ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdNOj6PWTkiU0Tr +yF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy +7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iah +ixTXTBmyUEFxPT9NcCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN +5r5N0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb +/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP0oUA51Aa +5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tK +G48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP +82Z+ +-----END CERTIFICATE----- + +WoSign +====== +-----BEGIN CERTIFICATE----- +MIIFdjCCA16gAwIBAgIQXmjWEXGUY1BWAGjzPsnFkTANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQG +EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNVBAMTIUNlcnRpZmljYXRpb24g +QXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgwMTAwMDFaMFUxCzAJ +BgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEqMCgGA1UEAxMhQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkgb2YgV29TaWduMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA +vcqNrLiRFVaXe2tcesLea9mhsMMQI/qnobLMMfo+2aYpbxY94Gv4uEBf2zmoAHqLoE1UfcIiePyO +CbiohdfMlZdLdNiefvAA5A6JrkkoRBoQmTIPJYhTpA2zDxIIFgsDcSccf+Hb0v1naMQFXQoOXXDX +2JegvFNBmpGN9J42Znp+VsGQX+axaCA2pIwkLCxHC1l2ZjC1vt7tj/id07sBMOby8w7gLJKA84X5 +KIq0VC6a7fd2/BVoFutKbOsuEo/Uz/4Mx1wdC34FMr5esAkqQtXJTpCzWQ27en7N1QhatH/YHGkR ++ScPewavVIMYe+HdVHpRaG53/Ma/UkpmRqGyZxq7o093oL5d//xWC0Nyd5DKnvnyOfUNqfTq1+ez +EC8wQjchzDBwyYaYD8xYTYO7feUapTeNtqwylwA6Y3EkHp43xP901DfA4v6IRmAR3Qg/UDaruHqk +lWJqbrDKaiFaafPz+x1wOZXzp26mgYmhiMU7ccqjUu6Du/2gd/Tkb+dC221KmYo0SLwX3OSACCK2 +8jHAPwQ+658geda4BmRkAjHXqc1S+4RFaQkAKtxVi8QGRkvASh0JWzko/amrzgD5LkhLJuYwTKVY +yrREgk/nkR4zw7CT/xH8gdLKH3Ep3XZPkiWvHYG3Dy+MwwbMLyejSuQOmbp8HkUff6oZRZb9/D0C +AwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOFmzw7R +8bNLtwYgFP6HEtX2/vs+MA0GCSqGSIb3DQEBBQUAA4ICAQCoy3JAsnbBfnv8rWTjMnvMPLZdRtP1 +LOJwXcgu2AZ9mNELIaCJWSQBnfmvCX0KI4I01fx8cpm5o9dU9OpScA7F9dY74ToJMuYhOZO9sxXq +T2r09Ys/L3yNWC7F4TmgPsc9SnOeQHrAK2GpZ8nzJLmzbVUsWh2eJXLOC62qx1ViC777Y7NhRCOj +y+EaDveaBk3e1CNOIZZbOVtXHS9dCF4Jef98l7VNg64N1uajeeAz0JmWAjCnPv/So0M/BVoG6kQC +2nz4SNAzqfkHx5Xh9T71XXG68pWpdIhhWeO/yloTunK0jF02h+mmxTwTv97QRCbut+wucPrXnbes +5cVAWubXbHssw1abR80LzvobtCHXt2a49CUwi1wNuepnsvRtrtWhnk/Yn+knArAdBtaP4/tIEp9/ +EaEQPkxROpaw0RPxx9gmrjrKkcRpnd8BKWRRb2jaFOwIQZeQjdCygPLPwj2/kWjFgGcexGATVdVh +mVd8upUPYUk6ynW8yQqTP2cOEvIo4jEbwFcW3wh8GcF+Dx+FHgo2fFt+J7x6v+Db9NpSvd4MVHAx +kUOVyLzwPt0JfjBkUO1/AaQzZ01oT74V77D2AhGiGxMlOtzCWfHjXEa7ZywCRuoeSKbmW9m1vFGi +kpbbqsY3Iqb+zCB0oy2pLmvLwIIRIbWTee5Ehr7XHuQe+w== +-----END CERTIFICATE----- + +WoSign China +============ +-----BEGIN CERTIFICATE----- +MIIFWDCCA0CgAwIBAgIQUHBrzdgT/BtOOzNy0hFIjTANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQG +EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMMEkNBIOayg+mAmuagueiv +geS5pjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgwMTAwMDFaMEYxCzAJBgNVBAYTAkNOMRowGAYD +VQQKExFXb1NpZ24gQ0EgTGltaXRlZDEbMBkGA1UEAwwSQ0Eg5rKD6YCa5qC56K+B5LmmMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0EkhHiX8h8EqwqzbdoYGTufQdDTc7WU1/FDWiD+k +8H/rD195L4mx/bxjWDeTmzj4t1up+thxx7S8gJeNbEvxUNUqKaqoGXqW5pWOdO2XCld19AXbbQs5 +uQF/qvbW2mzmBeCkTVL829B0txGMe41P/4eDrv8FAxNXUDf+jJZSEExfv5RxadmWPgxDT74wwJ85 +dE8GRV2j1lY5aAfMh09Qd5Nx2UQIsYo06Yms25tO4dnkUkWMLhQfkWsZHWgpLFbE4h4TV2TwYeO5 +Ed+w4VegG63XX9Gv2ystP9Bojg/qnw+LNVgbExz03jWhCl3W6t8Sb8D7aQdGctyB9gQjF+BNdeFy +b7Ao65vh4YOhn0pdr8yb+gIgthhid5E7o9Vlrdx8kHccREGkSovrlXLp9glk3Kgtn3R46MGiCWOc +76DbT52VqyBPt7D3h1ymoOQ3OMdc4zUPLK2jgKLsLl3Az+2LBcLmc272idX10kaO6m1jGx6KyX2m ++Jzr5dVjhU1zZmkR/sgO9MHHZklTfuQZa/HpelmjbX7FF+Ynxu8b22/8DU0GAbQOXDBGVWCvOGU6 +yke6rCzMRh+yRpY/8+0mBe53oWprfi1tWFxK1I5nuPHa1UaKJ/kR8slC/k7e3x9cxKSGhxYzoacX +GKUN5AXlK8IrC6KVkLn9YDxOiT7nnO4fuwECAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFOBNv9ybQV0T6GTwp+kVpOGBwboxMA0GCSqGSIb3DQEBCwUA +A4ICAQBqinA4WbbaixjIvirTthnVZil6Xc1bL3McJk6jfW+rtylNpumlEYOnOXOvEESS5iVdT2H6 +yAa+Tkvv/vMx/sZ8cApBWNromUuWyXi8mHwCKe0JgOYKOoICKuLJL8hWGSbueBwj/feTZU7n85iY +r83d2Z5AiDEoOqsuC7CsDCT6eiaY8xJhEPRdF/d+4niXVOKM6Cm6jBAyvd0zaziGfjk9DgNyp115 +j0WKWa5bIW4xRtVZjc8VX90xJc/bYNaBRHIpAlf2ltTW/+op2znFuCyKGo3Oy+dCMYYFaA6eFN0A +kLppRQjbbpCBhqcqBT/mhDn4t/lXX0ykeVoQDF7Va/81XwVRHmyjdanPUIPTfPRm94KNPQx96N97 +qA4bLJyuQHCH2u2nFoJavjVsIE4iYdm8UXrNemHcSxH5/mc0zy4EZmFcV5cjjPOGG0jfKq+nwf/Y +jj4Du9gqsPoUJbJRa4ZDhS4HIxaAjUz7tGM7zMN07RujHv41D198HRaG9Q7DlfEvr10lO1Hm13ZB +ONFLAzkopR6RctR9q5czxNM+4Gm2KHmgCY0c0f9BckgG/Jou5yD5m6Leie2uPAmvylezkolwQOQv +T8Jwg0DXJCxr5wkf09XHwQj02w47HAcLQxGEIYbpgNR12KvxAmLBsX5VYc8T1yaw15zLKYs4SgsO +kI26oQ== +-----END CERTIFICATE----- + +COMODO RSA Certification Authority +================================== +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE +BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG +A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwHhcNMTAwMTE5MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMC +R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE +ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0Rn +dJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZ +FGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+ +5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pG +x8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z+pUX +2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQL +OvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3 +sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+C +GCe01a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5 +WdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w +DQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvlwFTPoCWOAvn9sKIN9SCYPBMt +rFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+ +nq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg +tZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW +sRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp +pC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmckejkk9u+UJueBPSZI9FoJA +zMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yLS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHq +ZJx64SIDqZxubw5lT2yHh17zbqD5daWbQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk52 +7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I +LaZRfyHBNVOFBkpdn627G190 +-----END CERTIFICATE----- + +USERTrust RSA Certification Authority +===================================== +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UE +BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK +ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UE +BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK +ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCAEmUXNg7D2wiz +0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2j +Y0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFn +RghRy4YUVD+8M/5+bJz/Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O ++T23LLb2VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq +/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6lZrEpfDKE +Y1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8liM2EuLE/pDkP2QKe6xJM +lXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8 +yexDJtC/QV9AqURE9JnnV4eeUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+ +eLf8ZxXhyVeEHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPFUp/L+M+ZBn8b2kMVn54CVVeW +FPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KOVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ +7l8wXEskEVX/JJpuXior7gtNn3/3ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQ +Eg9zKC7F4iRO/Fjs8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM +8WcRiQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYzeSf7dNXGi +FSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZXHlKYC6SQK5MNyosycdi +yA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9c +J2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRBVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGw +sAvgnEzDHNb842m1R0aBL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gx +Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +USERTrust ECC Certification Authority +===================================== +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC +VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC +VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2 +0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez +nPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV +HQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB +HU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu +9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- + +GlobalSign ECC Root CA - R4 +=========================== +-----BEGIN CERTIFICATE----- +MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprl +OQcJFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAwDgYDVR0P +AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61FuOJAf/sKbvu+M8k8o4TV +MAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGXkPoUVy0D7O48027KqGx2vKLeuwIgJ6iF +JzWbVsaj8kfSt24bAgAXqmemFZHe+pTsewv4n4Q= +-----END CERTIFICATE----- + +GlobalSign ECC Root CA - R5 +=========================== +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6 +SFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS +h5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd +BgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx +uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7 +yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +Staat der Nederlanden Root CA - G3 +================================== +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE +CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g +Um9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloXDTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMC +TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l +ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4y +olQPcPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WWIkYFsO2t +x1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqXxz8ecAgwoNzFs21v0IJy +EavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFyKJLZWyNtZrVtB0LrpjPOktvA9mxjeM3K +Tj215VKb8b475lRgsGYeCasH/lSJEULR9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUur +mkVLoR9BvUhTFXFkC4az5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU5 +1nus6+N86U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7Ngzp +07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHPbMk7ccHViLVlvMDo +FxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXtBznaqB16nzaeErAMZRKQFWDZJkBE +41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTtXUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleu +yjWcLhL75LpdINyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwpLiniyMMB8jPq +KqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8Ipf3YF3qKS9Ysr1YvY2WTxB1 +v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixpgZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA +8KCWAg8zxXHzniN9lLf9OtMJgwYh/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b +8KKaa8MFSu1BYBQw0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0r +mj1AfsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq4BZ+Extq +1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR1VmiiXTTn74eS9fGbbeI +JG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/QFH1T/U67cjF68IeHRaVesd+QnGTbksV +tzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM94B7IWcnMFk= +-----END CERTIFICATE----- + +Staat der Nederlanden EV Root CA +================================ +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJOTDEeMBwGA1UE +CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFhdCBkZXIgTmVkZXJsYW5kZW4g +RVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0yMjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5M +MR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRl +cmxhbmRlbiBFViBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkk +SzrSM4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nCUiY4iKTW +O0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3dZ//BYY1jTw+bbRcwJu+r +0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46prfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8 +Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13lpJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gV +XJrm0w912fxBmJc+qiXbj5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr +08C+eKxCKFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS/ZbV +0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0XcgOPvZuM5l5Tnrmd +74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH1vI4gnPah1vlPNOePqc7nvQDs/nx +fRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrPpx9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwa +ivsnuL8wbqg7MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u2dfOWBfoqSmu +c0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHSv4ilf0X8rLiltTMMgsT7B/Zq +5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTCwPTxGfARKbalGAKb12NMcIxHowNDXLldRqAN +b/9Zjr7dn3LDWyvfjFvO5QxGbJKyCqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tN +f1zuacpzEPuKqf2evTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi +5Dp6Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIaGl6I6lD4 +WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeLeG9QgkRQP2YGiqtDhFZK +DyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGy +eUN51q1veieQA6TqJIc/2b3Z6fJfUEkc7uzXLg== +-----END CERTIFICATE----- + +IdenTrust Commercial Root CA 1 +============================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQG +EwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBS +b290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQwMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzES +MBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB +IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ld +hNlT3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU+ehcCuz/ +mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gpS0l4PJNgiCL8mdo2yMKi +1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1bVoE/c40yiTcdCMbXTMTEl3EASX2MN0C +XZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl +3ZBWzvurpWCdxJ35UrCLvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzy +NeVJSQjKVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZKdHzV +WYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHTc+XvvqDtMwt0viAg +xGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hvl7yTmvmcEpB4eoCHFddydJxVdHix +uuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5NiGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI +hvcNAQELBQADggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwtLRvM7Kqas6pg +ghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt +ozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmV +YjzlVYA211QC//G5Xc7UI2/YRYRKW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUX +feu+h1sXIFRRk0pTAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/ro +kTLql1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG4iZZRHUe +2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZmUlO+KWA2yUPHGNiiskz +Z2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7R +cGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +IdenTrust Public Sector Root CA 1 +================================= +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG +EwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3Rv +ciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcNMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJV +UzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBS +b290IENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTy +P4o7ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGyRBb06tD6 +Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlSbdsHyo+1W/CD80/HLaXI +rcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF/YTLNiCBWS2ab21ISGHKTN9T0a9SvESf +qy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoS +mJxZZoY+rfGwyj4GD3vwEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFn +ol57plzy9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9VGxyh +LrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ2fjXctscvG29ZV/v +iDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsVWaFHVCkugyhfHMKiq3IXAAaOReyL +4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gDW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8B +Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMw +DQYJKoZIhvcNAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHVDRDtfULAj+7A +mgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9TaDKQGXSc3z1i9kKlT/YPyNt +GtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8GlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFt +m6/n6J91eEyrRjuazr8FGF1NFTwWmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMx +NRF4eKLg6TCMf4DfWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4 +Mhn5+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJtshquDDI +ajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhAGaQdp/lLQzfcaFpPz+vC +ZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ +3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +Entrust Root Certification Authority - G2 +========================================= +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV +BAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy +bXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug +b25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw +HhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT +DUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx +OTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP +/vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz +HHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU +s/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y +TGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx +AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6 +0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z +iXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi +nWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+ +vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO +e4pIb4tF9g== +-----END CERTIFICATE----- + +Entrust Root Certification Authority - EC1 +========================================== +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx +FjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn +YWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl +ZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw +FAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs +LXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg +dXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt +IEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy +AsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef +9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h +vxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8 +kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- + +CFCA EV ROOT +============ +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDTjEwMC4GA1UE +CgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB +IEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw +MC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQD +DAxDRkNBIEVWIFJPT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnV +BU03sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpLTIpTUnrD +7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5/ZOkVIBMUtRSqy5J35DN +uF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp7hZZLDRJGqgG16iI0gNyejLi6mhNbiyW +ZXvKWfry4t3uMCz7zEasxGPrb382KzRzEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7 +xzbh72fROdOXW3NiGUgthxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9f +py25IGvPa931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqotaK8K +gWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNgTnYGmE69g60dWIol +hdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfVPKPtl8MeNPo4+QgO48BdK4PRVmrJ +tqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hvcWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAf +BgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB +/wQEAwIBBjAdBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObTej/tUxPQ4i9q +ecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdLjOztUmCypAbqTuv0axn96/Ua +4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBSESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sG +E5uPhnEFtC+NiWYzKXZUmhH4J/qyP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfX +BDrDMlI1Dlb4pd19xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjn +aH9dCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN5mydLIhy +PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX +kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C +ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5 +==================================================== +-----BEGIN CERTIFICATE----- +MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UEBhMCVFIxDzAN +BgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp +bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1Qg +RWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAw +ODA3MDFaFw0yMzA0MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0w +SwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnE +n2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRp +ZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEApCUZ4WWe60ghUEoI5RHwWrom/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537 +jVJp45wnEFPzpALFp/kRGml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1m +ep5Fimh34khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z5UNP +9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0hO8EuPbJbKoCPrZV +4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QIDAQABo0IwQDAdBgNVHQ4EFgQUVpkH +HtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI +hvcNAQELBQADggEBAJ5FdnsXSDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPo +BP5yCccLqh0lVX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq +URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nfpeYVhDfwwvJl +lpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CFYv4HAqGEVka+lgqaE9chTLd8 +B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW+qtB4Uu2NQvAmxU= +-----END CERTIFICATE----- + +Certinomis - Root CA +==================== +-----BEGIN CERTIFICATE----- +MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjETMBEGA1UEChMK +Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAbBgNVBAMTFENlcnRpbm9taXMg +LSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMzMTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIx +EzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRD +ZXJ0aW5vbWlzIC0gUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQos +P5L2fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJflLieY6pOo +d5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQVWZUKxkd8aRi5pwP5ynap +z8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDFTKWrteoB4owuZH9kb/2jJZOLyKIOSY00 +8B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09x +RLWtwHkziOC/7aOgFLScCbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE +6OXWk6RiwsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJwx3t +FvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SGm/lg0h9tkQPTYKbV +PZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4F2iw4lNVYC2vPsKD2NkJK/DAZNuH +i5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZngWVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGj +YzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I +6tNxIqSSaHh02TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF +AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/0KGRHCwPT5iV +WVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWwF6YSjNRieOpWauwK0kDDPAUw +Pk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZSg081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAX +lCOotQqSD7J6wWAsOMwaplv/8gzjqh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJ +y29SWwNyhlCVCNSNh4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9 +Iff/ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8Vbtaw5Bng +DwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwjY/M50n92Uaf0yKHxDHYi +I0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nM +cyrDflOR1m749fPH0FFNjkulW+YZFzvWgQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVr +hkIGuUE= +-----END CERTIFICATE----- + +OISTE WISeKey Global Root GB CA +=============================== +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG +EwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl +ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw +MzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD +VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds +b2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX +scriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP +rby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk +9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o +Qnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg +GUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI +hvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD +dHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0 +VQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui +HZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +Certification Authority of WoSign G2 +==================================== +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQayXaioidfLwPBbOxemFFRDANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQG +EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxLTArBgNVBAMTJENlcnRpZmljYXRpb24g +QXV0aG9yaXR5IG9mIFdvU2lnbiBHMjAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4NThaMFgx +CzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEtMCsGA1UEAxMkQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkgb2YgV29TaWduIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAvsXEoCKASU+/2YcRxlPhuw+9YH+v9oIOH9ywjj2X4FA8jzrvZjtFB5sg+OPXJYY1kBai +XW8wGQiHC38Gsp1ij96vkqVg1CuAmlI/9ZqD6TRay9nVYlzmDuDfBpgOgHzKtB0TiGsOqCR3A9Du +W/PKaZE1OVbFbeP3PU9ekzgkyhjpJMuSA93MHD0JcOQg5PGurLtzaaNjOg9FD6FKmsLRY6zLEPg9 +5k4ot+vElbGs/V6r+kHLXZ1L3PR8du9nfwB6jdKgGlxNIuG12t12s9R23164i5jIFFTMaxeSt+BK +v0mUYQs4kI9dJGwlezt52eJ+na2fmKEG/HgUYFf47oB3sQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU+mCp62XF3RYUCE4MD42b4Pdkr2cwDQYJKoZI +hvcNAQELBQADggEBAFfDejaCnI2Y4qtAqkePx6db7XznPWZaOzG73/MWM5H8fHulwqZm46qwtyeY +P0nXYGdnPzZPSsvxFPpahygc7Y9BMsaV+X3avXtbwrAh449G3CE4Q3RM+zD4F3LBMvzIkRfEzFg3 +TgvMWvchNSiDbGAtROtSjFA9tWwS1/oJu2yySrHFieT801LYYRf+epSEj3m2M1m6D8QL4nCgS3gu ++sif/a+RZQp4OBXllxcU3fngLDT4ONCEIgDAFFEYKwLcMFrw6AF8NTojrwjkr6qOKEJJLvD1mTS+ +7Q9LGOHSJDy7XUe3IfKN0QqZjuNuPq1w4I+5ysxugTH2e5x6eeRncRg= +-----END CERTIFICATE----- + +CA WoSign ECC Root +================== +-----BEGIN CERTIFICATE----- +MIICCTCCAY+gAwIBAgIQaEpYcIBr8I8C+vbe6LCQkDAKBggqhkjOPQQDAzBGMQswCQYDVQQGEwJD +TjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMTEkNBIFdvU2lnbiBFQ0MgUm9v +dDAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4NThaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQK +ExFXb1NpZ24gQ0EgTGltaXRlZDEbMBkGA1UEAxMSQ0EgV29TaWduIEVDQyBSb290MHYwEAYHKoZI +zj0CAQYFK4EEACIDYgAE4f2OuEMkq5Z7hcK6C62N4DrjJLnSsb6IOsq/Srj57ywvr1FQPEd1bPiU +t5v8KB7FVMxjnRZLU8HnIKvNrCXSf4/CwVqCXjCLelTOA7WRf6qU0NGKSMyCBSah1VES1ns2o0Iw +QDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUqv3VWqP2h4syhf3R +MluARZPzA7gwCgYIKoZIzj0EAwMDaAAwZQIxAOSkhLCB1T2wdKyUpOgOPQB0TKGXa/kNUTyh2Tv0 +Daupn75OcsqF1NnstTJFGG+rrQIwfcf3aWMvoeGY7xMQ0Xk/0f7qO3/eVvSQsRUR2LIiFdAvwyYu +a/GRspBl9JrmkO5K +-----END CERTIFICATE----- + +SZAFIR ROOT CA2 +=============== +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG +A1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV +BAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ +BgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD +VQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q +qEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK +DJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE +2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ +ckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi +ieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC +AQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5 +O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67 +oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul +4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6 ++/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +Certum Trusted Network CA 2 +=========================== +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE +BhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1 +bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y +ayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ +TDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB +IDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9 +7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o +CgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b +Rr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p +uTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130 +GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ +9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB +Rgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye +hizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM +BhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI +hvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW +Al45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA +L55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo +clm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM +pkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb +w3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo +J/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm +ypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX +is7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7 +zAYspsbiDrW5viSP +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions RootCA 2015 +======================================================= +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcT +BkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0 +aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl +YXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAx +MTIxWjCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMg +QWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNV +BAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIw +MTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDC+Kk/G4n8PDwEXT2QNrCROnk8Zlrv +bTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+eh +iGsxr/CL0BgzuNtFajT0AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+ +6PAQZe104S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06CojXd +FPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV9Cz82XBST3i4vTwr +i5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrDgfgXy5I2XdGj2HUb4Ysn6npIQf1F +GQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2 +fu/Z8VFRfS0myGlZYeCsargqNhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9mu +iNX6hME6wGkoLfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVdctA4GGqd83EkVAswDQYJKoZI +hvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0IXtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+ +D1hYc2Ryx+hFjtyp8iY/xnmMsVMIM4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrM +d/K4kPFox/la/vot9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+y +d+2VZ5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/eaj8GsGsVn +82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnhX9izjFk0WaSrT2y7Hxjb +davYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQl033DlZdwJVqwjbDG2jJ9SrcR5q+ss7F +Jej6A7na+RZukYT1HCjI/CbM1xyQVqdfbzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVt +J94Cj8rDtSvK6evIIVM4pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGa +JI7ZjnHKe7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0vm9q +p/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions ECC RootCA 2015 +=========================================================== +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0 +aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u +cyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj +aCBJbnN0aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEw +MzcxMlowgaoxCzAJBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmlj +IEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUQwQgYD +VQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIEVDQyBSb290 +Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKgQehLgoRc4vgxEZmGZE4JJS+dQS8KrjVP +dJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJajq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoK +Vlp8aQuqgAkkbH7BRqNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O +BBYEFLQiC4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaeplSTA +GiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7SofTUwJCA3sS61kFyjn +dc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +Certplus Root CA G1 +=================== +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgISESBVg+QtPlRWhS2DN7cs3EYRMA0GCSqGSIb3DQEBDQUAMD4xCzAJBgNV +BAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTAe +Fw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhD +ZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBANpQh7bauKk+nWT6VjOaVj0W5QOVsjQcmm1iBdTYj+eJZJ+622SLZOZ5KmHN +r49aiZFluVj8tANfkT8tEBXgfs+8/H9DZ6itXjYj2JizTfNDnjl8KvzsiNWI7nC9hRYt6kuJPKNx +Qv4c/dMcLRC4hlTqQ7jbxofaqK6AJc96Jh2qkbBIb6613p7Y1/oA/caP0FG7Yn2ksYyy/yARujVj +BYZHYEMzkPZHogNPlk2dT8Hq6pyi/jQu3rfKG3akt62f6ajUeD94/vI4CTYd0hYCyOwqaK/1jpTv +LRN6HkJKHRUxrgwEV/xhc/MxVoYxgKDEEW4wduOU8F8ExKyHcomYxZ3MVwia9Az8fXoFOvpHgDm2 +z4QTd28n6v+WZxcIbekN1iNQMLAVdBM+5S//Ds3EC0pd8NgAM0lm66EYfFkuPSi5YXHLtaW6uOrc +4nBvCGrch2c0798wct3zyT8j/zXhviEpIDCB5BmlIOklynMxdCm+4kLV87ImZsdo/Rmz5yCTmehd +4F6H50boJZwKKSTUzViGUkAksnsPmBIgJPaQbEfIDbsYIC7Z/fyL8inqh3SV4EJQeIQEQWGw9CEj +jy3LKCHyamz0GqbFFLQ3ZU+V/YDI+HLlJWvEYLF7bY5KinPOWftwenMGE9nTdDckQQoRb5fc5+R+ +ob0V8rqHDz1oihYHAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0G +A1UdDgQWBBSowcCbkahDFXxdBie0KlHYlwuBsTAfBgNVHSMEGDAWgBSowcCbkahDFXxdBie0KlHY +lwuBsTANBgkqhkiG9w0BAQ0FAAOCAgEAnFZvAX7RvUz1isbwJh/k4DgYzDLDKTudQSk0YcbX8ACh +66Ryj5QXvBMsdbRX7gp8CXrc1cqh0DQT+Hern+X+2B50ioUHj3/MeXrKls3N/U/7/SMNkPX0XtPG +YX2eEeAC7gkE2Qfdpoq3DIMku4NQkv5gdRE+2J2winq14J2by5BSS7CTKtQ+FjPlnsZlFT5kOwQ/ +2wyPX1wdaR+v8+khjPPvl/aatxm2hHSco1S1cE5j2FddUyGbQJJD+tZ3VTNPZNX70Cxqjm0lpu+F +6ALEUz65noe8zDUa3qHpimOHZR4RKttjd5cUvpoUmRGywO6wT/gUITJDT5+rosuoD6o7BlXGEilX +CNQ314cnrUlZp5GrRHpejXDbl85IULFzk/bwg2D5zfHhMf1bfHEhYxQUqq/F3pN+aLHsIqKqkHWe +tUNy6mSjhEv9DKgma3GX7lZjZuhCVPnHHd/Qj1vfyDBviP4NxDMcU6ij/UgQ8uQKTuEVV/xuZDDC +VRHc6qnNSlSsKWNEz0pAoNZoWRsz+e86i9sgktxChL8Bq4fA1SCC28a5g4VCXA9DO2pJNdWY9BW/ ++mGBDAkgGNLQFwzLSABQ6XaCjGTXOqAHVcweMcDvOrRl++O/QmueD6i9a5jc2NvLi6Td11n0bt3+ +qsOR0C5CB8AMTVPNJLFMWx5R9N/pkvo= +-----END CERTIFICATE----- + +Certplus Root CA G2 +=================== +-----BEGIN CERTIFICATE----- +MIICHDCCAaKgAwIBAgISESDZkc6uo+jF5//pAq/Pc7xVMAoGCCqGSM49BAMDMD4xCzAJBgNVBAYT +AkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjAeFw0x +NDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0 +cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjB2MBAGByqGSM49AgEGBSuBBAAiA2IA +BM0PW1aC3/BFGtat93nwHcmsltaeTpwftEIRyoa/bfuFo8XlGVzX7qY/aWfYeOKmycTbLXku54uN +Am8xIk0G42ByRZ0OQneezs/lf4WbGOT8zC5y0xaTTsqZY1yhBSpsBqNjMGEwDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMB8GA1Ud +IwQYMBaAFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMAoGCCqGSM49BAMDA2gAMGUCMHD+sAvZ94OX7PNV +HdTcswYO/jOYnYs5kGuUIe22113WTNchp+e/IQ8rzfcq3IUHnQIxAIYUFuXcsGXCwI4Un78kFmjl +vPl5adytRSv3tjFzzAalU5ORGpOucGpnutee5WEaXw== +-----END CERTIFICATE----- + +OpenTrust Root CA G1 +==================== +-----BEGIN CERTIFICATE----- +MIIFbzCCA1egAwIBAgISESCzkFU5fX82bWTCp59rY45nMA0GCSqGSIb3DQEBCwUAMEAxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcx +MB4XDTE0MDUyNjA4NDU1MFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM +CU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzEwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQD4eUbalsUwXopxAy1wpLuwxQjczeY1wICkES3d5oeuXT2R0odsN7fa +Yp6bwiTXj/HbpqbfRm9RpnHLPhsxZ2L3EVs0J9V5ToybWL0iEA1cJwzdMOWo010hOHQX/uMftk87 +ay3bfWAfjH1MBcLrARYVmBSO0ZB3Ij/swjm4eTrwSSTilZHcYTSSjFR077F9jAHiOH3BX2pfJLKO +YheteSCtqx234LSWSE9mQxAGFiQD4eCcjsZGT44ameGPuY4zbGneWK2gDqdkVBFpRGZPTBKnjix9 +xNRbxQA0MMHZmf4yzgeEtE7NCv82TWLxp2NX5Ntqp66/K7nJ5rInieV+mhxNaMbBGN4zK1FGSxyO +9z0M+Yo0FMT7MzUj8czxKselu7Cizv5Ta01BG2Yospb6p64KTrk5M0ScdMGTHPjgniQlQ/GbI4Kq +3ywgsNw2TgOzfALU5nsaqocTvz6hdLubDuHAk5/XpGbKuxs74zD0M1mKB3IDVedzagMxbm+WG+Oi +n6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPwvFEVVJSmdz7QdFG9 +URQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYYEQRVzXR7z2FwefR7LFxckvzluFqr +TJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUl0YhVyE12jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/Px +N3DlCPaTKbYwDQYJKoZIhvcNAQELBQADggIBAB3dAmB84DWn5ph76kTOZ0BP8pNuZtQ5iSas000E +PLuHIT839HEl2ku6q5aCgZG27dmxpGWX4m9kWaSW7mDKHyP7Rbr/jyTwyqkxf3kfgLMtMrpkZ2Cv +uVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbSFXJfLkur1J1juONI5f6ELlgK +n0Md/rcYkoZDSw6cMoYsYPXpSOqV7XAp8dUv/TW0V8/bhUiZucJvbI/NeJWsZCj9VrDDb8O+WVLh +X4SPgPL0DTatdrOjteFkdjpY3H1PXlZs5VVZV6Xf8YpmMIzUUmI4d7S+KNfKNsSbBfD4Fdvb8e80 +nR14SohWZ25g/4/Ii+GOvUKpMwpZQhISKvqxnUOOBZuZ2mKtVzazHbYNeS2WuOvyDEsMpZTGMKcm +GS3tTAZQMPH9WD25SxdfGbRqhFS0OE85og2WaMMolP3tLR9Ka0OWLpABEPs4poEL0L9109S5zvE/ +bw4cHjdx5RiHdRk/ULlepEU0rbDK5uUTdg8xFKmOLZTW1YVNcxVPS/KyPu1svf0OnWZzsD2097+o +4BGkxK51CUpjAEggpsadCwmKtODmzj7HPiY46SvepghJAwSQiumPv+i2tCqjI40cHLI5kqiPAlxA +OXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj1oxx +-----END CERTIFICATE----- + +OpenTrust Root CA G2 +==================== +-----BEGIN CERTIFICATE----- +MIIFbzCCA1egAwIBAgISESChaRu/vbm9UpaPI+hIvyYRMA0GCSqGSIb3DQEBDQUAMEAxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcy +MB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM +CU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzIwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDMtlelM5QQgTJT32F+D3Y5z1zCU3UdSXqWON2ic2rxb95eolq5cSG+ +Ntmh/LzubKh8NBpxGuga2F8ORAbtp+Dz0mEL4DKiltE48MLaARf85KxP6O6JHnSrT78eCbY2albz +4e6WiWYkBuTNQjpK3eCasMSCRbP+yatcfD7J6xcvDH1urqWPyKwlCm/61UWY0jUJ9gNDlP7ZvyCV +eYCYitmJNbtRG6Q3ffyZO6v/v6wNj0OxmXsWEH4db0fEFY8ElggGQgT4hNYdvJGmQr5J1WqIP7wt +UdGejeBSzFfdNTVY27SPJIjki9/ca1TSgSuyzpJLHB9G+h3Ykst2Z7UJmQnlrBcUVXDGPKBWCgOz +3GIZ38i1MH/1PCZ1Eb3XG7OHngevZXHloM8apwkQHZOJZlvoPGIytbU6bumFAYueQ4xncyhZW+vj +3CzMpSZyYhK05pyDRPZRpOLAeiRXyg6lPzq1O4vldu5w5pLeFlwoW5cZJ5L+epJUzpM5ChaHvGOz +9bGTXOBut9Dq+WIyiET7vycotjCVXRIouZW+j1MY5aIYFuJWpLIsEPUdN6b4t/bQWVyJ98LVtZR0 +0dX+G7bw5tYee9I8y6jj9RjzIR9u701oBnstXW5DiabA+aC/gh7PU3+06yzbXfZqfUAkBXKJOAGT +y3HCOV0GEfZvePg3DTmEJwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUajn6QiL35okATV59M4PLuG53hq8wHwYDVR0jBBgwFoAUajn6QiL35okATV59 +M4PLuG53hq8wDQYJKoZIhvcNAQENBQADggIBAJjLq0A85TMCl38th6aP1F5Kr7ge57tx+4BkJamz +Gj5oXScmp7oq4fBXgwpkTx4idBvpkF/wrM//T2h6OKQQbA2xx6R3gBi2oihEdqc0nXGEL8pZ0keI +mUEiyTCYYW49qKgFbdEfwFFEVn8nNQLdXpgKQuswv42hm1GqO+qTRmTFAHneIWv2V6CG1wZy7HBG +S4tz3aAhdT7cHcCP009zHIXZ/n9iyJVvttN7jLpTwm+bREx50B1ws9efAvSyB7DH5fitIw6mVskp +EndI2S9G/Tvw/HRwkqWOOAgfZDC2t0v7NqwQjqBSM2OdAzVWxWm9xiNaJ5T2pBL4LTM8oValX9YZ +6e18CL13zSdkzJTaTkZQh+D5wVOAHrut+0dSixv9ovneDiK3PTNZbNTe9ZUGMg1RGUFcPk8G97kr +gCf2o6p6fAbhQ8MTOWIaNr3gKC6UAuQpLmBVrkA9sHSSXvAgZJY/X0VdiLWK2gKgW0VU3jg9CcCo +SmVGFvyqv1ROTVu+OEO3KMqLM6oaJbolXCkvW0pujOotnCr2BXbgd5eAiN1nE28daCSLT7d0geX0 +YJ96Vdc+N9oWaz53rK4YcJUIeSkDiv7BO7M/Gg+kO14fWKGVyasvc0rQLW6aWQ9VGHgtPFGml4vm +u7JwqkwR3v98KzfUetF3NI/n+UL3PIEMS1IK +-----END CERTIFICATE----- + +OpenTrust Root CA G3 +==================== +-----BEGIN CERTIFICATE----- +MIICITCCAaagAwIBAgISESDm+Ez8JLC+BUCs2oMbNGA/MAoGCCqGSM49BAMDMEAxCzAJBgNVBAYT +AkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEczMB4X +DTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9w +ZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzMwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAARK7liuTcpm3gY6oxH84Bjwbhy6LTAMidnW7ptzg6kjFYwvWYpa3RTqnVkrQ7cG7DK2uu5B +ta1doYXM6h0UZqNnfkbilPPntlahFVmhTzeXuSIevRHr9LIfXsMUmuXZl5mjYzBhMA4GA1UdDwEB +/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAf +BgNVHSMEGDAWgBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAKBggqhkjOPQQDAwNpADBmAjEAj6jcnboM +BBf6Fek9LykBl7+BFjNAk2z8+e2AcG+qj9uEwov1NcoG3GRvaBbhj5G5AjEA2Euly8LQCGzpGPta +3U1fJAuwACEl74+nBCZx4nxp5V2a+EEfOzmTk51V6s2N8fvB +-----END CERTIFICATE----- + +ISRG Root X1 +============ +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UE +BhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNoIEdyb3VwMRUwEwYDVQQD +EwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQG +EwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMT +DElTUkcgUm9vdCBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54r +Vygch77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+0TM8ukj1 +3Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6UA5/TR5d8mUgjU+g4rk8K +b4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sWT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCN +Aymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyHB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ +4Q7e2RCOFvu396j3x+UCB5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf +1b0SHzUvKBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWnOlFu +hjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTnjh8BCNAw1FtxNrQH +usEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbwqHyGO0aoSCqI3Haadr8faqU9GY/r +OPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CIrU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4G +A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY +9umbbjANBgkqhkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ3BebYhtF8GaV +0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KKNFtY2PwByVS5uCbMiogziUwt +hDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJw +TdwJx4nLCgdNbOhdjsnvzqvHu7UrTkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nx +e5AW0wdeRlN8NwdCjNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZA +JzVcoyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq4RgqsahD +YVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPAmRGunUHBcnWEvgJBQl9n +JEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57demyPxgcYxn/eR44/KJ4EBs+lVDR3veyJ +m+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- + +AC RAIZ FNMT-RCM +================ +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNVBAYT +AkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTAeFw0wODEw +MjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJD +TTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBALpxgHpMhm5/yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcf +qQgfBBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAzWHFctPVr +btQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxFtBDXaEAUwED653cXeuYL +j2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z374jNUUeAlz+taibmSXaXvMiwzn15Cou +08YfxGyqxRxqAQVKL9LFwag0Jl1mpdICIfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mw +WsXmo8RZZUc1g16p6DULmbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnT +tOmlcYF7wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peSMKGJ +47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2ZSysV4999AeU14EC +ll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMetUqIJ5G+GR4of6ygnXYMgrwTJbFaa +i0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FPd9xf3E6Jobd2Sn9R2gzL+HYJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1o +dHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1RXxlDPiyN8+s +D8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYMLVN0V2Ue1bLdI4E7pWYjJ2cJ +j+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrT +Qfv6MooqtyuGC2mDOL7Nii4LcK2NJpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW ++YJF1DngoABd15jmfZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7 +Ixjp6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp1txyM/1d +8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B9kiABdcPUXmsEKvU7ANm +5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wokRqEIr9baRRmW1FMdW4R58MD3R++Lj8UG +rp1MYp3/RgT408m2ECVAdf4WqslKYIYvuu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- + +Amazon Root CA 1 +================ +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD +VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1 +MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv +bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH +FzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ +gLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t +dHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce +VOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3 +DQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM +CCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy +8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa +2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2 +xJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- + +Amazon Root CA 2 +================ +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD +VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1 +MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv +bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4 +kHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp +N+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9 +AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd +fLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx +kv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS +btqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0 +Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN +c/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf+ +3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw +DPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA +A7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE +YFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW +xkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ +gj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW +aQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV +Yh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3 +KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi +JUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw= +-----END CERTIFICATE----- + +Amazon Root CA 3 +================ +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG +EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy +NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ +MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB +f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr +Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43 +rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc +eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw== +-----END CERTIFICATE----- + +Amazon Root CA 4 +================ +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG +EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy +NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ +MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN +/sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri +83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA +MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1 +AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- + +LuxTrust Global Root 2 +====================== +-----BEGIN CERTIFICATE----- +MIIFwzCCA6ugAwIBAgIUCn6m30tEntpqJIWe5rgV0xZ/u7EwDQYJKoZIhvcNAQELBQAwRjELMAkG +A1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNVBAMMFkx1eFRydXN0IEdsb2Jh +bCBSb290IDIwHhcNMTUwMzA1MTMyMTU3WhcNMzUwMzA1MTMyMTU3WjBGMQswCQYDVQQGEwJMVTEW +MBQGA1UECgwNTHV4VHJ1c3QgUy5BLjEfMB0GA1UEAwwWTHV4VHJ1c3QgR2xvYmFsIFJvb3QgMjCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANeFl78RmOnwYoNMPIf5U2o3C/IPPIfOb9wm +Kb3FibrJgz337spbxm1Jc7TJRqMbNBM/wYlFV/TZsfs2ZUv7COJIcRHIbjuend+JZTemhfY7RBi2 +xjcwYkSSl2l9QjAk5A0MiWtj3sXh306pFGxT4GHO9hcvHTy95iJMHZP1EMShduxq3sVs35a0VkBC +wGKSMKEtFZSg0iAGCW5qbeXrt77U8PEVfIvmTroTzEsnXpk8F12PgX8zPU/TPxvsXD/wPEx1bvKm +1Z3aLQdjAsZy6ZS8TEmVT4hSyNvoaYL4zDRbIvCGp4m9SAptZoFtyMhk+wHh9OHe2Z7d21vUKpkm +FRseTJIpgp7VkoGSQXAZ96Tlk0u8d2cx3Rz9MXANF5kM+Qw5GSoXtTBxVdUPrljhPS80m8+f9niF +wpN6cj5mj5wWEWCPnolvZ77gR1o7DJpni89Gxq44o/KnvObWhWszJHAiS8sIm7vI+AIpHb4gDEa/ +a4ebsypmQjVGbKq6rfmYe+lQVRQxv7HaLe2ArWgk+2mr2HETMOZns4dA/Yl+8kPREd8vZS9kzl8U +ubG/Mb2HeFpZZYiq/FkySIbWTLkpS5XTdvN3JW1CHDiDTf2jX5t/Lax5Gw5CMZdjpPuKadUiDTSQ +MC6otOBttpSsvItO13D8xTiOZCXhTTmQzsmHhFhxAgMBAAGjgagwgaUwDwYDVR0TAQH/BAUwAwEB +/zBCBgNVHSAEOzA5MDcGByuBKwEBAQowLDAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBvc2l0b3J5 +Lmx1eHRydXN0Lmx1MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBT/GCh2+UgFLKGu8SsbK7JT ++Et8szAdBgNVHQ4EFgQU/xgodvlIBSyhrvErGyuyU/hLfLMwDQYJKoZIhvcNAQELBQADggIBAGoZ +FO1uecEsh9QNcH7X9njJCwROxLHOk3D+sFTAMs2ZMGQXvw/l4jP9BzZAcg4atmpZ1gDlaCDdLnIN +H2pkMSCEfUmmWjfrRcmF9dTHF5kH5ptV5AzoqbTOjFu1EVzPig4N1qx3gf4ynCSecs5U89BvolbW +7MM3LGVYvlcAGvI1+ut7MV3CwRI9loGIlonBWVx65n9wNOeD4rHh4bhY79SV5GCc8JaXcozrhAIu +ZY+kt9J/Z93I055cqqmkoCUUBpvsT34tC38ddfEz2O3OuHVtPlu5mB0xDVbYQw8wkbIEa91WvpWA +VWe+2M2D2RjuLg+GLZKecBPs3lHJQ3gCpU3I+V/EkVhGFndadKpAvAefMLmx9xIX3eP/JEAdemrR +TxgKqpAd60Ae36EeRJIQmvKN4dFLRp7oRUKX6kWZ8+xm1QL68qZKJKrezrnK+T+Tb/mjuuqlPpmt +/f97mfVl7vBZKGfXkJWkE4SphMHozs51k2MavDzq1WQfLSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc +7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31I +iyBMz2TWuJdGsE7RKlY6oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr +-----END CERTIFICATE----- + +TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 +============================================= +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIxGDAWBgNVBAcT +D0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxpbXNlbCB2ZSBUZWtub2xvamlr +IEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0wKwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24g +TWVya2V6aSAtIEthbXUgU00xNjA0BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRp +ZmlrYXNpIC0gU3VydW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYD +VQQGEwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXllIEJpbGlt +c2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklUQUsxLTArBgNVBAsTJEth +bXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBTTTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11 +IFNNIFNTTCBLb2sgU2VydGlmaWthc2kgLSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAr3UwM6q7a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y8 +6Ij5iySrLqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INrN3wc +wv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2XYacQuFWQfw4tJzh0 +3+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/iSIzL+aFCr2lqBs23tPcLG07xxO9 +WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4fAJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQU +ZT/HiobGPN08VFw1+DrtUgxHV8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJ +KoZIhvcNAQELBQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPfIPP54+M638yc +lNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4lzwDGrpDxpa5RXI4s6ehlj2R +e37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0j +q5Rm+K37DwhuJi1/FwcJsoz7UMCflo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- diff --git a/misc/cloudformation.template b/misc/cloudformation.template new file mode 100644 index 0000000000..db4e59eb7e --- /dev/null +++ b/misc/cloudformation.template @@ -0,0 +1,317 @@ + +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Description": "mapbox-gl-native travis resources", + "Resources": { + "BuildUser": { + "Type": "AWS::IAM::User", + "Properties": { + "Policies": [ + { + "PolicyName": "list-testing", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:ListBucket" + ], + "Effect": "Allow", + "Resource": [ + "arn:aws:s3:::mapbox" + ], + "Condition": { + "StringLike": { + "s3:prefix": "mapbox-gl-native/*" + } + } + } + ] + } + }, + { + "PolicyName": "build-testing", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:DeleteObject", + "s3:GetObject", + "s3:GetObjectAcl", + "s3:PutObject", + "s3:PutObjectAcl" + ], + "Effect": "Allow", + "Resource": [ + "arn:aws:s3:::mapbox/mapbox-gl-native/*" + ] + } + ] + } + }, + { + "PolicyName": "list-node", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:ListBucket" + ], + "Resource": [ + "arn:aws:s3:::mapbox-node-binary" + ], + "Effect": "Allow" + } + ] + } + }, + { + "PolicyName": "build-node", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:DeleteObject", + "s3:GetObject", + "s3:GetObjectAcl", + "s3:PutObject", + "s3:PutObjectAcl" + ], + "Resource": [ + "arn:aws:s3:::mapbox-node-binary/@mapbox/mapbox-gl-native/*" + ], + "Effect": "Allow" + } + ] + } + }, + { + "PolicyName": "android", + "PolicyDocument": { + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "ec2:DescribeInstances", + "ec2:RunInstances", + "ec2:CreateTags", + "ec2:GetConsoleOutput" + ], + "Resource": [ + "*" + ] + }, + { + "Effect": "Allow", + "Action": "iam:PassRole", + "Resource": { + "Fn::GetAtt": [ + "AndroidRole", + "Arn" + ] + } + } + ] + } + }, + { + "PolicyName": "cloudwatch-metrics", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "cloudwatch:PutMetricData", + "cloudwatch:GetMetricData", + "cloudwatch:GetMetricStatistics" + ], + "Effect": "Allow", + "Resource": [ + "*" + ] + } + ] + } + }, + { + "PolicyName": "get-signing-key", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject" + ], + "Effect": "Allow", + "Resource": [ + "arn:aws:s3:::mapbox/android/signing-credentials/secring.gpg" + ] + } + ] + } + }, + { + "PolicyName": "publish-metrics", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:DeleteObject", + "s3:GetObject", + "s3:GetObjectAcl", + "s3:PutObject", + "s3:PutObjectAcl" + ], + "Effect": "Allow", + "Resource": [ + "arn:aws:s3:::mapbox/mapbox-gl-native/metrics/*" + ] + } + ] + } + }, + { + "PolicyName": "cloudwatch-metrics", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "cloudwatch:PutMetricData", + "cloudwatch:GetMetricData", + "cloudwatch:GetMetricStatistics" + ], + "Effect": "Allow", + "Resource": [ + "*" + ] + } + ] + } + }, + { + "PolicyName": "publish-nightlies", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:DeleteObject", + "s3:GetObject", + "s3:GetObjectAcl", + "s3:PutObject", + "s3:PutObjectAcl" + ], + "Effect": "Allow", + "Resource": [ + "arn:aws:s3:::mapbox/mapbox-gl-native/ios/builds/*" + ] + } + ] + } + } + ] + } + }, + "BuildUserKey": { + "Type": "AWS::IAM::AccessKey", + "Properties": { + "UserName": { + "Ref": "BuildUser" + } + } + }, + "AndroidRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": [ + "ec2.amazonaws.com" + ] + }, + "Action": [ + "sts:AssumeRole" + ] + } + ] + }, + "Policies": [ + { + "PolicyName": "android-testing", + "PolicyDocument": { + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:PutObject" + ], + "Resource": [ + "arn:aws:s3:::mapbox-gl-testing/android/*" + ] + } + ] + } + }, + { + "PolicyName": "android", + "PolicyDocument": { + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:PutObject" + ], + "Resource": [ + "arn:aws:s3:::mapbox/mapbox-gl-native/android/build/*" + ] + } + ] + } + } + ], + "Path": "/android-gl-build/travis/role/" + } + }, + "AndroidInstanceProfile": { + "Type": "AWS::IAM::InstanceProfile", + "Properties": { + "Roles": [ + { + "Ref": "AndroidRole" + } + ], + "Path": "/android-gl-build/travis/instance-profile/" + } + } + }, + "Outputs": { + "AccessKeyId": { + "Value": { + "Ref": "BuildUserKey" + } + }, + "SecretAccessKey": { + "Value": { + "Fn::GetAtt": [ + "BuildUserKey", + "SecretAccessKey" + ] + } + }, + "AndroidInstanceProfile": { + "Value": { + "Fn::GetAtt": [ + "AndroidInstanceProfile", + "Arn" + ] + } + }, + "AndroidRole": { + "Value": { + "Fn::GetAtt": [ + "AndroidRole", + "Arn" + ] + } + } + } +} diff --git a/misc/mb-icon-blue-circle.svg b/misc/mb-icon-blue-circle.svg new file mode 100644 index 0000000000..93f8c86a50 --- /dev/null +++ b/misc/mb-icon-blue-circle.svg @@ -0,0 +1,115 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/misc/mb-icon-blue-square.png b/misc/mb-icon-blue-square.png new file mode 100644 index 0000000000..0a9bc1cdea Binary files /dev/null and b/misc/mb-icon-blue-square.png differ diff --git a/misc/mb-icon-blue-square.svg b/misc/mb-icon-blue-square.svg new file mode 100644 index 0000000000..de531b179b --- /dev/null +++ b/misc/mb-icon-blue-square.svg @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/misc/proto/binary_program.proto b/misc/proto/binary_program.proto new file mode 100644 index 0000000000..9d06a209c3 --- /dev/null +++ b/misc/proto/binary_program.proto @@ -0,0 +1,18 @@ +// Protocol Version 1 + +package mapboxgl.binary_program; + +option optimize_for = LITE_RUNTIME; + +message binding { + required string name = 1; + required uint32 value = 2; +} + +message binary_program { + required uint32 format = 1; + required bytes code = 2; + repeated binding attribute = 3; + repeated binding uniform = 4; + optional string identifier = 5; +} diff --git a/misc/proto/glyphs.proto b/misc/proto/glyphs.proto new file mode 100644 index 0000000000..6930b47a2b --- /dev/null +++ b/misc/proto/glyphs.proto @@ -0,0 +1,33 @@ +// Protocol Version 1 + +package mapboxgl.glyphs; + +option optimize_for = LITE_RUNTIME; + +// Stores a glyph with metrics and optional SDF bitmap information. +message glyph { + required uint32 id = 1; + + // A signed distance field of the glyph with a border of 3 pixels. + optional bytes bitmap = 2; + + // Glyph metrics. + required uint32 width = 3; + required uint32 height = 4; + required sint32 left = 5; + required sint32 top = 6; + required uint32 advance = 7; +} + +// Stores fontstack information and a list of faces. +message fontstack { + required string name = 1; + required string range = 2; + repeated glyph glyphs = 3; +} + +message glyphs { + repeated fontstack stacks = 1; + + extensions 16 to 8191; +} diff --git a/misc/proto/style.proto b/misc/proto/style.proto new file mode 100644 index 0000000000..90e5b65061 --- /dev/null +++ b/misc/proto/style.proto @@ -0,0 +1,110 @@ +enum bucket_type { + fill = 1; + line = 2; + point = 3; + + background = 15; +} + +enum cap_type { + round_cap = 1; + butt_cap = 2; + square_cap = 3; +} + +enum join_type { + miter_join = 1; + bevel_join = 2; + round_join = 3; +} + +enum winding_type { + evenodd = 1; + nonzero = 2; +} + +enum property_type { + null = 1; + constant = 2; + stops = 3; + linear = 4; +} + +message value { + // Exactly one of these values may be present in a valid message + optional string string_value = 1; + optional float float_value = 2; + optional double double_value = 3; + optional int64 int_value = 4; + optional uint64 uint_value = 5; + optional sint64 sint_value = 6; + optional bool bool_value = 7; + + extensions 8 to max; +} + +message bucket { + required string name = 1; + required bucket_type type = 2; + + // Specify what data to pull into this bucket + required string source_name = 3; + required string source_layer = 4; + optional string source_field = 5; + repeated value source_value = 6; + + // Specifies how the geometry for this bucket should be created + optional cap_type cap = 7; + optional join_type join = 8; + optional string font = 9; + optional float font_size = 10; +} + +message layer { + required string name = 1; + optional string bucket_name = 2; + repeated layer child_layer = 3; +} + +message property { + required property_type function = 1; + repeated float value = 2 [ packed = true ]; +} + +message fill_style { + required string layer_name = 1; + optional property hidden = 2; + optional winding_type winding = 3 [ default = nonzero ]; + optional property antialias = 4; + optional fixed32 fill_color = 5 [ default = 0x000000FF ]; // rgba (=> rgb << 8 | 0xFF for opaque!) + optional fixed32 stroke_color = 6; // if none is specified, no stroke will be painted + optional property opacity = 7; // values from 0..1 + optional string image = 8; + // TODO: translate x/y +} + +message stroke_style { + required string layer_name = 1; + optional property hidden = 2; + optional fixed32 color = 3 [ default = 0x000000FF ]; // rgba (=> rgb << 8 | 0xFF for opaque!) + optional property width = 4; + optional property offset = 5; + optional property opacity = 6; // values from 0..1 + // line join + line cap are already defined in the + // TODO: dasharray + // TODO: image/icon + // TODO: translate x/y +} + +message class { + required string name = 1; + repeated fill_style fill = 2; + repeated stroke_style stroke = 3; +} + +// root level object +message style { + repeated bucket bucket = 1; + repeated layer layer = 2; + repeated class class = 3; +} diff --git a/misc/proto/vector_tile.proto b/misc/proto/vector_tile.proto new file mode 100644 index 0000000000..1cde2c7aa9 --- /dev/null +++ b/misc/proto/vector_tile.proto @@ -0,0 +1,109 @@ +// Protocol Version 1 + +package mapboxgl.vector; + +option optimize_for = LITE_RUNTIME; + +enum geom_type { + Unknown = 0; + Point = 1; + LineString = 2; + Polygon = 3; +} + +// Variant type encoding +message value { + // Exactly one of these values may be present in a valid message + optional string string_value = 1; + optional float float_value = 2; + optional double double_value = 3; + optional int64 int_value = 4; + optional uint64 uint_value = 5; + optional sint64 sint_value = 6; + optional bool bool_value = 7; + + extensions 8 to max; +} + +message feature { + optional uint64 id = 1; + + // Tags of this feature. Even numbered values refer to the nth + // value in the keys list on the tile message, odd numbered + // values refer to the nth value in the values list on the tile + // message. + repeated uint32 tags = 2 [ packed = true ]; + + // The type of geometry stored in this feature. + optional geom_type type = 3 [ default = Unknown ]; + + // Contains a stream of commands and parameters (vertices). The + // repeat count is shifted to the left by 3 bits. This means + // that the command has 3 bits (0-15). The repeat count + // indicates how often this command is to be repeated. Defined + // commands are: + // - MoveTo: 1 (2 parameters follow) + // - LineTo: 2 (2 parameters follow) + // - ClosePath: 15 (no parameters follow) + // + // Ex.: MoveTo(3, 6), LineTo(8, 12), LineTo(20, 34), ClosePath + // Encoded as: [ 3 6 18 5 6 12 22 15 ] + // == command type 15 (ClosePath) + // ===== relative LineTo(+12, +22) == LineTo(20, 34) + // === relative LineTo(+5, +6) == LineTo(8, 12) + // == [00010 010] = command type 2 (LineTo), length 2 + // === relative MoveTo(+3, +6) + // = implicit command type 1 (MoveTo), length 1 + // Commands are encoded as uint32 varints, vertex parameters are + // encoded as sint32 varints (zigzag). Vertex parameters are + // also encoded as deltas to the previous position. The original + // position is (0,0) + repeated uint32 geometry = 4 [ packed = true ]; + + // A list of indices to the geometry array that specify a triangulation of + // this geometry. This must only exist if this feature is a polygon. + // These are the valid indices for the example above: + // 0 ==> (3/6) + // 1 ==> (8/12) + // 2 ==> (20/34) + // Indices beyond 2 are invalid, as the total number of vertices is 3. + repeated sint32 triangulation = 5 [ packed = true ]; + + // The total number of vertices encoded in the geometry field. This is can + // be deduced by manually iterating through the geometry field, but we can + // just as well store the number to avoid the overhead on parsing. + optional uint32 vertex_count = 6; +} + +message layer { + // Any compliant implementation must first read the version + // number encoded in this message and choose the correct + // implementation for this version number before proceeding to + // decode other parts of this message. + required uint32 version = 15 [ default = 1 ]; + + required string name = 1; + + // The actual features in this tile. + repeated feature features = 2; + + // Dictionary encoding for keys + repeated string keys = 3; + + // Dictionary encoding for values + repeated value values = 4; + + // The bounding box in this tile spans from 0..4095 units + optional uint32 extent = 5 [ default = 4096 ]; + + // Total vertex count in this layer. + optional uint32 vertex_count = 6; + + extensions 16 to max; +} + +message tile { + repeated layer layers = 3; + + extensions 16 to 8191; +} diff --git a/platform/linux/config.cmake b/platform/linux/config.cmake index 6de571e88b..dd5f0af112 100644 --- a/platform/linux/config.cmake +++ b/platform/linux/config.cmake @@ -115,7 +115,7 @@ macro(mbgl_platform_glfw) add_custom_command( TARGET mbgl-glfw POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_SOURCE_DIR}/common/ca-bundle.crt + ${CMAKE_SOURCE_DIR}/misc/ca-bundle.crt ${CMAKE_CURRENT_BINARY_DIR}/ca-bundle.crt ) endmacro() diff --git a/platform/qt/resources/common.qrc b/platform/qt/resources/common.qrc index 598059d55e..24f663df77 100644 --- a/platform/qt/resources/common.qrc +++ b/platform/qt/resources/common.qrc @@ -1,6 +1,6 @@ - ../../../common/mb-icon-blue-square.png + ../../../misc/mb-icon-blue-square.png ../../../platform/default/resources/default_marker.svg source1.geojson source2.geojson diff --git a/proto/binary_program.proto b/proto/binary_program.proto deleted file mode 100644 index 9d06a209c3..0000000000 --- a/proto/binary_program.proto +++ /dev/null @@ -1,18 +0,0 @@ -// Protocol Version 1 - -package mapboxgl.binary_program; - -option optimize_for = LITE_RUNTIME; - -message binding { - required string name = 1; - required uint32 value = 2; -} - -message binary_program { - required uint32 format = 1; - required bytes code = 2; - repeated binding attribute = 3; - repeated binding uniform = 4; - optional string identifier = 5; -} diff --git a/proto/glyphs.proto b/proto/glyphs.proto deleted file mode 100644 index 6930b47a2b..0000000000 --- a/proto/glyphs.proto +++ /dev/null @@ -1,33 +0,0 @@ -// Protocol Version 1 - -package mapboxgl.glyphs; - -option optimize_for = LITE_RUNTIME; - -// Stores a glyph with metrics and optional SDF bitmap information. -message glyph { - required uint32 id = 1; - - // A signed distance field of the glyph with a border of 3 pixels. - optional bytes bitmap = 2; - - // Glyph metrics. - required uint32 width = 3; - required uint32 height = 4; - required sint32 left = 5; - required sint32 top = 6; - required uint32 advance = 7; -} - -// Stores fontstack information and a list of faces. -message fontstack { - required string name = 1; - required string range = 2; - repeated glyph glyphs = 3; -} - -message glyphs { - repeated fontstack stacks = 1; - - extensions 16 to 8191; -} diff --git a/proto/style.proto b/proto/style.proto deleted file mode 100644 index 90e5b65061..0000000000 --- a/proto/style.proto +++ /dev/null @@ -1,110 +0,0 @@ -enum bucket_type { - fill = 1; - line = 2; - point = 3; - - background = 15; -} - -enum cap_type { - round_cap = 1; - butt_cap = 2; - square_cap = 3; -} - -enum join_type { - miter_join = 1; - bevel_join = 2; - round_join = 3; -} - -enum winding_type { - evenodd = 1; - nonzero = 2; -} - -enum property_type { - null = 1; - constant = 2; - stops = 3; - linear = 4; -} - -message value { - // Exactly one of these values may be present in a valid message - optional string string_value = 1; - optional float float_value = 2; - optional double double_value = 3; - optional int64 int_value = 4; - optional uint64 uint_value = 5; - optional sint64 sint_value = 6; - optional bool bool_value = 7; - - extensions 8 to max; -} - -message bucket { - required string name = 1; - required bucket_type type = 2; - - // Specify what data to pull into this bucket - required string source_name = 3; - required string source_layer = 4; - optional string source_field = 5; - repeated value source_value = 6; - - // Specifies how the geometry for this bucket should be created - optional cap_type cap = 7; - optional join_type join = 8; - optional string font = 9; - optional float font_size = 10; -} - -message layer { - required string name = 1; - optional string bucket_name = 2; - repeated layer child_layer = 3; -} - -message property { - required property_type function = 1; - repeated float value = 2 [ packed = true ]; -} - -message fill_style { - required string layer_name = 1; - optional property hidden = 2; - optional winding_type winding = 3 [ default = nonzero ]; - optional property antialias = 4; - optional fixed32 fill_color = 5 [ default = 0x000000FF ]; // rgba (=> rgb << 8 | 0xFF for opaque!) - optional fixed32 stroke_color = 6; // if none is specified, no stroke will be painted - optional property opacity = 7; // values from 0..1 - optional string image = 8; - // TODO: translate x/y -} - -message stroke_style { - required string layer_name = 1; - optional property hidden = 2; - optional fixed32 color = 3 [ default = 0x000000FF ]; // rgba (=> rgb << 8 | 0xFF for opaque!) - optional property width = 4; - optional property offset = 5; - optional property opacity = 6; // values from 0..1 - // line join + line cap are already defined in the - // TODO: dasharray - // TODO: image/icon - // TODO: translate x/y -} - -message class { - required string name = 1; - repeated fill_style fill = 2; - repeated stroke_style stroke = 3; -} - -// root level object -message style { - repeated bucket bucket = 1; - repeated layer layer = 2; - repeated class class = 3; -} diff --git a/proto/vector_tile.proto b/proto/vector_tile.proto deleted file mode 100644 index 1cde2c7aa9..0000000000 --- a/proto/vector_tile.proto +++ /dev/null @@ -1,109 +0,0 @@ -// Protocol Version 1 - -package mapboxgl.vector; - -option optimize_for = LITE_RUNTIME; - -enum geom_type { - Unknown = 0; - Point = 1; - LineString = 2; - Polygon = 3; -} - -// Variant type encoding -message value { - // Exactly one of these values may be present in a valid message - optional string string_value = 1; - optional float float_value = 2; - optional double double_value = 3; - optional int64 int_value = 4; - optional uint64 uint_value = 5; - optional sint64 sint_value = 6; - optional bool bool_value = 7; - - extensions 8 to max; -} - -message feature { - optional uint64 id = 1; - - // Tags of this feature. Even numbered values refer to the nth - // value in the keys list on the tile message, odd numbered - // values refer to the nth value in the values list on the tile - // message. - repeated uint32 tags = 2 [ packed = true ]; - - // The type of geometry stored in this feature. - optional geom_type type = 3 [ default = Unknown ]; - - // Contains a stream of commands and parameters (vertices). The - // repeat count is shifted to the left by 3 bits. This means - // that the command has 3 bits (0-15). The repeat count - // indicates how often this command is to be repeated. Defined - // commands are: - // - MoveTo: 1 (2 parameters follow) - // - LineTo: 2 (2 parameters follow) - // - ClosePath: 15 (no parameters follow) - // - // Ex.: MoveTo(3, 6), LineTo(8, 12), LineTo(20, 34), ClosePath - // Encoded as: [ 3 6 18 5 6 12 22 15 ] - // == command type 15 (ClosePath) - // ===== relative LineTo(+12, +22) == LineTo(20, 34) - // === relative LineTo(+5, +6) == LineTo(8, 12) - // == [00010 010] = command type 2 (LineTo), length 2 - // === relative MoveTo(+3, +6) - // = implicit command type 1 (MoveTo), length 1 - // Commands are encoded as uint32 varints, vertex parameters are - // encoded as sint32 varints (zigzag). Vertex parameters are - // also encoded as deltas to the previous position. The original - // position is (0,0) - repeated uint32 geometry = 4 [ packed = true ]; - - // A list of indices to the geometry array that specify a triangulation of - // this geometry. This must only exist if this feature is a polygon. - // These are the valid indices for the example above: - // 0 ==> (3/6) - // 1 ==> (8/12) - // 2 ==> (20/34) - // Indices beyond 2 are invalid, as the total number of vertices is 3. - repeated sint32 triangulation = 5 [ packed = true ]; - - // The total number of vertices encoded in the geometry field. This is can - // be deduced by manually iterating through the geometry field, but we can - // just as well store the number to avoid the overhead on parsing. - optional uint32 vertex_count = 6; -} - -message layer { - // Any compliant implementation must first read the version - // number encoded in this message and choose the correct - // implementation for this version number before proceeding to - // decode other parts of this message. - required uint32 version = 15 [ default = 1 ]; - - required string name = 1; - - // The actual features in this tile. - repeated feature features = 2; - - // Dictionary encoding for keys - repeated string keys = 3; - - // Dictionary encoding for values - repeated value values = 4; - - // The bounding box in this tile spans from 0..4095 units - optional uint32 extent = 5 [ default = 4096 ]; - - // Total vertex count in this layer. - optional uint32 vertex_count = 6; - - extensions 16 to max; -} - -message tile { - repeated layer layers = 3; - - extensions 16 to 8191; -} diff --git a/scripts/update_ca_bundle.sh b/scripts/update_ca_bundle.sh index 992bd7030f..3bd268bd0c 100755 --- a/scripts/update_ca_bundle.sh +++ b/scripts/update_ca_bundle.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -cd common +cd misc curl https://raw.githubusercontent.com/curl/curl/master/lib/mk-ca-bundle.pl | perl rm certdata.txt -- cgit v1.2.1 From 637892cd6f0f8953b787b9d727bdf82ed3813c96 Mon Sep 17 00:00:00 2001 From: Jason Wray Date: Tue, 2 Jan 2018 15:36:37 -0500 Subject: [ios, macos] Move private categories into explicitly private headers Instead of creating `MGLAdditions` categories/files for our own classes, this standardizes on the `Private` convention that we had been using elsewhere. This also fixes build errors where the `MGLAdditions` categories weren't importing their parents. --- platform/darwin/src/MGLFeature.mm | 6 +-- platform/darwin/src/MGLPolygon+MGLAdditions.h | 7 --- platform/darwin/src/MGLPolygon+MGLAdditions.m | 27 ----------- platform/darwin/src/MGLPolygon.mm | 26 ++++++++++- platform/darwin/src/MGLPolygon_Private.h | 11 +++++ platform/darwin/src/MGLPolyline+MGLAdditions.h | 7 --- platform/darwin/src/MGLPolyline+MGLAdditions.m | 14 ------ platform/darwin/src/MGLPolyline.mm | 13 +++++- platform/darwin/src/MGLPolyline_Private.h | 12 +++++ platform/darwin/src/MGLStyle.mm | 2 +- platform/darwin/src/MGLVectorSource+MGLAdditions.h | 15 ------ platform/darwin/src/MGLVectorSource+MGLAdditions.m | 53 ---------------------- platform/darwin/src/MGLVectorSource.mm | 53 ++++++++++++++++++++++ platform/darwin/src/MGLVectorSource_Private.h | 7 +++ platform/ios/ios.xcodeproj/project.pbxproj | 44 ++++-------------- platform/ios/src/MGLMapAccessibilityElement.mm | 5 +- platform/ios/src/MGLMapView.mm | 2 +- platform/macos/app/MapDocument.m | 2 +- platform/macos/macos.xcodeproj/project.pbxproj | 32 ++++--------- 19 files changed, 143 insertions(+), 195 deletions(-) delete mode 100644 platform/darwin/src/MGLPolygon+MGLAdditions.h delete mode 100644 platform/darwin/src/MGLPolygon+MGLAdditions.m create mode 100644 platform/darwin/src/MGLPolygon_Private.h delete mode 100644 platform/darwin/src/MGLPolyline+MGLAdditions.h delete mode 100644 platform/darwin/src/MGLPolyline+MGLAdditions.m create mode 100644 platform/darwin/src/MGLPolyline_Private.h delete mode 100644 platform/darwin/src/MGLVectorSource+MGLAdditions.h delete mode 100644 platform/darwin/src/MGLVectorSource+MGLAdditions.m diff --git a/platform/darwin/src/MGLFeature.mm b/platform/darwin/src/MGLFeature.mm index 84f1a1ff25..033052bda8 100644 --- a/platform/darwin/src/MGLFeature.mm +++ b/platform/darwin/src/MGLFeature.mm @@ -7,11 +7,11 @@ #import "MGLShape_Private.h" #import "MGLPointCollection_Private.h" -#import "MGLPolyline+MGLAdditions.h" -#import "MGLPolygon+MGLAdditions.h" +#import "MGLPolyline_Private.h" +#import "MGLPolygon_Private.h" + #import "NSDictionary+MGLAdditions.h" #import "NSArray+MGLAdditions.h" - #import "NSExpression+MGLAdditions.h" #import diff --git a/platform/darwin/src/MGLPolygon+MGLAdditions.h b/platform/darwin/src/MGLPolygon+MGLAdditions.h deleted file mode 100644 index f409fb96ca..0000000000 --- a/platform/darwin/src/MGLPolygon+MGLAdditions.h +++ /dev/null @@ -1,7 +0,0 @@ -#import - -@interface MGLPolygon (MGLAdditions) - -- (NS_ARRAY_OF(id) *)mgl_coordinates; - -@end diff --git a/platform/darwin/src/MGLPolygon+MGLAdditions.m b/platform/darwin/src/MGLPolygon+MGLAdditions.m deleted file mode 100644 index 3e76a37157..0000000000 --- a/platform/darwin/src/MGLPolygon+MGLAdditions.m +++ /dev/null @@ -1,27 +0,0 @@ -#import "MGLPolygon+MGLAdditions.h" - -@implementation MGLPolygon (MGLAdditions) - -- (NS_ARRAY_OF(id) *)mgl_coordinates { - NSMutableArray *coordinates = [NSMutableArray array]; - - NSMutableArray *exteriorRing = [NSMutableArray array]; - for (NSUInteger index = 0; index < self.pointCount; index++) { - CLLocationCoordinate2D coordinate = self.coordinates[index]; - [exteriorRing addObject:@[@(coordinate.longitude), @(coordinate.latitude)]]; - } - [coordinates addObject:exteriorRing]; - - for (MGLPolygon *interiorPolygon in self.interiorPolygons) { - NSMutableArray *interiorRing = [NSMutableArray array]; - for (int index = 0; index < interiorPolygon.pointCount; index++) { - CLLocationCoordinate2D coordinate = interiorPolygon.coordinates[index]; - [interiorRing addObject:@[@(coordinate.longitude), @(coordinate.latitude)]]; - } - [coordinates addObject:interiorRing]; - } - - return [coordinates copy]; -} - -@end diff --git a/platform/darwin/src/MGLPolygon.mm b/platform/darwin/src/MGLPolygon.mm index e7843224e9..2af768d514 100644 --- a/platform/darwin/src/MGLPolygon.mm +++ b/platform/darwin/src/MGLPolygon.mm @@ -1,9 +1,9 @@ -#import "MGLPolygon.h" +#import "MGLPolygon_Private.h" #import "MGLMultiPoint_Private.h" #import "MGLGeometry_Private.h" -#import "MGLPolygon+MGLAdditions.h" +#import "MGLFeature.h" #import #import @@ -102,6 +102,28 @@ @"coordinates": self.mgl_coordinates}; } +- (NS_ARRAY_OF(id) *)mgl_coordinates { + NSMutableArray *coordinates = [NSMutableArray array]; + + NSMutableArray *exteriorRing = [NSMutableArray array]; + for (NSUInteger index = 0; index < self.pointCount; index++) { + CLLocationCoordinate2D coordinate = self.coordinates[index]; + [exteriorRing addObject:@[@(coordinate.longitude), @(coordinate.latitude)]]; + } + [coordinates addObject:exteriorRing]; + + for (MGLPolygon *interiorPolygon in self.interiorPolygons) { + NSMutableArray *interiorRing = [NSMutableArray array]; + for (int index = 0; index < interiorPolygon.pointCount; index++) { + CLLocationCoordinate2D coordinate = interiorPolygon.coordinates[index]; + [interiorRing addObject:@[@(coordinate.longitude), @(coordinate.latitude)]]; + } + [coordinates addObject:interiorRing]; + } + + return [coordinates copy]; +} + @end @interface MGLMultiPolygon () diff --git a/platform/darwin/src/MGLPolygon_Private.h b/platform/darwin/src/MGLPolygon_Private.h new file mode 100644 index 0000000000..75afcd61f6 --- /dev/null +++ b/platform/darwin/src/MGLPolygon_Private.h @@ -0,0 +1,11 @@ +#import "MGLPolygon.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface MGLPolygon (Private) + +- (NS_ARRAY_OF(id) *)mgl_coordinates; + +@end + +NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLPolyline+MGLAdditions.h b/platform/darwin/src/MGLPolyline+MGLAdditions.h deleted file mode 100644 index 4cdbbf17f9..0000000000 --- a/platform/darwin/src/MGLPolyline+MGLAdditions.h +++ /dev/null @@ -1,7 +0,0 @@ -#import - -@interface MGLPolyline (MGLAdditions) - -- (NS_ARRAY_OF(id) *)mgl_coordinates; - -@end diff --git a/platform/darwin/src/MGLPolyline+MGLAdditions.m b/platform/darwin/src/MGLPolyline+MGLAdditions.m deleted file mode 100644 index d1db2c58a0..0000000000 --- a/platform/darwin/src/MGLPolyline+MGLAdditions.m +++ /dev/null @@ -1,14 +0,0 @@ -#import "MGLPolyline+MGLAdditions.h" - -@implementation MGLPolyline (MGLAdditions) - -- (NS_ARRAY_OF(id) *)mgl_coordinates { - NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:self.pointCount]; - for (NSUInteger index = 0; index < self.pointCount; index++) { - CLLocationCoordinate2D coordinate = self.coordinates[index]; - [coordinates addObject:@[@(coordinate.longitude), @(coordinate.latitude)]]; - } - return [coordinates copy]; -} - -@end diff --git a/platform/darwin/src/MGLPolyline.mm b/platform/darwin/src/MGLPolyline.mm index 0e371a4dda..e011d09215 100644 --- a/platform/darwin/src/MGLPolyline.mm +++ b/platform/darwin/src/MGLPolyline.mm @@ -1,9 +1,9 @@ -#import "MGLPolyline.h" +#import "MGLPolyline_Private.h" #import "MGLMultiPoint_Private.h" #import "MGLGeometry_Private.h" -#import "MGLPolyline+MGLAdditions.h" +#import "MGLFeature.h" #import #import @@ -49,6 +49,15 @@ @"coordinates": self.mgl_coordinates}; } +- (NS_ARRAY_OF(id) *)mgl_coordinates { + NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:self.pointCount]; + for (NSUInteger index = 0; index < self.pointCount; index++) { + CLLocationCoordinate2D coordinate = self.coordinates[index]; + [coordinates addObject:@[@(coordinate.longitude), @(coordinate.latitude)]]; + } + return [coordinates copy]; +} + - (BOOL)isEqual:(id)other { return self == other || ([other isKindOfClass:[MGLPolyline class]] && [super isEqual:other]); } diff --git a/platform/darwin/src/MGLPolyline_Private.h b/platform/darwin/src/MGLPolyline_Private.h new file mode 100644 index 0000000000..405a0c5bc9 --- /dev/null +++ b/platform/darwin/src/MGLPolyline_Private.h @@ -0,0 +1,12 @@ +#import "MGLPolyline.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface MGLPolyline (Private) + +- (NS_ARRAY_OF(id) *)mgl_coordinates; + +@end + +NS_ASSUME_NONNULL_END + diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm index 71f2785a94..f04ae2b104 100644 --- a/platform/darwin/src/MGLStyle.mm +++ b/platform/darwin/src/MGLStyle.mm @@ -17,7 +17,7 @@ #import "MGLLight_Private.h" #import "MGLTileSource_Private.h" #import "MGLVectorSource.h" -#import "MGLVectorSource+MGLAdditions.h" +#import "MGLVectorSource_Private.h" #import "MGLRasterSource.h" #import "MGLShapeSource.h" #import "MGLImageSource.h" diff --git a/platform/darwin/src/MGLVectorSource+MGLAdditions.h b/platform/darwin/src/MGLVectorSource+MGLAdditions.h deleted file mode 100644 index 43b0aba747..0000000000 --- a/platform/darwin/src/MGLVectorSource+MGLAdditions.h +++ /dev/null @@ -1,15 +0,0 @@ -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface MGLVectorSource (MGLAdditions) - -+ (NSString *)preferredMapboxStreetsLanguage; - -- (NS_DICTIONARY_OF(NSString *, NSString *) *)localizedKeysByKeyForPreferredLanguage:(nullable NSString *)preferredLanguage; - -@property (nonatomic, readonly, getter=isMapboxStreets) BOOL mapboxStreets; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLVectorSource+MGLAdditions.m b/platform/darwin/src/MGLVectorSource+MGLAdditions.m deleted file mode 100644 index a305388117..0000000000 --- a/platform/darwin/src/MGLVectorSource+MGLAdditions.m +++ /dev/null @@ -1,53 +0,0 @@ -#import "MGLVectorSource+MGLAdditions.h" - -@implementation MGLVectorSource (MGLAdditions) - -+ (NS_SET_OF(NSString *) *)mapboxStreetsLanguages { - // https://www.mapbox.com/vector-tiles/mapbox-streets-v7/#overview - static dispatch_once_t onceToken; - static NS_SET_OF(NSString *) *mapboxStreetsLanguages; - dispatch_once(&onceToken, ^{ - // https://www.mapbox.com/vector-tiles/mapbox-streets-v7/#overview - mapboxStreetsLanguages = [NSSet setWithObjects:@"ar", @"de", @"en", @"es", @"fr", @"pt", @"ru", @"zh", @"zh-Hans", nil]; - }); - return mapboxStreetsLanguages; -} - -+ (NSString *)preferredMapboxStreetsLanguage { - NSArray *supportedLanguages = [MGLVectorSource mapboxStreetsLanguages].allObjects; - NSArray *preferredLanguages = [NSBundle preferredLocalizationsFromArray:supportedLanguages - forPreferences:[NSLocale preferredLanguages]]; - NSString *mostSpecificLanguage; - for (NSString *language in preferredLanguages) { - if (language.length > mostSpecificLanguage.length) { - mostSpecificLanguage = language; - } - } - return mostSpecificLanguage ?: @"en"; -} - -- (BOOL)isMapboxStreets { - NSURL *url = self.configurationURL; - if (![url.scheme isEqualToString:@"mapbox"]) { - return NO; - } - NSArray *identifiers = [url.host componentsSeparatedByString:@","]; - return [identifiers containsObject:@"mapbox.mapbox-streets-v7"] || [identifiers containsObject:@"mapbox.mapbox-streets-v6"]; -} - -- (NS_DICTIONARY_OF(NSString *, NSString *) *)localizedKeysByKeyForPreferredLanguage:(nullable NSString *)preferredLanguage { - if (!self.mapboxStreets) { - return @{}; - } - - // Replace {name} and {name_*} with the matching localized name tag. - NSString *localizedKey = preferredLanguage ? [NSString stringWithFormat:@"name_%@", preferredLanguage] : @"name"; - NSMutableDictionary *localizedKeysByKey = [NSMutableDictionary dictionaryWithObject:localizedKey forKey:@"name"]; - for (NSString *languageCode in [MGLVectorSource mapboxStreetsLanguages]) { - NSString *key = [NSString stringWithFormat:@"name_%@", languageCode]; - localizedKeysByKey[key] = localizedKey; - } - return localizedKeysByKey; -} - -@end diff --git a/platform/darwin/src/MGLVectorSource.mm b/platform/darwin/src/MGLVectorSource.mm index b1bda56f2d..90ffe6f98b 100644 --- a/platform/darwin/src/MGLVectorSource.mm +++ b/platform/darwin/src/MGLVectorSource.mm @@ -5,6 +5,7 @@ #import "MGLTileSource_Private.h" #import "MGLStyle_Private.h" #import "MGLMapView_Private.h" + #import "NSPredicate+MGLAdditions.h" #import "NSURL+MGLAdditions.h" @@ -71,3 +72,55 @@ } @end + +@implementation MGLVectorSource (Private) + ++ (NS_SET_OF(NSString *) *)mapboxStreetsLanguages { + // https://www.mapbox.com/vector-tiles/mapbox-streets-v7/#overview + static dispatch_once_t onceToken; + static NS_SET_OF(NSString *) *mapboxStreetsLanguages; + dispatch_once(&onceToken, ^{ + // https://www.mapbox.com/vector-tiles/mapbox-streets-v7/#overview + mapboxStreetsLanguages = [NSSet setWithObjects:@"ar", @"de", @"en", @"es", @"fr", @"pt", @"ru", @"zh", @"zh-Hans", nil]; + }); + return mapboxStreetsLanguages; +} + ++ (NSString *)preferredMapboxStreetsLanguage { + NSArray *supportedLanguages = [MGLVectorSource mapboxStreetsLanguages].allObjects; + NSArray *preferredLanguages = [NSBundle preferredLocalizationsFromArray:supportedLanguages + forPreferences:[NSLocale preferredLanguages]]; + NSString *mostSpecificLanguage; + for (NSString *language in preferredLanguages) { + if (language.length > mostSpecificLanguage.length) { + mostSpecificLanguage = language; + } + } + return mostSpecificLanguage ?: @"en"; +} + +- (BOOL)isMapboxStreets { + NSURL *url = self.configurationURL; + if (![url.scheme isEqualToString:@"mapbox"]) { + return NO; + } + NSArray *identifiers = [url.host componentsSeparatedByString:@","]; + return [identifiers containsObject:@"mapbox.mapbox-streets-v7"] || [identifiers containsObject:@"mapbox.mapbox-streets-v6"]; +} + +- (NS_DICTIONARY_OF(NSString *, NSString *) *)localizedKeysByKeyForPreferredLanguage:(nullable NSString *)preferredLanguage { + if (!self.mapboxStreets) { + return @{}; + } + + // Replace {name} and {name_*} with the matching localized name tag. + NSString *localizedKey = preferredLanguage ? [NSString stringWithFormat:@"name_%@", preferredLanguage] : @"name"; + NSMutableDictionary *localizedKeysByKey = [NSMutableDictionary dictionaryWithObject:localizedKey forKey:@"name"]; + for (NSString *languageCode in [MGLVectorSource mapboxStreetsLanguages]) { + NSString *key = [NSString stringWithFormat:@"name_%@", languageCode]; + localizedKeysByKey[key] = localizedKey; + } + return localizedKeysByKey; +} + +@end diff --git a/platform/darwin/src/MGLVectorSource_Private.h b/platform/darwin/src/MGLVectorSource_Private.h index 335743173e..233809aea2 100644 --- a/platform/darwin/src/MGLVectorSource_Private.h +++ b/platform/darwin/src/MGLVectorSource_Private.h @@ -3,6 +3,13 @@ NS_ASSUME_NONNULL_BEGIN @interface MGLVectorSource (Private) + +@property (nonatomic, readonly, getter=isMapboxStreets) BOOL mapboxStreets; + ++ (NSString *)preferredMapboxStreetsLanguage; + +- (NS_DICTIONARY_OF(NSString *, NSString *) *)localizedKeysByKeyForPreferredLanguage:(nullable NSString *)preferredLanguage; + @end NS_ASSUME_NONNULL_END diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index b2d204c122..a6b3372eb7 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -30,10 +30,6 @@ 1F7454971ECD450D00021D39 /* MGLLight_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F7454941ECD450D00021D39 /* MGLLight_Private.h */; }; 1F7454A91ED08AB400021D39 /* MGLLightTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F7454A61ED08AB400021D39 /* MGLLightTest.mm */; }; 1F95931D1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F95931C1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm */; }; - 1FB7DAAF1F2A4DBD00410606 /* MGLVectorSource+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FDD9D6D1F26936400252B09 /* MGLVectorSource+MGLAdditions.h */; }; - 1FB7DAB01F2A4DC200410606 /* MGLVectorSource+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FDD9D6D1F26936400252B09 /* MGLVectorSource+MGLAdditions.h */; }; - 1FB7DAB11F2A4DC800410606 /* MGLVectorSource+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FDD9D6E1F26936400252B09 /* MGLVectorSource+MGLAdditions.m */; }; - 1FB7DAB21F2A4DC900410606 /* MGLVectorSource+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FDD9D6E1F26936400252B09 /* MGLVectorSource+MGLAdditions.m */; }; 30E578171DAA85520050F07E /* UIImage+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 30E578111DAA7D690050F07E /* UIImage+MGLAdditions.h */; }; 30E578181DAA85520050F07E /* UIImage+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 30E578111DAA7D690050F07E /* UIImage+MGLAdditions.h */; }; 30E578191DAA855E0050F07E /* UIImage+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 30E578121DAA7D690050F07E /* UIImage+MGLAdditions.mm */; }; @@ -223,14 +219,6 @@ 55E2AD131E5B125400E8C587 /* MGLOfflineStorageTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 55E2AD121E5B125400E8C587 /* MGLOfflineStorageTests.mm */; }; 632281DF1E6F855900D75A5D /* MBXEmbeddedMapViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 632281DE1E6F855900D75A5D /* MBXEmbeddedMapViewController.m */; }; 6407D6701E0085FD00F6A9C3 /* MGLDocumentationExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6407D66F1E0085FD00F6A9C3 /* MGLDocumentationExampleTests.swift */; }; - 7E016D7E1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E016D7C1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.h */; }; - 7E016D7F1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E016D7C1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.h */; }; - 7E016D801D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E016D7D1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.m */; }; - 7E016D811D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E016D7D1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.m */; }; - 7E016D841D9E890300A29A21 /* MGLPolygon+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E016D821D9E890300A29A21 /* MGLPolygon+MGLAdditions.h */; }; - 7E016D851D9E890300A29A21 /* MGLPolygon+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E016D821D9E890300A29A21 /* MGLPolygon+MGLAdditions.h */; }; - 7E016D861D9E890300A29A21 /* MGLPolygon+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E016D831D9E890300A29A21 /* MGLPolygon+MGLAdditions.m */; }; - 7E016D871D9E890300A29A21 /* MGLPolygon+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E016D831D9E890300A29A21 /* MGLPolygon+MGLAdditions.m */; }; 920A3E5D1E6F995200C16EFC /* MGLSourceQueryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 920A3E5C1E6F995200C16EFC /* MGLSourceQueryTests.m */; }; 927FBCFC1F4DAA8300F8BF1F /* MBXSnapshotsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 927FBCFB1F4DAA8300F8BF1F /* MBXSnapshotsViewController.m */; }; 927FBCFF1F4DB05500F8BF1F /* MGLMapSnapshotter.h in Headers */ = {isa = PBXBuildFile; fileRef = 927FBCFD1F4DB05500F8BF1F /* MGLMapSnapshotter.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -245,6 +233,8 @@ 9620BB391E69FE1700705A1D /* MGLSDKUpdateChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 9620BB361E69FE1700705A1D /* MGLSDKUpdateChecker.h */; }; 9620BB3A1E69FE1700705A1D /* MGLSDKUpdateChecker.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9620BB371E69FE1700705A1D /* MGLSDKUpdateChecker.mm */; }; 9620BB3B1E69FE1700705A1D /* MGLSDKUpdateChecker.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9620BB371E69FE1700705A1D /* MGLSDKUpdateChecker.mm */; }; + 9654C1261FFC1AB900DB6A19 /* MGLPolyline_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 9654C1251FFC1AB900DB6A19 /* MGLPolyline_Private.h */; }; + 9654C1291FFC1CCD00DB6A19 /* MGLPolygon_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 9654C1271FFC1CC000DB6A19 /* MGLPolygon_Private.h */; }; 966FCF4C1F3A5C9200F2B6DE /* MGLUserLocationHeadingBeamLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 966FCF4A1F3A5C9200F2B6DE /* MGLUserLocationHeadingBeamLayer.h */; }; 966FCF4E1F3A5C9200F2B6DE /* MGLUserLocationHeadingBeamLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 966FCF4B1F3A5C9200F2B6DE /* MGLUserLocationHeadingBeamLayer.m */; }; 966FCF4F1F3A5C9200F2B6DE /* MGLUserLocationHeadingBeamLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 966FCF4B1F3A5C9200F2B6DE /* MGLUserLocationHeadingBeamLayer.m */; }; @@ -600,8 +590,6 @@ 1F7454941ECD450D00021D39 /* MGLLight_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLLight_Private.h; sourceTree = ""; }; 1F7454A61ED08AB400021D39 /* MGLLightTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLLightTest.mm; path = ../../darwin/test/MGLLightTest.mm; sourceTree = ""; }; 1F95931C1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLNSDateAdditionsTests.mm; path = ../../darwin/test/MGLNSDateAdditionsTests.mm; sourceTree = ""; }; - 1FDD9D6D1F26936400252B09 /* MGLVectorSource+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLVectorSource+MGLAdditions.h"; sourceTree = ""; }; - 1FDD9D6E1F26936400252B09 /* MGLVectorSource+MGLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MGLVectorSource+MGLAdditions.m"; sourceTree = ""; }; 20DABE861DF78148007AC5FF /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Foundation.strings"; sourceTree = ""; }; 20DABE881DF78148007AC5FF /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; 20DABE8A1DF78149007AC5FF /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Root.strings"; sourceTree = ""; }; @@ -729,10 +717,6 @@ 632281DD1E6F855900D75A5D /* MBXEmbeddedMapViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBXEmbeddedMapViewController.h; sourceTree = ""; }; 632281DE1E6F855900D75A5D /* MBXEmbeddedMapViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBXEmbeddedMapViewController.m; sourceTree = ""; }; 6407D66F1E0085FD00F6A9C3 /* MGLDocumentationExampleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MGLDocumentationExampleTests.swift; path = ../../darwin/test/MGLDocumentationExampleTests.swift; sourceTree = ""; }; - 7E016D7C1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLPolyline+MGLAdditions.h"; sourceTree = ""; }; - 7E016D7D1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MGLPolyline+MGLAdditions.m"; sourceTree = ""; }; - 7E016D821D9E890300A29A21 /* MGLPolygon+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLPolygon+MGLAdditions.h"; sourceTree = ""; }; - 7E016D831D9E890300A29A21 /* MGLPolygon+MGLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MGLPolygon+MGLAdditions.m"; sourceTree = ""; }; 920A3E5C1E6F995200C16EFC /* MGLSourceQueryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLSourceQueryTests.m; path = ../../darwin/test/MGLSourceQueryTests.m; sourceTree = ""; }; 927FBCFA1F4DAA8300F8BF1F /* MBXSnapshotsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBXSnapshotsViewController.h; sourceTree = ""; }; 927FBCFB1F4DAA8300F8BF1F /* MBXSnapshotsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBXSnapshotsViewController.m; sourceTree = ""; }; @@ -742,6 +726,8 @@ 960D0C351ECF5AAF008E151F /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 9620BB361E69FE1700705A1D /* MGLSDKUpdateChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLSDKUpdateChecker.h; sourceTree = ""; }; 9620BB371E69FE1700705A1D /* MGLSDKUpdateChecker.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = MGLSDKUpdateChecker.mm; sourceTree = ""; }; + 9654C1251FFC1AB900DB6A19 /* MGLPolyline_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLPolyline_Private.h; sourceTree = ""; }; + 9654C1271FFC1CC000DB6A19 /* MGLPolygon_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLPolygon_Private.h; sourceTree = ""; }; 9660916B1E5BBFD700A9A03B /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; 9660916C1E5BBFD900A9A03B /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = ""; }; 9660916D1E5BBFDB00A9A03B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; @@ -1152,8 +1138,6 @@ 35599DB81D46AD7F0048254D /* Categories */ = { isa = PBXGroup; children = ( - 1FDD9D6D1F26936400252B09 /* MGLVectorSource+MGLAdditions.h */, - 1FDD9D6E1F26936400252B09 /* MGLVectorSource+MGLAdditions.m */, 350098DA1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.h */, 350098DB1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.mm */, ); @@ -1629,8 +1613,10 @@ 4049C2AB1DB6E05500B3F799 /* MGLPointCollection_Private.h */, 4049C29C1DB6CD6C00B3F799 /* MGLPointCollection.mm */, DA8847E91CBAFA5100AB86E3 /* MGLPolygon.h */, + 9654C1271FFC1CC000DB6A19 /* MGLPolygon_Private.h */, DA88480C1CBAFA6200AB86E3 /* MGLPolygon.mm */, DA8847EA1CBAFA5100AB86E3 /* MGLPolyline.h */, + 9654C1251FFC1AB900DB6A19 /* MGLPolyline_Private.h */, DA88480D1CBAFA6200AB86E3 /* MGLPolyline.mm */, DA8847EB1CBAFA5100AB86E3 /* MGLShape.h */, 40CF6DBA1DAC3C1800A4D18B /* MGLShape_Private.h */, @@ -1661,10 +1647,6 @@ DAD165831CF4CFED001FF4B9 /* Categories */ = { isa = PBXGroup; children = ( - 7E016D821D9E890300A29A21 /* MGLPolygon+MGLAdditions.h */, - 7E016D831D9E890300A29A21 /* MGLPolygon+MGLAdditions.m */, - 7E016D7C1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.h */, - 7E016D7D1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.m */, 400532FF1DB0862B0069F638 /* NSArray+MGLAdditions.h */, 400533001DB0862B0069F638 /* NSArray+MGLAdditions.mm */, DA8848121CBAFA6200AB86E3 /* NSBundle+MGLAdditions.h */, @@ -1764,15 +1746,14 @@ 35E1A4D81D74336F007AA97F /* MGLValueEvaluator.h in Headers */, DA88482C1CBAFA6200AB86E3 /* NSBundle+MGLAdditions.h in Headers */, 357FE2DD1E02D2B20068B753 /* NSCoder+MGLAdditions.h in Headers */, - 7E016D7E1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.h in Headers */, 35D13AB71D3D15E300AFB4E0 /* MGLStyleLayer.h in Headers */, 07D947531F67488E00E37934 /* MGLAbstractShapeSource_Private.h in Headers */, + 9654C1261FFC1AB900DB6A19 /* MGLPolyline_Private.h in Headers */, DA88488E1CBB047F00AB86E3 /* reachability.h in Headers */, 40F887701D7A1E58008ECB67 /* MGLShapeSource_Private.h in Headers */, 350098DC1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.h in Headers */, DA8848231CBAFA6200AB86E3 /* MGLOfflineStorage_Private.h in Headers */, 404326891D5B9B27007111BD /* MGLAnnotationContainerView_Private.h in Headers */, - 1FB7DAAF1F2A4DBD00410606 /* MGLVectorSource+MGLAdditions.h in Headers */, DA88483B1CBAFB8500AB86E3 /* MGLCalloutView.h in Headers */, 35E0CFE61D3E501500188327 /* MGLStyle_Private.h in Headers */, 3510FFF01D6D9D8C00F413B2 /* NSExpression+MGLAdditions.h in Headers */, @@ -1789,12 +1770,12 @@ DAF0D8131DFE0EC500B28378 /* MGLVectorSource_Private.h in Headers */, 354B83961D2E873E005D9406 /* MGLUserLocationAnnotationView.h in Headers */, DA8847F01CBAFA5100AB86E3 /* MGLAnnotation.h in Headers */, - 7E016D841D9E890300A29A21 /* MGLPolygon+MGLAdditions.h in Headers */, 400533011DB0862B0069F638 /* NSArray+MGLAdditions.h in Headers */, 1F06668A1EC64F8E001C16D7 /* MGLLight.h in Headers */, 4049C29D1DB6CD6C00B3F799 /* MGLPointCollection.h in Headers */, 40CF6DBB1DAC3C6600A4D18B /* MGLShape_Private.h in Headers */, 4018B1CA1CDC288E00F666AF /* MGLAnnotationView.h in Headers */, + 9654C1291FFC1CCD00DB6A19 /* MGLPolygon_Private.h in Headers */, 35E79F201D41266300957B9E /* MGLStyleLayer_Private.h in Headers */, FA68F14A1E9D656600F9F6C2 /* MGLFillExtrusionStyleLayer.h in Headers */, 353933FB1D3FB7C0003F57D7 /* MGLRasterStyleLayer.h in Headers */, @@ -1921,7 +1902,6 @@ 9620BB391E69FE1700705A1D /* MGLSDKUpdateChecker.h in Headers */, 3510FFEB1D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.h in Headers */, 35E1A4D91D74336F007AA97F /* MGLValueEvaluator.h in Headers */, - 7E016D7F1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.h in Headers */, DABFB8701CBE9A0F00D62B32 /* MGLMapView+IBAdditions.h in Headers */, 353AFA151D65AB17005A69F4 /* NSDate+MGLAdditions.h in Headers */, 3510FFFA1D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.h in Headers */, @@ -1955,7 +1935,6 @@ 968F36B51E4D128D003A5522 /* MGLDistanceFormatter.h in Headers */, 4018B1CB1CDC288E00F666AF /* MGLAnnotationView.h in Headers */, DABFB85F1CBE99E500D62B32 /* MGLGeometry.h in Headers */, - 7E016D851D9E890300A29A21 /* MGLPolygon+MGLAdditions.h in Headers */, 353933F61D3FB785003F57D7 /* MGLBackgroundStyleLayer.h in Headers */, DABFB85D1CBE99E500D62B32 /* MGLAccountManager.h in Headers */, 353933F91D3FB79F003F57D7 /* MGLLineStyleLayer.h in Headers */, @@ -1963,7 +1942,6 @@ 35136D4D1D4277FC00C20EFD /* MGLSource.h in Headers */, DA35A2BC1CCA9A6900E826B2 /* MGLClockDirectionFormatter.h in Headers */, 35D13AC41D3D19DD00AFB4E0 /* MGLFillStyleLayer.h in Headers */, - 1FB7DAB01F2A4DC200410606 /* MGLVectorSource+MGLAdditions.h in Headers */, DABFB86E1CBE9A0F00D62B32 /* MGLCalloutView.h in Headers */, 1F7454971ECD450D00021D39 /* MGLLight_Private.h in Headers */, DABFB8601CBE99E500D62B32 /* MGLMapCamera.h in Headers */, @@ -2341,12 +2319,10 @@ files = ( 35136D391D42271A00C20EFD /* MGLBackgroundStyleLayer.mm in Sources */, 3510FFEC1D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.mm in Sources */, - 7E016D801D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.m in Sources */, DAED38651D62D0FC00D7640F /* NSURL+MGLAdditions.m in Sources */, 9620BB3A1E69FE1700705A1D /* MGLSDKUpdateChecker.mm in Sources */, 354B83981D2E873E005D9406 /* MGLUserLocationAnnotationView.m in Sources */, DA88485D1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.m in Sources */, - 1FB7DAB11F2A4DC800410606 /* MGLVectorSource+MGLAdditions.m in Sources */, DAD165701CF41981001FF4B9 /* MGLFeature.mm in Sources */, 30E578191DAA855E0050F07E /* UIImage+MGLAdditions.mm in Sources */, 40EDA1C11CFE0E0500D9EA68 /* MGLAnnotationContainerView.m in Sources */, @@ -2404,7 +2380,6 @@ DA88481D1CBAFA6200AB86E3 /* MGLMapCamera.mm in Sources */, DA8848261CBAFA6200AB86E3 /* MGLPolygon.mm in Sources */, 35B82BFA1D6C5F8400B1B721 /* NSPredicate+MGLAdditions.mm in Sources */, - 7E016D861D9E890300A29A21 /* MGLPolygon+MGLAdditions.m in Sources */, DA8848521CBAFB9800AB86E3 /* MGLAPIClient.m in Sources */, 966FCF4E1F3A5C9200F2B6DE /* MGLUserLocationHeadingBeamLayer.m in Sources */, DA8848301CBAFA6200AB86E3 /* NSProcessInfo+MGLAdditions.m in Sources */, @@ -2432,12 +2407,10 @@ files = ( 35136D3A1D42271A00C20EFD /* MGLBackgroundStyleLayer.mm in Sources */, 3510FFED1D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.mm in Sources */, - 7E016D811D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.m in Sources */, 354B83991D2E873E005D9406 /* MGLUserLocationAnnotationView.m in Sources */, 9620BB3B1E69FE1700705A1D /* MGLSDKUpdateChecker.mm in Sources */, DAA4E4221CBB730400178DFB /* MGLPointAnnotation.mm in Sources */, DAED38661D62D0FC00D7640F /* NSURL+MGLAdditions.m in Sources */, - 1FB7DAB21F2A4DC900410606 /* MGLVectorSource+MGLAdditions.m in Sources */, DAD165711CF41981001FF4B9 /* MGLFeature.mm in Sources */, 30E5781A1DAA855E0050F07E /* UIImage+MGLAdditions.mm in Sources */, 40EDA1C21CFE0E0500D9EA68 /* MGLAnnotationContainerView.m in Sources */, @@ -2494,7 +2467,6 @@ 07D8C6FB1F67560100381808 /* MGLComputedShapeSource.mm in Sources */, DAA4E4341CBB730400178DFB /* MGLFaux3DUserLocationAnnotationView.m in Sources */, 35B82BFB1D6C5F8400B1B721 /* NSPredicate+MGLAdditions.mm in Sources */, - 7E016D871D9E890300A29A21 /* MGLPolygon+MGLAdditions.m in Sources */, DAA4E4311CBB730400178DFB /* MGLMapboxEvents.m in Sources */, 966FCF4F1F3A5C9200F2B6DE /* MGLUserLocationHeadingBeamLayer.m in Sources */, DAA4E4231CBB730400178DFB /* MGLPolygon.mm in Sources */, diff --git a/platform/ios/src/MGLMapAccessibilityElement.mm b/platform/ios/src/MGLMapAccessibilityElement.mm index 4e5f165fbf..1a2953b0bb 100644 --- a/platform/ios/src/MGLMapAccessibilityElement.mm +++ b/platform/ios/src/MGLMapAccessibilityElement.mm @@ -2,10 +2,11 @@ #import "MGLDistanceFormatter.h" #import "MGLCompassDirectionFormatter.h" #import "MGLFeature.h" -#import "MGLVectorSource+MGLAdditions.h" -#import "NSBundle+MGLAdditions.h" #import "MGLGeometry_Private.h" +#import "MGLVectorSource_Private.h" + +#import "NSBundle+MGLAdditions.h" @implementation MGLMapAccessibilityElement diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index c60e56f808..8dec9e520d 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -41,11 +41,11 @@ #import "MGLGeometry_Private.h" #import "MGLMultiPoint_Private.h" #import "MGLOfflineStorage_Private.h" +#import "MGLVectorSource_Private.h" #import "MGLFoundation_Private.h" #import "MGLRendererFrontend.h" #import "MGLRendererConfiguration.h" -#import "MGLVectorSource+MGLAdditions.h" #import "NSBundle+MGLAdditions.h" #import "NSDate+MGLAdditions.h" #import "NSException+MGLAdditions.h" diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m index 8f23a0248a..eb20063996 100644 --- a/platform/macos/app/MapDocument.m +++ b/platform/macos/app/MapDocument.m @@ -6,7 +6,7 @@ #import "MGLMapsnapshotter.h" #import "MGLStyle+MBXAdditions.h" -#import "MGLVectorSource+MGLAdditions.h" +#import "MGLVectorSource_Private.h" #import diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj index bd1fefb43e..ded17d003a 100644 --- a/platform/macos/macos.xcodeproj/project.pbxproj +++ b/platform/macos/macos.xcodeproj/project.pbxproj @@ -22,8 +22,6 @@ 1F7454A51ECFB00300021D39 /* MGLLight.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F7454A21ECFB00300021D39 /* MGLLight.mm */; }; 1F7454AB1ED1DDBD00021D39 /* MGLLightTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F7454AA1ED1DDBD00021D39 /* MGLLightTest.mm */; }; 1F95931B1E6DE2B600D5B294 /* MGLNSDateAdditionsTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F95931A1E6DE2B600D5B294 /* MGLNSDateAdditionsTests.mm */; }; - 1FCDF1421F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FCDF1401F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.h */; }; - 1FCDF1431F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FCDF1411F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.m */; }; 30E5781B1DAA857E0050F07E /* NSImage+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 30E578141DAA7D920050F07E /* NSImage+MGLAdditions.h */; }; 3508EC641D749D39009B0EE4 /* NSExpression+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3508EC621D749D39009B0EE4 /* NSExpression+MGLAdditions.h */; }; 3508EC651D749D39009B0EE4 /* NSExpression+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3508EC631D749D39009B0EE4 /* NSExpression+MGLAdditions.mm */; }; @@ -71,11 +69,7 @@ 4049C2A51DB6CE7F00B3F799 /* MGLPointCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 4049C2A11DB6CE7800B3F799 /* MGLPointCollection.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4049C2AD1DB8020600B3F799 /* MGLPointCollection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4049C2A71DB6D09B00B3F799 /* MGLPointCollection.mm */; }; 408AA85B1DAEECFE00022900 /* MGLShape_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 408AA85A1DAEECF100022900 /* MGLShape_Private.h */; }; - 408AA8651DAEEE3400022900 /* MGLPolygon+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 408AA8601DAEED3300022900 /* MGLPolygon+MGLAdditions.h */; }; - 408AA8661DAEEE3600022900 /* MGLPolyline+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 408AA8611DAEED3300022900 /* MGLPolyline+MGLAdditions.h */; }; 408AA8671DAEEE3900022900 /* NSDictionary+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 408AA85F1DAEED3300022900 /* NSDictionary+MGLAdditions.h */; }; - 408AA8681DAEEE5200022900 /* MGLPolygon+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 408AA85C1DAEED3300022900 /* MGLPolygon+MGLAdditions.m */; }; - 408AA8691DAEEE5500022900 /* MGLPolyline+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 408AA85D1DAEED3300022900 /* MGLPolyline+MGLAdditions.m */; }; 408AA86A1DAEEE5D00022900 /* NSDictionary+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 408AA85E1DAEED3300022900 /* NSDictionary+MGLAdditions.mm */; }; 40ABDB561DB0022100372083 /* NSImage+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 405C03971DB0004E001AC280 /* NSImage+MGLAdditions.mm */; }; 40B77E451DB11BC9003DA2FE /* NSArray+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 40B77E431DB11BB0003DA2FE /* NSArray+MGLAdditions.h */; }; @@ -95,6 +89,8 @@ 92092EF11F5EB10E00AF5130 /* MGLMapSnapshotter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 92092EEF1F5EB10E00AF5130 /* MGLMapSnapshotter.mm */; }; 920A3E591E6F859D00C16EFC /* MGLSourceQueryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 920A3E581E6F859D00C16EFC /* MGLSourceQueryTests.m */; }; 92F2C3EB1F0E3A1900268EC0 /* MGLRendererFrontend.h in Headers */ = {isa = PBXBuildFile; fileRef = 92F2C3EA1F0E3A1900268EC0 /* MGLRendererFrontend.h */; }; + 9654C12B1FFC38E000DB6A19 /* MGLPolyline_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 9654C12A1FFC38E000DB6A19 /* MGLPolyline_Private.h */; }; + 9654C12D1FFC394700DB6A19 /* MGLPolygon_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 9654C12C1FFC394700DB6A19 /* MGLPolygon_Private.h */; }; 96E027311E57C9A7004B8E66 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 96E027331E57C9A7004B8E66 /* Localizable.strings */; }; DA00FC8A1D5EEAC3009AABC8 /* MGLAttributionInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DA00FC881D5EEAC3009AABC8 /* MGLAttributionInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; DA00FC8B1D5EEAC3009AABC8 /* MGLAttributionInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA00FC891D5EEAC3009AABC8 /* MGLAttributionInfo.mm */; }; @@ -303,8 +299,6 @@ 1F7454A21ECFB00300021D39 /* MGLLight.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLLight.mm; sourceTree = ""; }; 1F7454AA1ED1DDBD00021D39 /* MGLLightTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLLightTest.mm; sourceTree = ""; }; 1F95931A1E6DE2B600D5B294 /* MGLNSDateAdditionsTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLNSDateAdditionsTests.mm; path = ../../darwin/test/MGLNSDateAdditionsTests.mm; sourceTree = ""; }; - 1FCDF1401F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLVectorSource+MGLAdditions.h"; sourceTree = ""; }; - 1FCDF1411F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MGLVectorSource+MGLAdditions.m"; sourceTree = ""; }; 30E578141DAA7D920050F07E /* NSImage+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSImage+MGLAdditions.h"; path = "src/NSImage+MGLAdditions.h"; sourceTree = SOURCE_ROOT; }; 3508EC621D749D39009B0EE4 /* NSExpression+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSExpression+MGLAdditions.h"; sourceTree = ""; }; 3508EC631D749D39009B0EE4 /* NSExpression+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSExpression+MGLAdditions.mm"; sourceTree = ""; }; @@ -355,12 +349,8 @@ 405C03961DB0004E001AC280 /* NSImage+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSImage+MGLAdditions.h"; sourceTree = ""; }; 405C03971DB0004E001AC280 /* NSImage+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSImage+MGLAdditions.mm"; sourceTree = ""; }; 408AA85A1DAEECF100022900 /* MGLShape_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLShape_Private.h; sourceTree = ""; }; - 408AA85C1DAEED3300022900 /* MGLPolygon+MGLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MGLPolygon+MGLAdditions.m"; sourceTree = ""; }; - 408AA85D1DAEED3300022900 /* MGLPolyline+MGLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MGLPolyline+MGLAdditions.m"; sourceTree = ""; }; 408AA85E1DAEED3300022900 /* NSDictionary+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSDictionary+MGLAdditions.mm"; sourceTree = ""; }; 408AA85F1DAEED3300022900 /* NSDictionary+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+MGLAdditions.h"; sourceTree = ""; }; - 408AA8601DAEED3300022900 /* MGLPolygon+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLPolygon+MGLAdditions.h"; sourceTree = ""; }; - 408AA8611DAEED3300022900 /* MGLPolyline+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLPolyline+MGLAdditions.h"; sourceTree = ""; }; 40B77E421DB11BB0003DA2FE /* NSArray+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSArray+MGLAdditions.mm"; sourceTree = ""; }; 40B77E431DB11BB0003DA2FE /* NSArray+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+MGLAdditions.h"; sourceTree = ""; }; 40E1601A1DF216E6005EA6D9 /* MGLStyleLayerTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleLayerTests.h; sourceTree = ""; }; @@ -379,6 +369,8 @@ 92092EEF1F5EB10E00AF5130 /* MGLMapSnapshotter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLMapSnapshotter.mm; sourceTree = ""; }; 920A3E581E6F859D00C16EFC /* MGLSourceQueryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLSourceQueryTests.m; sourceTree = ""; }; 92F2C3EA1F0E3A1900268EC0 /* MGLRendererFrontend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLRendererFrontend.h; sourceTree = ""; }; + 9654C12A1FFC38E000DB6A19 /* MGLPolyline_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLPolyline_Private.h; sourceTree = ""; }; + 9654C12C1FFC394700DB6A19 /* MGLPolygon_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLPolygon_Private.h; sourceTree = ""; }; 966091701E5BBFF700A9A03B /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; 966091711E5BBFF900A9A03B /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = ""; }; 966091721E5BBFFA00A9A03B /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/Localizable.strings; sourceTree = ""; }; @@ -686,8 +678,6 @@ 352742791D4C235C00A1ECE6 /* Categories */ = { isa = PBXGroup; children = ( - 1FCDF1401F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.h */, - 1FCDF1411F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.m */, DA8F25A61D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.h */, DA8F25A71D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.mm */, ); @@ -951,8 +941,10 @@ DAF0D80D1DFE0E5D00B28378 /* MGLPointCollection_Private.h */, 4049C2A71DB6D09B00B3F799 /* MGLPointCollection.mm */, DAE6C3541CC31E0400DB3429 /* MGLPolygon.h */, + 9654C12C1FFC394700DB6A19 /* MGLPolygon_Private.h */, DAE6C3771CC31E2A00DB3429 /* MGLPolygon.mm */, DAE6C3551CC31E0400DB3429 /* MGLPolyline.h */, + 9654C12A1FFC38E000DB6A19 /* MGLPolyline_Private.h */, DAE6C3781CC31E2A00DB3429 /* MGLPolyline.mm */, DAE6C3561CC31E0400DB3429 /* MGLShape.h */, 408AA85A1DAEECF100022900 /* MGLShape_Private.h */, @@ -983,10 +975,6 @@ DAD1657F1CF4CF50001FF4B9 /* Categories */ = { isa = PBXGroup; children = ( - 408AA8601DAEED3300022900 /* MGLPolygon+MGLAdditions.h */, - 408AA85C1DAEED3300022900 /* MGLPolygon+MGLAdditions.m */, - 408AA8611DAEED3300022900 /* MGLPolyline+MGLAdditions.h */, - 408AA85D1DAEED3300022900 /* MGLPolyline+MGLAdditions.m */, 40B77E431DB11BB0003DA2FE /* NSArray+MGLAdditions.h */, 40B77E421DB11BB0003DA2FE /* NSArray+MGLAdditions.mm */, DAE6C37D1CC31E2A00DB3429 /* NSBundle+MGLAdditions.h */, @@ -1164,7 +1152,6 @@ DAE6C38D1CC31E2A00DB3429 /* MGLOfflineRegion_Private.h in Headers */, DA7DC9831DED647F0027472F /* MGLRasterSource_Private.h in Headers */, 1753ED401E53CE6100A9FD90 /* MGLConversion.h in Headers */, - 408AA8651DAEEE3400022900 /* MGLPolygon+MGLAdditions.h in Headers */, DA8F259C1D51CB000010E6B5 /* MGLStyleValue_Private.h in Headers */, DAE6C35B1CC31E0400DB3429 /* MGLAnnotation.h in Headers */, DAE6C3B61CC31EF300DB3429 /* MGLMapView_Private.h in Headers */, @@ -1223,12 +1210,10 @@ 1F7454A31ECFB00300021D39 /* MGLLight_Private.h in Headers */, 359819591E02F611008FC139 /* NSCoder+MGLAdditions.h in Headers */, DAE6C38E1CC31E2A00DB3429 /* MGLOfflineStorage_Private.h in Headers */, - 408AA8661DAEEE3600022900 /* MGLPolyline+MGLAdditions.h in Headers */, DA87A9A01DC9DC6200810D09 /* MGLValueEvaluator.h in Headers */, DAE6C3601CC31E0400DB3429 /* MGLOfflineRegion.h in Headers */, DAE6C3681CC31E0400DB3429 /* MGLTilePyramidOfflineRegion.h in Headers */, DA35A2CF1CCAAED300E826B2 /* NSValue+MGLAdditions.h in Headers */, - 1FCDF1421F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.h in Headers */, DAE6C3A61CC31E9400DB3429 /* MGLMapViewDelegate.h in Headers */, DAE6C38B1CC31E2A00DB3429 /* MGLOfflinePack_Private.h in Headers */, 558DE7A61E56161C00C7916D /* MGLFoundation_Private.h in Headers */, @@ -1252,8 +1237,10 @@ DAE6C3A51CC31E9400DB3429 /* MGLMapView+IBAdditions.h in Headers */, DA35A2AD1CCA091800E826B2 /* MGLCompassDirectionFormatter.h in Headers */, 352742851D4C244700A1ECE6 /* MGLRasterSource.h in Headers */, + 9654C12D1FFC394700DB6A19 /* MGLPolygon_Private.h in Headers */, 408AA85B1DAEECFE00022900 /* MGLShape_Private.h in Headers */, DACC22181CF3D4F700D220D9 /* MGLFeature_Private.h in Headers */, + 9654C12B1FFC38E000DB6A19 /* MGLPolyline_Private.h in Headers */, DA6408D71DA4E5DA00908C90 /* MGLVectorStyleLayer.h in Headers */, 352742891D4C245800A1ECE6 /* MGLShapeSource.h in Headers */, 1F7454A41ECFB00300021D39 /* MGLLight.h in Headers */, @@ -1474,7 +1461,6 @@ 40B77E461DB11BCD003DA2FE /* NSArray+MGLAdditions.mm in Sources */, DAE6C38C1CC31E2A00DB3429 /* MGLOfflinePack.mm in Sources */, 35D65C5B1D65AD5500722C23 /* NSDate+MGLAdditions.mm in Sources */, - 1FCDF1431F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.m in Sources */, DD0902B21DB1AC6400C5BDCE /* MGLNetworkConfiguration.m in Sources */, 1F7454A51ECFB00300021D39 /* MGLLight.mm in Sources */, DAE6C3B11CC31EF300DB3429 /* MGLAnnotationImage.m in Sources */, @@ -1518,7 +1504,6 @@ DAE6C38F1CC31E2A00DB3429 /* MGLOfflineStorage.mm in Sources */, DAED38601D62CED700D7640F /* NSURL+MGLAdditions.m in Sources */, 35C5D84A1D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.mm in Sources */, - 408AA8681DAEEE5200022900 /* MGLPolygon+MGLAdditions.m in Sources */, DAE6C3951CC31E2A00DB3429 /* MGLTilePyramidOfflineRegion.mm in Sources */, DAE6C3851CC31E2A00DB3429 /* MGLAccountManager.m in Sources */, DA00FC8B1D5EEAC3009AABC8 /* MGLAttributionInfo.mm in Sources */, @@ -1530,7 +1515,6 @@ 35C5D8481D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.mm in Sources */, DA35A2AE1CCA091800E826B2 /* MGLCompassDirectionFormatter.m in Sources */, DA8F258C1D51CA540010E6B5 /* MGLLineStyleLayer.mm in Sources */, - 408AA8691DAEEE5500022900 /* MGLPolyline+MGLAdditions.m in Sources */, DA8F25941D51CA750010E6B5 /* MGLSymbolStyleLayer.mm in Sources */, 3529039C1D6C63B80002C7DF /* NSPredicate+MGLAdditions.mm in Sources */, DA8F25981D51CAC70010E6B5 /* MGLVectorSource.mm in Sources */, -- cgit v1.2.1 From ed5438fc21672e838947c06669dd44051ce24c81 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Thu, 23 Nov 2017 13:36:15 +0200 Subject: [core] Allow prefetching tiles for all source types --- src/mbgl/renderer/tile_pyramid.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/mbgl/renderer/tile_pyramid.cpp b/src/mbgl/renderer/tile_pyramid.cpp index c1566d12a5..870d9050bc 100644 --- a/src/mbgl/renderer/tile_pyramid.cpp +++ b/src/mbgl/renderer/tile_pyramid.cpp @@ -93,14 +93,11 @@ void TilePyramid::update(const std::vector>& layer if (overscaledZoom >= zoomRange.min) { int32_t idealZoom = std::min(zoomRange.max, overscaledZoom); - // Make sure we're not reparsing overzoomed raster tiles. - if (type == SourceType::Raster) { + // Only attempt prefetching in continuous mode. + if (parameters.mode == MapMode::Continuous) { tileZoom = idealZoom; - // FIXME: Prefetching is only enabled for raster - // tiles until we fix #7026. - - // Request lower zoom level tiles (if configure to do so) in an attempt + // Request lower zoom level tiles (if configured to do so) in an attempt // to show something on the screen faster at the cost of a little of bandwidth. if (parameters.prefetchZoomDelta) { panZoom = std::max(tileZoom - parameters.prefetchZoomDelta, zoomRange.min); -- cgit v1.2.1 From c2809744d24be95d68ff64136d07d4895c9e5eb5 Mon Sep 17 00:00:00 2001 From: Benjamin Jaeger Date: Fri, 15 Dec 2017 17:36:42 -0500 Subject: Support custom LibraryLoader --- .../java/com/mapbox/mapboxsdk/LibraryLoader.java | 34 ++++++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/LibraryLoader.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/LibraryLoader.java index a024f0ab70..6633d5d952 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/LibraryLoader.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/LibraryLoader.java @@ -3,18 +3,46 @@ package com.mapbox.mapboxsdk; import timber.log.Timber; /** - * Centralises the knowledge about "mapbox-gl" library loading. + * Loads the mapbox-gl shared library + *

      + * By default uses the {@link System#loadLibrary(String)}, + * use {@link #setLibraryLoader(LibraryLoader)} to provide an alternative library loading hook. + *

      */ -public class LibraryLoader { +public abstract class LibraryLoader { + + private static final LibraryLoader DEFAULT = new LibraryLoader() { + @Override + public void load(String name) { + System.loadLibrary(name); + } + }; + + private static volatile LibraryLoader loader = DEFAULT; + + /** + * Set the library loader that loads the shared library. + * + * @param libraryLoader the library loader + */ + public static void setLibraryLoader(LibraryLoader libraryLoader) { + loader = libraryLoader; + } /** * Loads "libmapbox-gl.so" native shared library. + *

      + * Catches UnsatisfiedLinkErrors and prints a warning to logcat. + *

      */ public static void load() { try { - System.loadLibrary("mapbox-gl"); + loader.load("mapbox-gl"); } catch (UnsatisfiedLinkError error) { Timber.e(error, "Failed to load native shared library."); } } + + public abstract void load(String name); } + -- cgit v1.2.1 From dadd90e4e9085ab69bb9c95758f9a5224a1da0b3 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Wed, 3 Jan 2018 10:38:16 +0100 Subject: [all] - update licenses to 2018 --- LICENSE.md | 2 +- platform/android/MapboxGLAndroidSDK/gradle-javadoc.gradle | 2 +- platform/ios/app/Info.plist | 2 +- platform/ios/benchmark/Info.plist | 2 +- platform/ios/jazzy.yml | 2 +- platform/ios/uitest/LaunchScreen.xib | 2 +- platform/macos/jazzy.yml | 2 +- test/src/app-info.plist | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index d12e00b0e5..0b77be538e 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -mapbox-gl-native copyright (c) 2014-2017 Mapbox. +mapbox-gl-native copyright (c) 2014-2018 Mapbox. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/platform/android/MapboxGLAndroidSDK/gradle-javadoc.gradle b/platform/android/MapboxGLAndroidSDK/gradle-javadoc.gradle index eeb5e9b4d6..39372b4378 100644 --- a/platform/android/MapboxGLAndroidSDK/gradle-javadoc.gradle +++ b/platform/android/MapboxGLAndroidSDK/gradle-javadoc.gradle @@ -10,7 +10,7 @@ android.libraryVariants.all { variant -> options.windowTitle("Mapbox Android SDK $VERSION_NAME Reference") options.docTitle("Mapbox Android SDK $VERSION_NAME") options.header("Mapbox Android SDK $VERSION_NAME Reference") - options.bottom("© 2015–2017 Mapbox. All rights reserved.") + options.bottom("© 2015–2018 Mapbox. All rights reserved.") options.links("http://docs.oracle.com/javase/7/docs/api/") options.linksOffline("http://d.android.com/reference/", "$System.env.ANDROID_HOME/docs/reference") options.overview("src/main/java/overview.html") diff --git a/platform/ios/app/Info.plist b/platform/ios/app/Info.plist index 0bf66cb8da..ea70ecd629 100644 --- a/platform/ios/app/Info.plist +++ b/platform/ios/app/Info.plist @@ -27,7 +27,7 @@ MGLIdeographicFontFamilyName PingFang TC NSHumanReadableCopyright - © 2014–2017 Mapbox + © 2014–2018 Mapbox NSLocationAlwaysUsageDescription The map will display your location. The map may also use your location when it isn’t visible in order to improve OpenStreetMap and Mapbox products. NSLocationWhenInUseUsageDescription diff --git a/platform/ios/benchmark/Info.plist b/platform/ios/benchmark/Info.plist index 35d3658a1c..b35cb572ab 100644 --- a/platform/ios/benchmark/Info.plist +++ b/platform/ios/benchmark/Info.plist @@ -25,7 +25,7 @@ LSRequiresIPhoneOS NSHumanReadableCopyright - © 2015–2017 Mapbox + © 2015–2018 Mapbox UIApplicationExitsOnSuspend UILaunchStoryboardName diff --git a/platform/ios/jazzy.yml b/platform/ios/jazzy.yml index 955d1079f9..90e357f72e 100644 --- a/platform/ios/jazzy.yml +++ b/platform/ios/jazzy.yml @@ -3,7 +3,7 @@ author: Mapbox author_url: https://www.mapbox.com/ github_url: https://github.com/mapbox/mapbox-gl-native dash_url: https://www.mapbox.com/ios-sdk/docsets/Mapbox.xml -copyright: '© 2014–2017 [Mapbox](https://www.mapbox.com/). See [license](https://github.com/mapbox/mapbox-gl-native/blob/master/LICENSE.md) for more details.' +copyright: '© 2014–2018 [Mapbox](https://www.mapbox.com/). See [license](https://github.com/mapbox/mapbox-gl-native/blob/master/LICENSE.md) for more details.' head: | diff --git a/platform/ios/uitest/LaunchScreen.xib b/platform/ios/uitest/LaunchScreen.xib index c0a15ddb13..dd23975342 100644 --- a/platform/ios/uitest/LaunchScreen.xib +++ b/platform/ios/uitest/LaunchScreen.xib @@ -12,7 +12,7 @@ -