From 6f9b2d533e2bcabd14cace1402a90353fa66865c Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Thu, 12 Jan 2023 09:27:42 +0100 Subject: [PATCH 01/38] Fix projection issues * respect padding when calculating visible region * in `CameraBoundsWithSizeUpdate`, do not redistribute existing padding and do not modify map's padding --- .../maps/mapbox/CameraBoundsWithSizeUpdate.kt | 19 +++++++++++-------- .../org/microg/gms/maps/mapbox/Projection.kt | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/CameraBoundsWithSizeUpdate.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/CameraBoundsWithSizeUpdate.kt index eea4304f5..9eacca012 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/CameraBoundsWithSizeUpdate.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/CameraBoundsWithSizeUpdate.kt @@ -29,14 +29,17 @@ internal class CameraBoundsWithSizeUpdate(val bounds: LatLngBounds, val width: I override fun getCameraPosition(map: MapboxMap): CameraPosition? { val padding = this.padding.clone() - val widthPad = ((map.width + map.padding[0] + map.padding[2] - width) / 2).toInt() - val heightPad = ((map.height + map.padding[1] + map.padding[3] - height) / 2).toInt() - padding[0] += widthPad - padding[1] += heightPad - padding[2] += widthPad - padding[3] += heightPad - Log.d(TAG, "map ${map.width} ${map.height}, set $width $height -> ${padding.map { it.toString() }.reduce { a, b -> "$a,$b"}}") - return map.getCameraForLatLngBounds(bounds, padding) + padding[0] += map.padding[0] + ((map.width - width) / 2).toInt() + padding[1] += map.padding[1] + ((map.height - height) / 2).toInt() + padding[2] += map.padding[2] + ((map.width - width) / 2).toInt() + padding[3] += map.padding[3] + ((map.height - height) / 2).toInt() + Log.d(TAG, "map ${map.width} ${map.height}, set $width $height -> ${Arrays.toString(padding)}") + return map.getCameraForLatLngBounds(bounds, padding)?.let { + CameraPosition.Builder(it).padding( + map.padding[0].toDouble(), map.padding[1].toDouble(), map.padding[2].toDouble(), map.padding[3].toDouble() + ).build() + } + } override fun equals(other: Any?): Boolean { diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Projection.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Projection.kt index ab22186dc..d4ed42f91 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Projection.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Projection.kt @@ -32,7 +32,7 @@ import kotlin.math.roundToInt // TODO: Do calculations using backed up locations instead of live (which requires UI thread) class ProjectionImpl(private val projection: Projection, private val withoutTiltOrBearing: Boolean) : IProjectionDelegate.Stub() { - private val visibleRegion = projection.visibleRegion + private val visibleRegion = projection.getVisibleRegion(false) private val farLeft = projection.toScreenLocation(visibleRegion.farLeft) private val farRight = projection.toScreenLocation(visibleRegion.farRight) private val nearLeft = projection.toScreenLocation(visibleRegion.nearLeft) -- GitLab From 90c175cc48a01d0dd9e2704728c8aa5b199c67ec Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Thu, 12 Jan 2023 09:46:24 +0100 Subject: [PATCH 02/38] Move from deprecated APIs for map padding --- .../maps/mapbox/CameraBoundsWithSizeUpdate.kt | 28 ++++++++++++++----- .../org/microg/gms/maps/mapbox/GoogleMap.kt | 5 +++- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/CameraBoundsWithSizeUpdate.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/CameraBoundsWithSizeUpdate.kt index 9eacca012..c31bf2238 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/CameraBoundsWithSizeUpdate.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/CameraBoundsWithSizeUpdate.kt @@ -29,15 +29,29 @@ internal class CameraBoundsWithSizeUpdate(val bounds: LatLngBounds, val width: I override fun getCameraPosition(map: MapboxMap): CameraPosition? { val padding = this.padding.clone() - padding[0] += map.padding[0] + ((map.width - width) / 2).toInt() - padding[1] += map.padding[1] + ((map.height - height) / 2).toInt() - padding[2] += map.padding[2] + ((map.width - width) / 2).toInt() - padding[3] += map.padding[3] + ((map.height - height) / 2).toInt() + + val mapPadding = map.cameraPosition.padding + mapPadding?.let { + for (i in 0..3) { + padding[i] += it[i].toInt() + } + } + + val widthPadding = ((map.width - width) / 2).toInt() + val heightPadding = ((map.height - height) / 2).toInt() + padding[0] += widthPadding + padding[1] += heightPadding + padding[2] += widthPadding + padding[3] += heightPadding + Log.d(TAG, "map ${map.width} ${map.height}, set $width $height -> ${Arrays.toString(padding)}") return map.getCameraForLatLngBounds(bounds, padding)?.let { - CameraPosition.Builder(it).padding( - map.padding[0].toDouble(), map.padding[1].toDouble(), map.padding[2].toDouble(), map.padding[3].toDouble() - ).build() + CameraPosition.Builder(it) + .apply { + mapPadding?.let { + padding(it) + } + }.build() } } diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index 1ca155ec4..dfb15eac3 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -52,6 +52,7 @@ import com.mapbox.mapboxsdk.plugins.annotation.Annotation import com.mapbox.mapboxsdk.style.layers.Property.LINE_CAP_ROUND import com.google.android.gms.dynamic.unwrap import com.mapbox.mapboxsdk.WellKnownTileServer +import com.mapbox.mapboxsdk.camera.CameraUpdateFactory import org.microg.gms.maps.MapsConstants.* import org.microg.gms.maps.mapbox.model.* import org.microg.gms.maps.mapbox.utils.MapContext @@ -488,7 +489,9 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) { Log.d(TAG, "setPadding: $left $top $right $bottom") map?.let { map -> - map.setPadding(left, top, right, bottom) + CameraUpdateFactory.paddingTo(left.toDouble(), top.toDouble(), right.toDouble(), bottom.toDouble()) + .let { map.moveCamera(it) } + val fourDp = mapView?.context?.resources?.getDimension(R.dimen.mapbox_four_dp)?.toInt() ?: 0 val ninetyTwoDp = mapView?.context?.resources?.getDimension(R.dimen.mapbox_ninety_two_dp)?.toInt() -- GitLab From 9cc36b4688826ac0d64e0a3133376b384afd2e06 Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Thu, 12 Jan 2023 14:20:58 +0100 Subject: [PATCH 03/38] Read mapbox key from environement variable `MAPBOX_VECTOR_TILES_KEY` --- play-services-maps-core-mapbox/build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/play-services-maps-core-mapbox/build.gradle b/play-services-maps-core-mapbox/build.gradle index 56883ed04..a5bbf5ae0 100644 --- a/play-services-maps-core-mapbox/build.gradle +++ b/play-services-maps-core-mapbox/build.gradle @@ -39,6 +39,9 @@ def execResult(...args) { } def mapboxKey() { + String environmentKey = System.getenv('MAPBOX_VECTOR_TILES_KEY') + if (environmentKey != null) return environmentKey + Properties properties = new Properties() try { properties.load(project.rootProject.file('local.properties').newDataInputStream()) -- GitLab From 74bff5ecc7f1a0f767b25a1d92abdc0ded46e98a Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Fri, 13 Jan 2023 13:27:13 +0100 Subject: [PATCH 04/38] Invoke map initialized callback prematurely if needed --- .../org/microg/gms/maps/mapbox/GoogleMap.kt | 117 ++++++++----- .../org/microg/gms/maps/mapbox/UiSettings.kt | 162 +++++++++++++----- 2 files changed, 195 insertions(+), 84 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index 1ca155ec4..a48e5d799 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -18,6 +18,7 @@ package org.microg.gms.maps.mapbox import android.annotation.SuppressLint import android.content.Context +import android.graphics.Point import android.location.Location import android.os.* import androidx.annotation.IdRes @@ -30,6 +31,7 @@ import android.widget.FrameLayout import android.widget.RelativeLayout import androidx.collection.LongSparseArray import com.google.android.gms.dynamic.IObjectWrapper +import com.google.android.gms.dynamic.ObjectWrapper import com.google.android.gms.maps.GoogleMapOptions import com.google.android.gms.maps.internal.* import com.google.android.gms.maps.model.* @@ -52,6 +54,7 @@ import com.mapbox.mapboxsdk.plugins.annotation.Annotation import com.mapbox.mapboxsdk.style.layers.Property.LINE_CAP_ROUND import com.google.android.gms.dynamic.unwrap import com.mapbox.mapboxsdk.WellKnownTileServer +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback import org.microg.gms.maps.MapsConstants.* import org.microg.gms.maps.mapbox.model.* import org.microg.gms.maps.mapbox.utils.MapContext @@ -85,7 +88,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) private var loaded = false private val mapLock = Object() - private val initializedCallbackList = mutableListOf() + private val initializedCallbackList = mutableListOf() private var loadedCallback: IOnMapLoadedCallback? = null private var cameraChangeListener: IOnCameraChangeListener? = null private var cameraMoveListener: IOnCameraMoveListener? = null @@ -167,7 +170,8 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } } - override fun getCameraPosition(): CameraPosition? = map?.cameraPosition?.toGms() + override fun getCameraPosition(): CameraPosition = + map?.cameraPosition?.toGms() ?: CameraPosition(LatLng(0.0, 0.0), 0f, 0f, 0f) override fun getMaxZoomLevel(): Float = (map?.maxZoomLevel?.toFloat() ?: 20f) + 1f override fun getMinZoomLevel(): Float = (map?.minZoomLevel?.toFloat() ?: 0f) + 1f @@ -193,14 +197,17 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } } - fun afterInitialized(runnable: () -> Unit) { - initializedCallbackList.add(object : IOnMapReadyCallback { - override fun onMapReady(map: IGoogleMapDelegate?) { - runnable() + fun afterInitialize(runnable: (MapboxMap) -> Unit) { + synchronized(mapLock) { + if (initialized) { + assert(map != null) + runnable(map!!) + } else { + initializedCallbackList.add(OnMapReadyCallback { + runnable(it) + }) } - - override fun asBinder(): IBinder? = null - }) + } } override fun animateCameraWithCallback(cameraUpdate: IObjectWrapper?, callback: ICancelableCallback?) { @@ -210,7 +217,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) this.map?.animateCamera(update, callback?.toMapbox()) } else { waitingCameraUpdates.add(update) - afterInitialized { callback?.onFinish() } + afterInitialize { callback?.onFinish() } } } } @@ -222,7 +229,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) this.map?.animateCamera(update, duration, callback?.toMapbox()) } else { waitingCameraUpdates.add(update) - afterInitialized { callback?.onFinish() } + afterInitialize { callback?.onFinish() } } } } @@ -234,21 +241,21 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) return true } - override fun setMinZoomPreference(minZoom: Float) { - map?.setMinZoomPreference(minZoom.toDouble() - 1) + override fun setMinZoomPreference(minZoom: Float) = afterInitialize { + it.setMinZoomPreference(minZoom.toDouble() - 1) } - override fun setMaxZoomPreference(maxZoom: Float) { - map?.setMaxZoomPreference(maxZoom.toDouble() - 1) + override fun setMaxZoomPreference(maxZoom: Float) = afterInitialize { + it.setMaxZoomPreference(maxZoom.toDouble() - 1) } - override fun resetMinMaxZoomPreference() { - map?.setMinZoomPreference(MapboxConstants.MINIMUM_ZOOM.toDouble()) - map?.setMaxZoomPreference(MapboxConstants.MAXIMUM_ZOOM.toDouble()) + override fun resetMinMaxZoomPreference() = afterInitialize { + it.setMinZoomPreference(MapboxConstants.MINIMUM_ZOOM.toDouble()) + it.setMaxZoomPreference(MapboxConstants.MAXIMUM_ZOOM.toDouble()) } - override fun setLatLngBoundsForCameraTarget(bounds: LatLngBounds?) { - map?.setLatLngBoundsForCameraTarget(bounds?.toMapbox()) + override fun setLatLngBoundsForCameraTarget(bounds: LatLngBounds?) = afterInitialize { + it.setLatLngBoundsForCameraTarget(bounds?.toMapbox()) } override fun addPolyline(options: PolylineOptions): IPolylineDelegate? { @@ -366,8 +373,8 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } - override fun setWatermarkEnabled(watermark: Boolean) { - map?.uiSettings?.isLogoEnabled = watermark + override fun setWatermarkEnabled(watermark: Boolean) = afterInitialize { + it.uiSettings.isLogoEnabled = watermark } override fun isTrafficEnabled(): Boolean { @@ -424,7 +431,11 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) mapView?.contentDescription = desc } - override fun getUiSettings(): IUiSettingsDelegate? = map?.uiSettings?.let { UiSettingsImpl(it) } + override fun getUiSettings(): IUiSettingsDelegate = + map?.uiSettings?.let { UiSettingsImpl(it) } ?: UiSettingsCache().also { + // Apply cached UI settings after map is initialized + initializedCallbackList.add(it.getMapReadyCallback()) + } override fun getProjection(): IProjectionDelegate? = map?.projection?.let { val experiment = try { @@ -433,6 +444,21 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) Log.w(TAG, e); false } ProjectionImpl(it, experiment) + } ?: object : IProjectionDelegate.Stub() { // dummy projection if map not initialized + override fun fromScreenLocation(obj: IObjectWrapper?): LatLng { + Log.d(TAG, "Map not initialized when calling getProjection(). Cannot calculate fromScreenLocation") + return LatLng(0.0,0.0) + } + + override fun toScreenLocation(latLng: LatLng?): IObjectWrapper { + Log.d(TAG, "Map not initialized when calling getProjection(). Cannot calculate toScreenLocation") + return ObjectWrapper.wrap(Point(0,0)) + } + + override fun getVisibleRegion(): VisibleRegion { + Log.d(TAG, "Map not initialized when calling getProjection(). Cannot calculate getVisibleRegion") + return VisibleRegion(LatLngBounds(LatLng(0.0,0.0), LatLng(0.0,0.0))) + } } override fun setOnCameraChangeListener(listener: IOnCameraChangeListener?) { @@ -485,18 +511,16 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } - override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) { + override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) = afterInitialize { Log.d(TAG, "setPadding: $left $top $right $bottom") - map?.let { map -> - map.setPadding(left, top, right, bottom) - val fourDp = mapView?.context?.resources?.getDimension(R.dimen.mapbox_four_dp)?.toInt() - ?: 0 - val ninetyTwoDp = mapView?.context?.resources?.getDimension(R.dimen.mapbox_ninety_two_dp)?.toInt() - ?: 0 - map.uiSettings.setLogoMargins(left + fourDp, top + fourDp, right + fourDp, bottom + fourDp) - map.uiSettings.setCompassMargins(left + fourDp, top + fourDp, right + fourDp, bottom + fourDp) - map.uiSettings.setAttributionMargins(left + ninetyTwoDp, top + fourDp, right + fourDp, bottom + fourDp) - } + it.setPadding(left, top, right, bottom) + val fourDp = mapView?.context?.resources?.getDimension(R.dimen.mapbox_four_dp)?.toInt() + ?: 0 + val ninetyTwoDp = mapView?.context?.resources?.getDimension(R.dimen.mapbox_ninety_two_dp)?.toInt() + ?: 0 + it.uiSettings.setLogoMargins(left + fourDp, top + fourDp, right + fourDp, bottom + fourDp) + it.uiSettings.setCompassMargins(left + fourDp, top + fourDp, right + fourDp, bottom + fourDp) + it.uiSettings.setAttributionMargins(left + ninetyTwoDp, top + fourDp, right + fourDp, bottom + fourDp) } override fun isBuildingsEnabled(): Boolean { @@ -506,7 +530,6 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) override fun setBuildingsEnabled(buildings: Boolean) { Log.d(TAG, "unimplemented Method: setBuildingsEnabled") - } override fun setOnMapLoadedCallback(callback: IOnMapLoadedCallback?) { @@ -636,11 +659,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) val initializedCallbackList = ArrayList(initializedCallbackList) Log.d(TAG, "Invoking ${initializedCallbackList.size} callbacks delayed, as map is initialized") for (callback in initializedCallbackList) { - try { - callback.onMapReady(this) - } catch (e: Exception) { - Log.w(TAG, e) - } + callback.onMapReady(map) } } @@ -766,8 +785,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) mapView?.onDestroy() mapView = null - // Don't make it null; this object is not deleted immediately, and it may want to access map.* stuff - //map = null + map = null created = false initialized = false @@ -799,16 +817,25 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) fun getMapAsync(callback: IOnMapReadyCallback) { synchronized(mapLock) { - if (initialized) { - Log.d(TAG, "Invoking callback instantly, as map is initialized") + + val runCallback = { try { callback.onMapReady(this) } catch (e: Exception) { Log.w(TAG, e) } + } + + if (initialized) { + Log.d(TAG, "Invoking callback instantly, as map is initialized") + runCallback() + } else if (mapView?.isShown != true) { + // If map is not shown, an app (e.g. Dott) may expect it to initialize anyway – before showing it + Log.d(TAG, "Invoking callback instantly: map cannot be initialized because it is not shown (yet)") + runCallback() } else { Log.d(TAG, "Delay callback invocation, as map is not yet initialized") - initializedCallbackList.add(callback) + initializedCallbackList.add { runCallback() } } } } diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/UiSettings.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/UiSettings.kt index 32320eb44..d3c5b7189 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/UiSettings.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/UiSettings.kt @@ -17,45 +17,22 @@ package org.microg.gms.maps.mapbox import android.os.Parcel -import android.os.RemoteException import android.util.Log import com.google.android.gms.maps.internal.IUiSettingsDelegate +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback import com.mapbox.mapboxsdk.maps.UiSettings -class UiSettingsImpl(private val uiSettings: UiSettings) : IUiSettingsDelegate.Stub() { - +/** + * This class "implements" unimplemented methods to avoid duplication in subclasses + */ +abstract class AbstractUiSettings : IUiSettingsDelegate.Stub() { override fun setZoomControlsEnabled(zoom: Boolean) { Log.d(TAG, "unimplemented Method: setZoomControlsEnabled") } - override fun setCompassEnabled(compass: Boolean) { - uiSettings.isCompassEnabled = compass - } - override fun setMyLocationButtonEnabled(locationButton: Boolean) { Log.d(TAG, "unimplemented Method: setMyLocationButtonEnabled") - - } - - override fun setScrollGesturesEnabled(scrollGestures: Boolean) { - uiSettings.isScrollGesturesEnabled = scrollGestures - } - - override fun setZoomGesturesEnabled(zoomGestures: Boolean) { - uiSettings.isZoomGesturesEnabled = zoomGestures - } - - override fun setTiltGesturesEnabled(tiltGestures: Boolean) { - uiSettings.isTiltGesturesEnabled = tiltGestures - } - - override fun setRotateGesturesEnabled(rotateGestures: Boolean) { - uiSettings.isRotateGesturesEnabled = rotateGestures - } - - override fun setAllGesturesEnabled(gestures: Boolean) { - uiSettings.setAllGesturesEnabled(gestures) } override fun isZoomControlsEnabled(): Boolean { @@ -63,21 +40,11 @@ class UiSettingsImpl(private val uiSettings: UiSettings) : IUiSettingsDelegate.S return false } - override fun isCompassEnabled(): Boolean = uiSettings.isCompassEnabled - override fun isMyLocationButtonEnabled(): Boolean { Log.d(TAG, "unimplemented Method: isMyLocationButtonEnabled") return false } - override fun isScrollGesturesEnabled(): Boolean = uiSettings.isScrollGesturesEnabled - - override fun isZoomGesturesEnabled(): Boolean = uiSettings.isZoomGesturesEnabled - - override fun isTiltGesturesEnabled(): Boolean = uiSettings.isTiltGesturesEnabled - - override fun isRotateGesturesEnabled(): Boolean = uiSettings.isRotateGesturesEnabled - override fun setIndoorLevelPickerEnabled(indoorLevelPicker: Boolean) { Log.d(TAG, "unimplemented Method: setIndoorLevelPickerEnabled") } @@ -105,6 +72,48 @@ class UiSettingsImpl(private val uiSettings: UiSettings) : IUiSettingsDelegate.S return true } + companion object { + private val TAG = "GmsMapsUi" + } +} + +class UiSettingsImpl(private val uiSettings: UiSettings) : AbstractUiSettings() { + + + override fun setCompassEnabled(compass: Boolean) { + uiSettings.isCompassEnabled = compass + } + + override fun setScrollGesturesEnabled(scrollGestures: Boolean) { + uiSettings.isScrollGesturesEnabled = scrollGestures + } + + override fun setZoomGesturesEnabled(zoomGestures: Boolean) { + uiSettings.isZoomGesturesEnabled = zoomGestures + } + + override fun setTiltGesturesEnabled(tiltGestures: Boolean) { + uiSettings.isTiltGesturesEnabled = tiltGestures + } + + override fun setRotateGesturesEnabled(rotateGestures: Boolean) { + uiSettings.isRotateGesturesEnabled = rotateGestures + } + + override fun setAllGesturesEnabled(gestures: Boolean) { + uiSettings.setAllGesturesEnabled(gestures) + } + + override fun isCompassEnabled(): Boolean = uiSettings.isCompassEnabled + + override fun isScrollGesturesEnabled(): Boolean = uiSettings.isScrollGesturesEnabled + + override fun isZoomGesturesEnabled(): Boolean = uiSettings.isZoomGesturesEnabled + + override fun isTiltGesturesEnabled(): Boolean = uiSettings.isTiltGesturesEnabled + + override fun isRotateGesturesEnabled(): Boolean = uiSettings.isRotateGesturesEnabled + override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = if (super.onTransact(code, data, reply, flags)) { true @@ -113,6 +122,81 @@ class UiSettingsImpl(private val uiSettings: UiSettings) : IUiSettingsDelegate.S } companion object { - private val TAG = "GmsMapsUi" + private val TAG = "GmsMapsUiImpl" } } + +class UiSettingsCache : AbstractUiSettings() { + + private var compass: Boolean? = null + private var scrollGestures: Boolean? = null + private var zoomGestures: Boolean? = null + private var tiltGestures: Boolean? = null + private var rotateGestures: Boolean? = null + private var otherGestures: Boolean? = null + + override fun setCompassEnabled(compass: Boolean) { + this.compass = compass + } + + override fun setScrollGesturesEnabled(scrollGestures: Boolean) { + this.scrollGestures = scrollGestures + } + + override fun setZoomGesturesEnabled(zoomGestures: Boolean) { + this.zoomGestures = zoomGestures + } + + override fun setTiltGesturesEnabled(tiltGestures: Boolean) { + this.tiltGestures = tiltGestures + } + + override fun setRotateGesturesEnabled(rotateGestures: Boolean) { + this.rotateGestures = rotateGestures + } + + override fun setAllGesturesEnabled(gestures: Boolean) { + // Simulate MapLibre's UiSettings behavior + isScrollGesturesEnabled = gestures + isRotateGesturesEnabled = gestures + isTiltGesturesEnabled = gestures + isZoomGesturesEnabled = gestures + + //setDoubleTapGesturesEnabled(gestures) + //setQuickZoomGesturesEnabled(gestures) + otherGestures = gestures + } + + override fun isCompassEnabled(): Boolean { + return compass ?: true + } + + override fun isScrollGesturesEnabled(): Boolean { + return scrollGestures ?: true + } + + override fun isZoomGesturesEnabled(): Boolean { + return zoomGestures ?: true + } + + override fun isTiltGesturesEnabled(): Boolean { + return tiltGestures ?: true + } + + override fun isRotateGesturesEnabled(): Boolean { + return rotateGestures ?: true + } + + fun getMapReadyCallback(): OnMapReadyCallback = OnMapReadyCallback { map -> + val uiSettings = map.uiSettings + compass?.let { uiSettings.isCompassEnabled = it } + scrollGestures?.let { uiSettings.isScrollGesturesEnabled = it } + zoomGestures?.let { uiSettings.isZoomGesturesEnabled = it } + tiltGestures?.let { uiSettings.isTiltGesturesEnabled = it } + rotateGestures?.let { uiSettings.isRotateGesturesEnabled = it } + otherGestures?.let { + uiSettings.isDoubleTapGesturesEnabled = it + uiSettings.isQuickZoomGesturesEnabled = it + } + } +} \ No newline at end of file -- GitLab From d4a722571b875016e6752e91f134a6bbcaf08b7f Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Mon, 16 Jan 2023 11:59:41 +0100 Subject: [PATCH 05/38] Fix draggable markers --- .../main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt | 7 ++++++- .../kotlin/org/microg/gms/maps/mapbox/model/Marker.kt | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index 1ca155ec4..deb3626ad 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -684,7 +684,12 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) override fun onAnnotationDrag(annotation: Symbol?) { try { - markers[annotation?.id]?.let { markerDragListener?.onMarkerDrag(it) } + annotation?.let { symbol -> + markers[symbol.id]?.let { marker -> + marker.setPositionWhileDragging(symbol.latLng.toGms()) + markerDragListener?.onMarkerDrag(marker) + } + } } catch (e: Exception) { Log.w(TAG, e) } diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt index 06da36578..2aaf4da31 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt @@ -87,6 +87,14 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options map.symbolManager?.let { update(it) } } + /** + * New position is already reflected on map while if drag is in progress. Calling + * `symbolManager.update` would interrupt the drag. + */ + internal fun setPositionWhileDragging(position: LatLng) { + this.position = position + } + override fun getPosition(): LatLng = position override fun setTitle(title: String?) { -- GitLab From 0008c656213baa6db022a38206fe60ce761fd3ea Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Tue, 17 Jan 2023 10:44:26 +0100 Subject: [PATCH 06/38] Snapshots --- .../kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index 1ca155ec4..bdbfcff59 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -30,6 +30,7 @@ import android.widget.FrameLayout import android.widget.RelativeLayout import androidx.collection.LongSparseArray import com.google.android.gms.dynamic.IObjectWrapper +import com.google.android.gms.dynamic.ObjectWrapper import com.google.android.gms.maps.GoogleMapOptions import com.google.android.gms.maps.internal.* import com.google.android.gms.maps.model.* @@ -481,8 +482,17 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } override fun snapshot(callback: ISnapshotReadyCallback, bitmap: IObjectWrapper?) { - Log.d(TAG, "unimplemented Method: snapshot") - + val map = map + if (map == null) { + // Snapshot cannot be taken + runOnMainLooper { callback.onBitmapWrappedReady(ObjectWrapper.wrap(null)) } + } else { + map.snapshot { + runOnMainLooper { + callback.onBitmapWrappedReady(ObjectWrapper.wrap(it)) + } + } + } } override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) { -- GitLab From 68d2d2c8f3ff32ff802b184a55f3b6fddb50a074 Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Wed, 18 Jan 2023 10:13:33 +0100 Subject: [PATCH 07/38] Approximate circles using a polygon and a line --- play-services-maps-core-mapbox/build.gradle | 2 + .../org/microg/gms/maps/mapbox/GoogleMap.kt | 36 ++-- .../microg/gms/maps/mapbox/model/Circle.kt | 158 ++++++++++++++---- 3 files changed, 146 insertions(+), 50 deletions(-) diff --git a/play-services-maps-core-mapbox/build.gradle b/play-services-maps-core-mapbox/build.gradle index 56883ed04..cd11c1ff1 100644 --- a/play-services-maps-core-mapbox/build.gradle +++ b/play-services-maps-core-mapbox/build.gradle @@ -26,6 +26,8 @@ dependencies { implementation("org.maplibre.gl:android-plugin-annotation-v9:1.0.0") { exclude group: 'com.google.android.gms' } + implementation 'org.maplibre.gl:android-sdk-turf:5.9.0' + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" } diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index 1ca155ec4..7c0638ef9 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -98,17 +98,13 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) private var markerDragListener: IOnMarkerDragListener? = null var lineManager: LineManager? = null - val pendingLines = mutableSetOf() + val pendingLines = mutableSetOf>() var lineId = 0L var fillManager: FillManager? = null - val pendingFills = mutableSetOf() + val pendingFills = mutableSetOf>() var fillId = 0L - var circleManager: CircleManager? = null - val pendingCircles = mutableSetOf() - var circleId = 0L - var symbolManager: SymbolManager? = null val pendingMarkers = mutableSetOf() val markers = mutableMapOf() @@ -302,20 +298,25 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } override fun addCircle(options: CircleOptions): ICircleDelegate? { - val circle = CircleImpl(this, "c${circleId++}", options) + val circle = CircleImpl(this, "c${fillId++}", options) synchronized(this) { - val circleManager = circleManager - if (circleManager == null) { - pendingCircles.add(circle) + val fillManager = fillManager + if (fillManager == null) { + pendingFills.add(circle) + } else { + circle.update(fillManager) + } + val lineManager = lineManager + if (lineManager == null) { + pendingLines.add(circle.line) } else { - circle.update(circleManager) + circle.line.update(lineManager) } } return circle } override fun clear() { - circleManager?.let { clear(it) } lineManager?.let { clear(it) } fillManager?.let { clear(it) } symbolManager?.let { clear(it) } @@ -342,12 +343,10 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } fun applyMapType() { - val circles = circleManager?.annotations?.values() val lines = lineManager?.annotations?.values() val fills = fillManager?.annotations?.values() val symbols = symbolManager?.annotations?.values() val update: (Style) -> Unit = { - circles?.let { runCatching { circleManager?.update(it) } } lines?.let { runCatching { lineManager?.update(it) } } fills?.let { runCatching { fillManager?.update(it) } } symbols?.let { runCatching { symbolManager?.update(it) } } @@ -649,11 +648,9 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) if (loaded) return@let val symbolManager: SymbolManager val lineManager: LineManager - val circleManager: CircleManager val fillManager: FillManager synchronized(mapLock) { - circleManager = CircleManager(view, map, it) fillManager = FillManager(view, map, it) symbolManager = SymbolManager(view, map, it) lineManager = LineManager(view, map, it) @@ -661,7 +658,6 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) this.symbolManager = symbolManager this.lineManager = lineManager - this.circleManager = circleManager this.fillManager = fillManager } symbolManager.iconAllowOverlap = true @@ -691,15 +687,15 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } override fun onAnnotationDragFinished(annotation: Symbol?) { + mapView?.post { try { markers[annotation?.id]?.let { markerDragListener?.onMarkerDragEnd(it) } } catch (e: Exception) { Log.w(TAG, e) } + } } }) - pendingCircles.forEach { it.update(circleManager) } - pendingCircles.clear() pendingFills.forEach { it.update(fillManager) } pendingFills.clear() pendingLines.forEach { it.update(lineManager) } @@ -743,8 +739,6 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) override fun onPause() = mapView?.onPause() ?: Unit override fun onDestroy() { Log.d(TAG, "destroy") - circleManager?.onDestroy() - circleManager = null lineManager?.onDestroy() lineManager = null diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt index aa016ea80..b20e2fe1b 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt @@ -20,76 +20,177 @@ import android.os.Parcel import android.util.Log import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.internal.ICircleDelegate -import com.mapbox.mapboxsdk.plugins.annotation.Circle -import com.mapbox.mapboxsdk.plugins.annotation.CircleOptions +import com.mapbox.geojson.LineString +import com.mapbox.geojson.Point +import com.mapbox.mapboxsdk.plugins.annotation.* import com.mapbox.mapboxsdk.utils.ColorUtils +import com.mapbox.turf.TurfConstants +import com.mapbox.turf.TurfMeasurement +import com.mapbox.turf.TurfMeta +import com.mapbox.turf.TurfTransformation import org.microg.gms.maps.mapbox.GoogleMapImpl -import org.microg.gms.maps.mapbox.utils.toMapbox import com.google.android.gms.maps.model.CircleOptions as GmsCircleOptions -class CircleImpl(private val map: GoogleMapImpl, private val id: String, options: GmsCircleOptions) : ICircleDelegate.Stub(), Markup { +val NORTH_POLE = Point.fromLngLat(0.0, 90.0) +val SOUTH_POLE = Point.fromLngLat(0.0, -90.0) + +/** + * Amount of points to be used in the polygon that approximates the circle. + */ +const val CIRCLE_POLYGON_STEPS = 256 + + +class CircleImpl(private val map: GoogleMapImpl, private val id: String, options: GmsCircleOptions) : ICircleDelegate.Stub(), Markup { private var center: LatLng = options.center - private var radius: Double = options.radius + private var radius: Double = options.radius // in meters private var strokeWidth: Float = options.strokeWidth private var strokeColor: Int = options.strokeColor private var fillColor: Int = options.fillColor private var visible: Boolean = options.isVisible - override var annotation: Circle? = null + internal val line: Markup = object : Markup { + override var annotation: Line? = null + override val annotationOptions: LineOptions + get() = LineOptions() + .withGeometry( + LineString.fromLngLats( + makeOutlineLatLngs() + ) + ).withLineWidth(strokeWidth / map.dpiFactor) + .withLineColor(ColorUtils.colorToRgbaString(strokeColor)) + .withLineOpacity(if (visible) 1f else 0f) + + override val removed: Boolean = false + } + + override var annotation: Fill? = null override var removed: Boolean = false - override val annotationOptions: CircleOptions - get() = CircleOptions() - .withLatLng(center.toMapbox()) - .withCircleColor(ColorUtils.colorToRgbaString(fillColor)) - .withCircleRadius(radius.toFloat()) - .withCircleStrokeColor(ColorUtils.colorToRgbaString(strokeColor)) - .withCircleStrokeWidth(strokeWidth / map.dpiFactor) - .withCircleOpacity(if (visible) 1f else 0f) - .withCircleStrokeOpacity(if (visible) 1f else 0f) + override val annotationOptions: FillOptions + get() = + FillOptions() + .withGeometry(makePolygon()) + .withFillColor(ColorUtils.colorToRgbaString(fillColor)) + .withFillOutlineColor(ColorUtils.colorToRgbaString(strokeColor)) + .withFillOpacity(if (visible && !wrapsAroundPoles()) 1f else 0f) + + private fun makePolygon() = TurfTransformation.circle( + Point.fromLngLat(center.longitude, center.latitude), radius, CIRCLE_POLYGON_STEPS, TurfConstants.UNIT_METERS + ) + + /** + * Google's "map renderer is unable to draw the circle fill if + * the circle encompasses either the North or South pole". + */ + private fun wrapsAroundPoles() = Point.fromLngLat(center.longitude, center.latitude).let { + TurfMeasurement.distance( + it, NORTH_POLE + ) * 1000 < radius || TurfMeasurement.distance( + it, SOUTH_POLE + ) * 1000 < radius + } + + private fun makeOutlineLatLngs() = + TurfMeta.coordAll( + makePolygon(), wrapsAroundPoles() + ).let { + // Circles around the poles are tricky to draw (https://github.com/mapbox/mapbox-gl-js/issues/11235). + // We modify our lines such to match the way Mapbox / MapLibre draws them. + // This results in a small gap somewhere in the line, but avoids an incorrect horizontal line. + + val centerPoint = Point.fromLngLat(center.longitude, center.latitude) + + if (!centerPoint.equals(NORTH_POLE) && TurfMeasurement.distance(centerPoint, NORTH_POLE) * 1000 < radius) { + // Wraps around North Pole + for (i in 0 until it.size) { + // We want to have the north-most points at the start and end + if (it[0].latitude() > it[1].latitude() && it[it.size-1].latitude() > it[it.size-2].latitude()) { + return@let it + } else { + // Cycle point list + val zero = it.removeFirst() + it.add(zero) + } + } + } + + if (!centerPoint.equals(SOUTH_POLE) && TurfMeasurement.distance(centerPoint, SOUTH_POLE) * 1000 < radius) { + // Wraps around South Pole + for (i in 0 until it.size) { + // We want to have the south-most points at the start and end + if (it[0].latitude() < it[1].latitude() && it[it.size-1].latitude() < it[it.size-2].latitude()) { + return@let it + } else { + // Cycle point list + val last = it.removeAt(it.size - 1) + it.add(0, last) + } + } + } + + it + } + + private fun updateLatLngs() { + val polygon = makePolygon() + + // Extracts points from generated polygon in expected format + annotation?.latLngs = FillOptions().withGeometry(polygon).latLngs + + line.annotation?.latLngs = makeOutlineLatLngs().map { point -> + com.mapbox.mapboxsdk.geometry.LatLng( + point.latitude(), + point.longitude() + ) + } + + if (wrapsAroundPoles()) { + annotation?.fillOpacity = 0f + } + } override fun remove() { removed = true - map.circleManager?.let { update(it) } + map.fillManager?.let { update(it) } } override fun getId(): String = id override fun setCenter(center: LatLng) { this.center = center - annotation?.latLng = center.toMapbox() - map.circleManager?.let { update(it) } + updateLatLngs() + map.fillManager?.let { update(it) } } override fun getCenter(): LatLng = center override fun setRadius(radius: Double) { this.radius = radius - annotation?.circleRadius = radius.toFloat() - map.circleManager?.let { update(it) } + updateLatLngs() + map.fillManager?.let { update(it) } } override fun getRadius(): Double = radius override fun setStrokeWidth(width: Float) { this.strokeWidth = width - annotation?.circleStrokeWidth = width / map.dpiFactor - map.circleManager?.let { update(it) } + line.annotation?.lineWidth = width / map.dpiFactor + map.lineManager?.let { line.update(it) } } override fun getStrokeWidth(): Float = strokeWidth override fun setStrokeColor(color: Int) { this.strokeColor = color - annotation?.setCircleStrokeColor(color) - map.circleManager?.let { update(it) } + line.annotation?.setLineColor(color) + map.lineManager?.let { line.update(it) } } override fun getStrokeColor(): Int = strokeColor override fun setFillColor(color: Int) { this.fillColor = color - annotation?.setCircleColor(color) - map.circleManager?.let { update(it) } + annotation?.setFillColor(color) + map.fillManager?.let { update(it) } } override fun getFillColor(): Int = fillColor @@ -105,9 +206,8 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options override fun setVisible(visible: Boolean) { this.visible = visible - annotation?.circleOpacity = if (visible) 1f else 0f - annotation?.circleStrokeOpacity = if (visible) 1f else 0f - map.circleManager?.let { update(it) } + annotation?.fillOpacity = if (visible && !wrapsAroundPoles()) 1f else 0f + map.fillManager?.let { update(it) } } override fun isVisible(): Boolean = visible -- GitLab From 861f830f09ef270d3f3a57a0ce7b2f7dd0b9485d Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Wed, 18 Jan 2023 10:42:11 +0100 Subject: [PATCH 08/38] Clickable circles --- .../gms/maps/internal/IGoogleMapDelegate.aidl | 3 ++- .../maps/internal/IOnCircleClickListener.aidl | 7 ++++++ .../maps/model/internal/ICircleDelegate.aidl | 2 ++ .../android/gms/maps/model/CircleOptions.java | 22 ++++++++++++++++++ .../org/microg/gms/maps/mapbox/GoogleMap.kt | 22 ++++++++++++++++++ .../microg/gms/maps/mapbox/model/Circle.kt | 23 +++++++++++++++++++ .../microg/gms/maps/vtm/GoogleMapImpl.java | 6 +++++ .../gms/maps/vtm/markup/CircleImpl.java | 13 +++++++++++ 8 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnCircleClickListener.aidl diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl index af44f1c50..556c2872c 100644 --- a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl @@ -13,6 +13,7 @@ import com.google.android.gms.maps.internal.IOnCameraIdleListener; import com.google.android.gms.maps.internal.IOnCameraMoveCanceledListener; import com.google.android.gms.maps.internal.IOnCameraMoveListener; import com.google.android.gms.maps.internal.IOnCameraMoveStartedListener; +import com.google.android.gms.maps.internal.IOnCircleClickListener; import com.google.android.gms.maps.internal.IOnMapClickListener; import com.google.android.gms.maps.internal.IOnMapLongClickListener; import com.google.android.gms.maps.internal.IOnMarkerClickListener; @@ -124,7 +125,7 @@ interface IGoogleMapDelegate { //void setPolygonClickListener(IOnPolygonClickListener listener) = 84; //void setInfoWindowCloseListener(IOnInfoWindowCloseListener listener) = 85; //void setPolylineClickListener(IOnPolylineClickListener listener) = 86; - //void setCircleClickListener(IOnCircleClickListener listener) = 88; + void setCircleClickListener(IOnCircleClickListener listener) = 88; boolean setMapStyle(in MapStyleOptions options) = 90; void setMinZoomPreference(float minZoom) = 91; diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnCircleClickListener.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnCircleClickListener.aidl new file mode 100644 index 000000000..cd7ad60e6 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnCircleClickListener.aidl @@ -0,0 +1,7 @@ +package com.google.android.gms.maps.internal; + +import com.google.android.gms.maps.model.internal.ICircleDelegate; + +interface IOnCircleClickListener { + void onCircleClick(ICircleDelegate circle); +} diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl index 719d8eab6..7582804c5 100644 --- a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl @@ -21,4 +21,6 @@ interface ICircleDelegate { boolean isVisible(); boolean equalsRemote(ICircleDelegate other); int hashCodeRemote(); + void setClickable(boolean clickable); + boolean isClickable(); } diff --git a/play-services-api/src/main/java/com/google/android/gms/maps/model/CircleOptions.java b/play-services-api/src/main/java/com/google/android/gms/maps/model/CircleOptions.java index 9f6110602..cb14f525d 100644 --- a/play-services-api/src/main/java/com/google/android/gms/maps/model/CircleOptions.java +++ b/play-services-api/src/main/java/com/google/android/gms/maps/model/CircleOptions.java @@ -43,6 +43,8 @@ public class CircleOptions extends AutoSafeParcelable { private float zIndex = 0; @SafeParceled(8) private boolean visible = true; + @SafeParceled(9) + private boolean clickable = false; /** * Creates circle options. @@ -144,6 +146,15 @@ public class CircleOptions extends AutoSafeParcelable { return visible; } + /** + * Gets the clickability setting for the circle. + * + * @return {@code true} if the circle is clickable; {@code false} if it is not. + */ + public boolean isClickable() { + return clickable; + } + /** * Sets the radius in meters. *

@@ -217,5 +228,16 @@ public class CircleOptions extends AutoSafeParcelable { return this; } + /** + * Specifies whether this circle is clickable. The default setting is {@code false}. + * + * @param clickable + * @return this {@code CircleOptions} object with a new clickability setting. + */ + public CircleOptions clickable(boolean clickable) { + this.clickable = clickable; + return this; + } + public static Creator CREATOR = new AutoCreator(CircleOptions.class); } diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index 7c0638ef9..e1cca36d1 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -96,6 +96,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) private var mapLongClickListener: IOnMapLongClickListener? = null private var markerClickListener: IOnMarkerClickListener? = null private var markerDragListener: IOnMarkerDragListener? = null + private var circleClickListener: IOnCircleClickListener? = null var lineManager: LineManager? = null val pendingLines = mutableSetOf>() @@ -103,6 +104,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) var fillManager: FillManager? = null val pendingFills = mutableSetOf>() + val circles = mutableMapOf() var fillId = 0L var symbolManager: SymbolManager? = null @@ -454,6 +456,10 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) markerDragListener = listener } + override fun setCircleClickListener(listener: IOnCircleClickListener?) { + circleClickListener = listener + } + override fun setOnInfoWindowClickListener(listener: IOnInfoWindowClickListener?) { Log.d(TAG, "unimplemented Method: setOnInfoWindowClickListener") @@ -696,6 +702,21 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } } }) + fillManager.addClickListener { fill -> + try { + circles[fill.id]?.let { circle -> + if (circle.isClickable) { + circleClickListener?.let { + it.onCircleClick(circle) + return@addClickListener true + } + } + } + } catch (e: Exception) { + Log.w(TAG, e) + } + false + } pendingFills.forEach { it.update(fillManager) } pendingFills.clear() pendingLines.forEach { it.update(lineManager) } @@ -745,6 +766,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) fillManager?.onDestroy() fillManager = null + circles.clear() symbolManager?.onDestroy() symbolManager = null diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt index b20e2fe1b..c904c777f 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt @@ -47,6 +47,7 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options private var strokeColor: Int = options.strokeColor private var fillColor: Int = options.fillColor private var visible: Boolean = options.isVisible + private var clickable: Boolean = options.isClickable internal val line: Markup = object : Markup { override var annotation: Line? = null @@ -216,6 +217,28 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options override fun hashCodeRemote(): Int = hashCode() + override fun setClickable(clickable: Boolean) { + this.clickable = clickable + } + + override fun isClickable(): Boolean { + return clickable + } + + override fun update(manager: AnnotationManager<*, Fill, FillOptions, *, *, *>) { + synchronized(this) { + val id = annotation?.id + if (removed && id != null) { + map.circles.remove(id) + } + super.update(manager) + val annotation = annotation + if (annotation != null && id == null) { + map.circles[annotation.id] = this + } + } + } + override fun hashCode(): Int { return id.hashCode() } diff --git a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/GoogleMapImpl.java b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/GoogleMapImpl.java index 87a512091..5a8bebbfd 100644 --- a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/GoogleMapImpl.java +++ b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/GoogleMapImpl.java @@ -44,6 +44,7 @@ import com.google.android.gms.maps.internal.IOnCameraIdleListener; import com.google.android.gms.maps.internal.IOnCameraMoveCanceledListener; import com.google.android.gms.maps.internal.IOnCameraMoveListener; import com.google.android.gms.maps.internal.IOnCameraMoveStartedListener; +import com.google.android.gms.maps.internal.IOnCircleClickListener; import com.google.android.gms.maps.internal.IOnInfoWindowClickListener; import com.google.android.gms.maps.internal.IOnMapClickListener; import com.google.android.gms.maps.internal.IOnMapLoadedCallback; @@ -212,6 +213,11 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub } + @Override + public void setCircleClickListener(IOnCircleClickListener listener) throws RemoteException { + Log.d(TAG, "unimplemented Method: setCircleClickListener"); + } + @Override public boolean setMapStyle(MapStyleOptions options) throws RemoteException { Log.d(TAG, "unimplemented Method: setMapStyle"); diff --git a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java index 18b4a9994..04c12d3cf 100644 --- a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java +++ b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java @@ -18,6 +18,7 @@ package org.microg.gms.maps.vtm.markup; import android.os.RemoteException; +import android.util.Log; import com.google.android.gms.maps.model.CircleOptions; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.internal.ICircleDelegate; @@ -30,6 +31,8 @@ import org.oscim.map.Map; public class CircleImpl extends ICircleDelegate.Stub implements DrawableMarkup { + private static final String TAG = "GmsMapCircle"; + private final String id; private final CircleOptions options; private final MarkupListener listener; @@ -139,6 +142,16 @@ public class CircleImpl extends ICircleDelegate.Stub implements DrawableMarkup { return id.hashCode(); } + @Override + public void setClickable(boolean clickable) throws RemoteException { + Log.d(TAG, "unimplemented method: setClickable"); + } + + @Override + public boolean isClickable() throws RemoteException { + return false; + } + @Override public boolean onClick() { return listener.onClick(this); -- GitLab From c70e589cf98e688ec66e7f1cf8306e040147edf7 Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Wed, 18 Jan 2023 11:01:18 +0100 Subject: [PATCH 09/38] Implement circle tag --- .../maps/model/internal/ICircleDelegate.aidl | 5 +++++ .../microg/gms/maps/mapbox/model/Circle.kt | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl index 7582804c5..8f2277e9e 100644 --- a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl @@ -1,5 +1,6 @@ package com.google.android.gms.maps.model.internal; +import com.google.android.gms.dynamic.IObjectWrapper; import com.google.android.gms.maps.model.LatLng; interface ICircleDelegate { @@ -23,4 +24,8 @@ interface ICircleDelegate { int hashCodeRemote(); void setClickable(boolean clickable); boolean isClickable(); + void setStrokePattern(IObjectWrapper object); + IObjectWrapper getStrokePattern(); + void setTag(IObjectWrapper object); + IObjectWrapper getTag(); } diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt index c904c777f..6908c6525 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt @@ -18,6 +18,9 @@ package org.microg.gms.maps.mapbox.model import android.os.Parcel import android.util.Log +import com.google.android.gms.dynamic.IObjectWrapper +import com.google.android.gms.dynamic.ObjectWrapper +import com.google.android.gms.dynamic.unwrap import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.internal.ICircleDelegate import com.mapbox.geojson.LineString @@ -48,6 +51,7 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options private var fillColor: Int = options.fillColor private var visible: Boolean = options.isVisible private var clickable: Boolean = options.isClickable + private var tag: Any? = null internal val line: Markup = object : Markup { override var annotation: Line? = null @@ -239,6 +243,21 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options } } + override fun setStrokePattern(pattern: IObjectWrapper) { + Log.d(TAG, "unimplemented method: set stroke pattern") + } + + override fun getStrokePattern(): IObjectWrapper { + Log.d(TAG, "unimplemented method: getStrokePattern") + return ObjectWrapper.wrap(null) + } + + override fun setTag(o: IObjectWrapper) { + this.tag = o.unwrap() + } + + override fun getTag(): IObjectWrapper = ObjectWrapper.wrap(tag) + override fun hashCode(): Int { return id.hashCode() } -- GitLab From a278b3d2f9f93203d6fbeb3b5bda0837f76196d1 Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Wed, 18 Jan 2023 11:21:35 +0100 Subject: [PATCH 10/38] Fill in missing methods in vtm implementation --- .../gms/maps/vtm/markup/CircleImpl.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java index 04c12d3cf..9fe9a05ff 100644 --- a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java +++ b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java @@ -19,6 +19,8 @@ package org.microg.gms.maps.vtm.markup; import android.os.RemoteException; import android.util.Log; +import com.google.android.gms.dynamic.IObjectWrapper; +import com.google.android.gms.dynamic.ObjectWrapper; import com.google.android.gms.maps.model.CircleOptions; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.internal.ICircleDelegate; @@ -152,6 +154,28 @@ public class CircleImpl extends ICircleDelegate.Stub implements DrawableMarkup { return false; } + @Override + public void setStrokePattern(IObjectWrapper object) throws RemoteException { + Log.d(TAG, "unimplemented method: setStrokePattern"); + } + + @Override + public IObjectWrapper getStrokePattern() throws RemoteException { + Log.d(TAG, "unimplemented method: getStrokePattern"); + return ObjectWrapper.wrap(null); + } + + @Override + public void setTag(IObjectWrapper object) throws RemoteException { + Log.d(TAG, "unimplemented method: setTag"); + } + + @Override + public IObjectWrapper getTag() throws RemoteException { + Log.d(TAG, "unimplemented method: getTag"); + return ObjectWrapper.wrap(null); + } + @Override public boolean onClick() { return listener.onClick(this); -- GitLab From 074fb3607d6f15084ac8589d06ae45e67d697bcc Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Wed, 18 Jan 2023 18:34:48 +0100 Subject: [PATCH 11/38] Apply review --- .../main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt | 8 ++++---- .../main/kotlin/org/microg/gms/maps/mapbox/UiSettings.kt | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index a48e5d799..c35e60ab3 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -172,6 +172,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) override fun getCameraPosition(): CameraPosition = map?.cameraPosition?.toGms() ?: CameraPosition(LatLng(0.0, 0.0), 0f, 0f, 0f) + override fun getMaxZoomLevel(): Float = (map?.maxZoomLevel?.toFloat() ?: 20f) + 1f override fun getMinZoomLevel(): Float = (map?.minZoomLevel?.toFloat() ?: 0f) + 1f @@ -200,7 +201,6 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) fun afterInitialize(runnable: (MapboxMap) -> Unit) { synchronized(mapLock) { if (initialized) { - assert(map != null) runnable(map!!) } else { initializedCallbackList.add(OnMapReadyCallback { @@ -447,17 +447,17 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } ?: object : IProjectionDelegate.Stub() { // dummy projection if map not initialized override fun fromScreenLocation(obj: IObjectWrapper?): LatLng { Log.d(TAG, "Map not initialized when calling getProjection(). Cannot calculate fromScreenLocation") - return LatLng(0.0,0.0) + return LatLng(0.0, 0.0) } override fun toScreenLocation(latLng: LatLng?): IObjectWrapper { Log.d(TAG, "Map not initialized when calling getProjection(). Cannot calculate toScreenLocation") - return ObjectWrapper.wrap(Point(0,0)) + return ObjectWrapper.wrap(Point(0, 0)) } override fun getVisibleRegion(): VisibleRegion { Log.d(TAG, "Map not initialized when calling getProjection(). Cannot calculate getVisibleRegion") - return VisibleRegion(LatLngBounds(LatLng(0.0,0.0), LatLng(0.0,0.0))) + return VisibleRegion(LatLngBounds(LatLng(0.0, 0.0), LatLng(0.0, 0.0))) } } diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/UiSettings.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/UiSettings.kt index d3c5b7189..e6ab10cf5 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/UiSettings.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/UiSettings.kt @@ -162,8 +162,7 @@ class UiSettingsCache : AbstractUiSettings() { isTiltGesturesEnabled = gestures isZoomGesturesEnabled = gestures - //setDoubleTapGesturesEnabled(gestures) - //setQuickZoomGesturesEnabled(gestures) + // Other gestures toggles double tap and quick zoom gestures otherGestures = gestures } -- GitLab From 2e624ae90c49f852448ae16c3e6840bf96525098 Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Wed, 18 Jan 2023 18:57:02 +0100 Subject: [PATCH 12/38] Apply review --- .../microg/gms/maps/mapbox/model/Circle.kt | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt index 6908c6525..38cd1f3b9 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt @@ -34,15 +34,14 @@ import com.mapbox.turf.TurfTransformation import org.microg.gms.maps.mapbox.GoogleMapImpl import com.google.android.gms.maps.model.CircleOptions as GmsCircleOptions -val NORTH_POLE = Point.fromLngLat(0.0, 90.0) -val SOUTH_POLE = Point.fromLngLat(0.0, -90.0) +val NORTH_POLE: Point = Point.fromLngLat(0.0, 90.0) +val SOUTH_POLE: Point = Point.fromLngLat(0.0, -90.0) /** * Amount of points to be used in the polygon that approximates the circle. */ const val CIRCLE_POLYGON_STEPS = 256 - class CircleImpl(private val map: GoogleMapImpl, private val id: String, options: GmsCircleOptions) : ICircleDelegate.Stub(), Markup { private var center: LatLng = options.center private var radius: Double = options.radius // in meters @@ -94,47 +93,48 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options ) * 1000 < radius } - private fun makeOutlineLatLngs() = - TurfMeta.coordAll( + private fun makeOutlineLatLngs(): MutableList { + val pointList = TurfMeta.coordAll( makePolygon(), wrapsAroundPoles() - ).let { - // Circles around the poles are tricky to draw (https://github.com/mapbox/mapbox-gl-js/issues/11235). - // We modify our lines such to match the way Mapbox / MapLibre draws them. - // This results in a small gap somewhere in the line, but avoids an incorrect horizontal line. - - val centerPoint = Point.fromLngLat(center.longitude, center.latitude) - - if (!centerPoint.equals(NORTH_POLE) && TurfMeasurement.distance(centerPoint, NORTH_POLE) * 1000 < radius) { - // Wraps around North Pole - for (i in 0 until it.size) { - // We want to have the north-most points at the start and end - if (it[0].latitude() > it[1].latitude() && it[it.size-1].latitude() > it[it.size-2].latitude()) { - return@let it - } else { - // Cycle point list - val zero = it.removeFirst() - it.add(zero) - } + ) + // Circles around the poles are tricky to draw (https://github.com/mapbox/mapbox-gl-js/issues/11235). + // We modify our lines such to match the way Mapbox / MapLibre draws them. + // This results in a small gap somewhere in the line, but avoids an incorrect horizontal line. + + val centerPoint = Point.fromLngLat(center.longitude, center.latitude) + + if (!centerPoint.equals(NORTH_POLE) && TurfMeasurement.distance(centerPoint, NORTH_POLE) * 1000 < radius) { + // Wraps around North Pole + for (i in 0 until pointList.size) { + // We want to have the north-most points at the start and end + if (pointList[0].latitude() > pointList[1].latitude() && pointList[pointList.size - 1].latitude() > pointList[pointList.size - 2].latitude()) { + return pointList + } else { + // Cycle point list + val zero = pointList.removeFirst() + pointList.add(zero) } } + } - if (!centerPoint.equals(SOUTH_POLE) && TurfMeasurement.distance(centerPoint, SOUTH_POLE) * 1000 < radius) { - // Wraps around South Pole - for (i in 0 until it.size) { - // We want to have the south-most points at the start and end - if (it[0].latitude() < it[1].latitude() && it[it.size-1].latitude() < it[it.size-2].latitude()) { - return@let it - } else { - // Cycle point list - val last = it.removeAt(it.size - 1) - it.add(0, last) - } + if (!centerPoint.equals(SOUTH_POLE) && TurfMeasurement.distance(centerPoint, SOUTH_POLE) * 1000 < radius) { + // Wraps around South Pole + for (i in 0 until pointList.size) { + // We want to have the south-most points at the start and end + if (pointList[0].latitude() < pointList[1].latitude() && pointList[pointList.size - 1].latitude() < pointList[pointList.size - 2].latitude()) { + return pointList + } else { + // Cycle point list + val last = pointList.removeAt(pointList.size - 1) + pointList.add(0, last) } } - - it } + // In this case no changes were made + return pointList + } + private fun updateLatLngs() { val polygon = makePolygon() -- GitLab From e8834f2c3ee7648ef1c511becba8cdda6b57386e Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Mon, 23 Jan 2023 08:40:58 +0000 Subject: [PATCH 13/38] Info window implementation --- .../gms/maps/internal/IGoogleMapDelegate.aidl | 6 +- .../internal/IOnInfoWindowCloseListener.aidl | 7 + .../IOnInfoWindowLongClickListener.aidl | 7 + .../org/microg/gms/maps/mapbox/GoogleMap.kt | 50 +++++- .../gms/maps/mapbox/model/BitmapDescriptor.kt | 2 +- .../gms/maps/mapbox/model/InfoWindow.kt | 156 ++++++++++++++++++ .../microg/gms/maps/mapbox/model/Marker.kt | 38 ++++- .../main/res/drawable/maps_default_bubble.xml | 33 ++++ .../res/layout/maps_default_bubble_layout.xml | 34 ++++ .../microg/gms/maps/vtm/GoogleMapImpl.java | 12 ++ 10 files changed, 329 insertions(+), 16 deletions(-) create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnInfoWindowCloseListener.aidl create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnInfoWindowLongClickListener.aidl create mode 100644 play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt create mode 100644 play-services-maps-core-mapbox/src/main/res/drawable/maps_default_bubble.xml create mode 100644 play-services-maps-core-mapbox/src/main/res/layout/maps_default_bubble_layout.xml diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl index af44f1c50..fe592337f 100644 --- a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl @@ -18,6 +18,8 @@ import com.google.android.gms.maps.internal.IOnMapLongClickListener; import com.google.android.gms.maps.internal.IOnMarkerClickListener; import com.google.android.gms.maps.internal.IOnMarkerDragListener; import com.google.android.gms.maps.internal.IOnInfoWindowClickListener; +import com.google.android.gms.maps.internal.IOnInfoWindowCloseListener; +import com.google.android.gms.maps.internal.IOnInfoWindowLongClickListener; import com.google.android.gms.maps.internal.IInfoWindowAdapter; import com.google.android.gms.maps.internal.IOnMapLoadedCallback; import com.google.android.gms.maps.internal.IOnMyLocationChangeListener; @@ -120,9 +122,9 @@ interface IGoogleMapDelegate { void onExitAmbient() = 81; //void setOnGroundOverlayClickListener(IOnGroundOverlayClickListener listener) = 82; - //void setInfoWindowLongClickListener(IOnInfoWindowLongClickListener listener) = 83; + void setInfoWindowLongClickListener(IOnInfoWindowLongClickListener listener) = 83; //void setPolygonClickListener(IOnPolygonClickListener listener) = 84; - //void setInfoWindowCloseListener(IOnInfoWindowCloseListener listener) = 85; + void setInfoWindowCloseListener(IOnInfoWindowCloseListener listener) = 85; //void setPolylineClickListener(IOnPolylineClickListener listener) = 86; //void setCircleClickListener(IOnCircleClickListener listener) = 88; diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnInfoWindowCloseListener.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnInfoWindowCloseListener.aidl new file mode 100644 index 000000000..1ddae39c1 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnInfoWindowCloseListener.aidl @@ -0,0 +1,7 @@ +package com.google.android.gms.maps.internal; + +import com.google.android.gms.maps.model.internal.IMarkerDelegate; + +interface IOnInfoWindowCloseListener { + void onInfoWindowClose(IMarkerDelegate marker); +} diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnInfoWindowLongClickListener.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnInfoWindowLongClickListener.aidl new file mode 100644 index 000000000..536e55e99 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnInfoWindowLongClickListener.aidl @@ -0,0 +1,7 @@ +package com.google.android.gms.maps.internal; + +import com.google.android.gms.maps.model.internal.IMarkerDelegate; + +interface IOnInfoWindowLongClickListener { + void onInfoWindowLongClick(IMarkerDelegate marker); +} diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index 2359aefe1..87d5bdfa0 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -54,6 +54,9 @@ import com.mapbox.mapboxsdk.plugins.annotation.Annotation import com.mapbox.mapboxsdk.style.layers.Property.LINE_CAP_ROUND import com.google.android.gms.dynamic.unwrap import com.mapbox.mapboxsdk.WellKnownTileServer +import org.microg.gms.maps.mapbox.model.DefaultInfoWindowAdapter +import org.microg.gms.maps.mapbox.model.InfoWindow +import org.microg.gms.maps.mapbox.model.getInfoWindowViewFor import com.mapbox.mapboxsdk.camera.CameraUpdateFactory import com.mapbox.mapboxsdk.maps.OnMapReadyCallback import org.microg.gms.maps.MapsConstants.* @@ -100,6 +103,12 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) private var mapLongClickListener: IOnMapLongClickListener? = null private var markerClickListener: IOnMarkerClickListener? = null private var markerDragListener: IOnMarkerDragListener? = null + private var infoWindowAdapter: IInfoWindowAdapter = DefaultInfoWindowAdapter(MapContext(context)) + internal var onInfoWindowClickListener: IOnInfoWindowClickListener? = null + internal var onInfoWindowLongClickListener: IOnInfoWindowLongClickListener? = null + internal var onInfoWindowCloseListener: IOnInfoWindowCloseListener? = null + + var currentInfoWindow: InfoWindow? = null var lineManager: LineManager? = null val pendingLines = mutableSetOf() @@ -483,13 +492,19 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } override fun setOnInfoWindowClickListener(listener: IOnInfoWindowClickListener?) { - Log.d(TAG, "unimplemented Method: setOnInfoWindowClickListener") + onInfoWindowClickListener = listener + } + override fun setInfoWindowLongClickListener(listener: IOnInfoWindowLongClickListener) { + onInfoWindowLongClickListener = listener } - override fun setInfoWindowAdapter(adapter: IInfoWindowAdapter?) { - Log.d(TAG, "unimplemented Method: setInfoWindowAdapter") + override fun setInfoWindowCloseListener(listener: IOnInfoWindowCloseListener) { + onInfoWindowCloseListener = listener + } + override fun setInfoWindowAdapter(adapter: IInfoWindowAdapter?) { + infoWindowAdapter = adapter ?: DefaultInfoWindowAdapter(MapContext(context)) } override fun getTestingHelper(): IObjectWrapper? { @@ -611,6 +626,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) map.addOnCameraMoveListener { try { cameraMoveListener?.onCameraMove() + currentInfoWindow?.update() } catch (e: Exception) { Log.w(TAG, e) } @@ -631,7 +647,11 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } map.addOnMapClickListener { latlng -> try { - mapClickListener?.let { if (!hasSymbolAt(latlng)) it.onMapClick(latlng.toGms()); } + if (!hasSymbolAt(latlng)) { + mapClickListener?.onMapClick(latlng.toGms()) + currentInfoWindow?.close() + currentInfoWindow = null + } } catch (e: Exception) { Log.w(TAG, e) } @@ -688,12 +708,17 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } symbolManager.iconAllowOverlap = true symbolManager.addClickListener { + val marker = markers[it.id] try { - markers[it.id]?.let { markerClickListener?.onMarkerClick(it) } == true + if (markers[it.id]?.let { markerClickListener?.onMarkerClick(it) } == true) { + return@addClickListener true + } } catch (e: Exception) { Log.w(TAG, e) - false + return@addClickListener false } + + marker?.let { showInfoWindow(it) } == true } symbolManager.addDragListener(object : OnSymbolDragListener { override fun onAnnotationDragStarted(annotation: Symbol?) { @@ -761,6 +786,17 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } } + internal fun showInfoWindow(marker: MarkerImpl): Boolean { + infoWindowAdapter.getInfoWindowViewFor(marker, MapContext(context))?.let { infoView -> + currentInfoWindow?.close() + currentInfoWindow = InfoWindow(infoView, this, marker).also { infoWindow -> + mapView?.let { infoWindow.open(it) } + } + return true + } + return false + } + override fun useViewLifecycleWhenInFragment(): Boolean { Log.d(TAG, "unimplemented Method: useViewLifecycleWhenInFragment") return false @@ -782,6 +818,8 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) symbolManager?.onDestroy() symbolManager = null + currentInfoWindow?.close() + pendingMarkers.clear() markers.clear() diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/BitmapDescriptor.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/BitmapDescriptor.kt index e228387da..f0dc0f882 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/BitmapDescriptor.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/BitmapDescriptor.kt @@ -24,7 +24,7 @@ import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions import com.mapbox.mapboxsdk.style.layers.Property.ICON_ANCHOR_TOP_LEFT import com.mapbox.mapboxsdk.utils.ColorUtils -open class BitmapDescriptorImpl(private val id: String, private val size: FloatArray) { +open class BitmapDescriptorImpl(private val id: String, internal val size: FloatArray) { open fun applyTo(options: SymbolOptions, anchor: FloatArray, dpiFactor: Float): SymbolOptions { return options.withIconImage(id).withIconAnchor(ICON_ANCHOR_TOP_LEFT).withIconOffset(arrayOf(-anchor[0] * size[0] / dpiFactor, -anchor[1] * size[1] / dpiFactor)) } diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt new file mode 100644 index 000000000..c5f00abbd --- /dev/null +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt @@ -0,0 +1,156 @@ +package org.microg.gms.maps.mapbox.model + +import android.graphics.PointF +import android.view.LayoutInflater +import android.view.View +import android.view.View.VISIBLE +import android.view.ViewGroup +import android.view.ViewManager +import android.widget.FrameLayout +import android.widget.TextView +import com.google.android.gms.dynamic.ObjectWrapper +import com.google.android.gms.dynamic.unwrap +import com.google.android.gms.maps.internal.IInfoWindowAdapter +import com.google.android.gms.maps.model.internal.IMarkerDelegate +import com.mapbox.android.gestures.Utils +import com.mapbox.mapboxsdk.maps.MapView +import org.microg.gms.maps.mapbox.GoogleMapImpl +import org.microg.gms.maps.mapbox.R +import org.microg.gms.maps.mapbox.utils.MapContext +import org.microg.gms.maps.mapbox.utils.toMapbox +import kotlin.math.* + +/** + * `InfoWindow` is a tooltip shown when a [MarkerImpl] is tapped. Only + * one info window is displayed at a time. When the user clicks on a marker, the currently open info + * window will be closed and the new info window will be displayed. If the user clicks the same + * marker while its info window is currently open, the info window will be reopened. + * + * The info window is drawn oriented against the device's screen, centered above its associated + * marker, unless a different info window anchor is set. The default info window contains the title + * in bold and snippet text below the title. + * If neither is set, no default info window is shown. + * + * Based on Mapbox's / MapLibre's [com.mapbox.mapboxsdk.annotations.InfoWindow]. + * + */ + +fun IInfoWindowAdapter.getInfoWindowViewFor(marker: IMarkerDelegate, mapContext: MapContext): View? { + getInfoWindow(marker).unwrap()?.let { return it } + + getInfoContents(marker).unwrap()?.let { view -> + // Detach from previous BubbleLayout parent, if exists + view.parent?.let { (it as ViewManager).removeView(view) } + + return FrameLayout(view.context).apply { + background = mapContext.getDrawable(R.drawable.maps_default_bubble) + val fourDp = Utils.dpToPx(4f) + elevation = fourDp + setPadding(fourDp.toInt(), fourDp.toInt(), fourDp.toInt(), fourDp.toInt() * 3) + addView(view) + } + } + + // When a custom adapter is used, but both methods return null, the default adapter must be used + if (this !is DefaultInfoWindowAdapter) { + return DefaultInfoWindowAdapter(mapContext).getInfoWindowViewFor(marker, mapContext) + } + + return null +} + +class InfoWindow internal constructor( + private val view: View, private val map: GoogleMapImpl, internal val marker: MarkerImpl +) { + private var coordinates: PointF = PointF(0f, 0f) + var isVisible = false + + init { + view.setOnClickListener { + map.onInfoWindowClickListener?.onInfoWindowClick(marker) + } + view.setOnLongClickListener { + map.onInfoWindowLongClickListener?.onInfoWindowLongClick(marker) + true + } + } + + fun open(mapView: MapView) { + val layoutParams: FrameLayout.LayoutParams = FrameLayout.LayoutParams( + FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT + ) + view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED) + + close(true) // if it was already opened + mapView.addView(view, layoutParams) + isVisible = true + + // Set correct position + update() + } + + /** + * Close this [InfoWindow] if it is visible, otherwise calling this will do nothing. + * + * @param silent `OnInfoWindowCloseListener` is only called if `silent` is not `false` + */ + fun close(silent: Boolean = false) { + if (isVisible) { + isVisible = false + (view.parent as ViewGroup?)?.removeView(view) + if (!silent) { + map.onInfoWindowCloseListener?.onInfoWindowClose(marker) + } + } + } + + /** + * Updates the position of the displayed view. + */ + fun update() { + map.map?.projection?.toScreenLocation(marker.position.toMapbox())?.let { + coordinates = it + } + + val iconDimensions = marker.getIconDimensions() + val width = iconDimensions?.get(0) ?: 0f + val height = iconDimensions?.get(1) ?: 0f + + view.x = + coordinates.x - view.measuredWidth / 2f + sin(Math.toRadians(marker.rotation.toDouble())).toFloat() * width * marker.getInfoWindowAnchor()[0] + view.y = coordinates.y - view.measuredHeight - max( + height * cos(Math.toRadians(marker.rotation.toDouble())).toFloat() * marker.getInfoWindowAnchor()[1], 0f + ) + } +} + +class DefaultInfoWindowAdapter(val context: MapContext) : IInfoWindowAdapter { + override fun asBinder() = null + + override fun getInfoWindow(marker: IMarkerDelegate?): ObjectWrapper { + + if (marker == null) return ObjectWrapper.wrap(null) + + val showDefaultMarker = (marker.title != null) || (marker.snippet != null) + + return if (!showDefaultMarker) ObjectWrapper.wrap(null) + else ObjectWrapper.wrap( + LayoutInflater.from(context).inflate(R.layout.maps_default_bubble_layout, null, false).apply { + + marker.title?.let { + val titleTextView = findViewById(R.id.title) + titleTextView.text = it + titleTextView.visibility = VISIBLE + } + + marker.snippet?.let { + val snippetTextView = findViewById(R.id.snippet) + snippetTextView.text = it + snippetTextView.visibility = VISIBLE + } + } + ) + } + + override fun getInfoContents(marker: IMarkerDelegate?) = null +} \ No newline at end of file diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt index 2aaf4da31..0d11c4c12 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt @@ -35,6 +35,7 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options private var visible: Boolean = options.isVisible private var rotation: Float = options.rotation private var anchor: FloatArray = floatArrayOf(options.anchorU, options.anchorV) + private var infoWindowAnchor: FloatArray? = null private var icon: BitmapDescriptorImpl? = options.icon?.remoteObject.unwrap() private var alpha: Float = options.alpha private var title: String? = options.title @@ -85,6 +86,7 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options this.position = position ?: return annotation?.latLng = position.toMapbox() map.symbolManager?.let { update(it) } + map.currentInfoWindow?.update() } /** @@ -93,18 +95,25 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options */ internal fun setPositionWhileDragging(position: LatLng) { this.position = position + map.currentInfoWindow?.update() } override fun getPosition(): LatLng = position override fun setTitle(title: String?) { this.title = title + map.currentInfoWindow?.let { + if (it.marker == this) it.close() + } } override fun getTitle(): String? = title override fun setSnippet(snippet: String?) { this.snippet = snippet + map.currentInfoWindow?.let { + if (it.marker == this) it.close() + } } override fun getSnippet(): String? = snippet @@ -118,18 +127,22 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options override fun isDraggable(): Boolean = draggable override fun showInfoWindow() { - Log.d(TAG, "unimplemented Method: showInfoWindow") - infoWindowShown = true + if (isInfoWindowShown) { + // Per docs, don't call `onWindowClose` if info window is re-opened programmatically + map.currentInfoWindow?.close(silent = true) + } + map.showInfoWindow(this) } override fun hideInfoWindow() { - Log.d(TAG, "unimplemented Method: hideInfoWindow") - infoWindowShown = false + if (isInfoWindowShown) { + map.currentInfoWindow?.close() + map.currentInfoWindow = null + } } override fun isInfoWindowShown(): Boolean { - Log.d(TAG, "unimplemented Method: isInfoWindowShow") - return infoWindowShown + return map.currentInfoWindow?.marker == this } override fun setVisible(visible: Boolean) { @@ -170,6 +183,9 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options anchor = floatArrayOf(x, y) annotation?.let { icon?.applyTo(it, anchor, map.dpiFactor) } map.symbolManager?.let { update(it) } + if (infoWindowAnchor == null) { + map.currentInfoWindow?.update() + } } override fun setFlat(flat: Boolean) { @@ -185,14 +201,18 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options this.rotation = rotation annotation?.iconRotate = rotation map.symbolManager?.let { update(it) } + map.currentInfoWindow?.update() } override fun getRotation(): Float = rotation override fun setInfoWindowAnchor(x: Float, y: Float) { - Log.d(TAG, "unimplemented Method: setInfoWindowAnchor") + infoWindowAnchor = floatArrayOf(x, y) + map.currentInfoWindow?.update() } + internal fun getInfoWindowAnchor() = infoWindowAnchor ?: floatArrayOf(0.5f, 1f) + override fun setAlpha(alpha: Float) { this.alpha = alpha annotation?.iconOpacity = if (visible) alpha else 0f @@ -222,6 +242,10 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false } + fun getIconDimensions(): FloatArray? { + return icon?.size + } + companion object { private val TAG = "GmsMapMarker" } diff --git a/play-services-maps-core-mapbox/src/main/res/drawable/maps_default_bubble.xml b/play-services-maps-core-mapbox/src/main/res/drawable/maps_default_bubble.xml new file mode 100644 index 000000000..c172be81e --- /dev/null +++ b/play-services-maps-core-mapbox/src/main/res/drawable/maps_default_bubble.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/play-services-maps-core-mapbox/src/main/res/layout/maps_default_bubble_layout.xml b/play-services-maps-core-mapbox/src/main/res/layout/maps_default_bubble_layout.xml new file mode 100644 index 000000000..6f175407c --- /dev/null +++ b/play-services-maps-core-mapbox/src/main/res/layout/maps_default_bubble_layout.xml @@ -0,0 +1,34 @@ + + + + + + + + \ No newline at end of file diff --git a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/GoogleMapImpl.java b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/GoogleMapImpl.java index 87a512091..301c7ed2e 100644 --- a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/GoogleMapImpl.java +++ b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/GoogleMapImpl.java @@ -45,6 +45,8 @@ import com.google.android.gms.maps.internal.IOnCameraMoveCanceledListener; import com.google.android.gms.maps.internal.IOnCameraMoveListener; import com.google.android.gms.maps.internal.IOnCameraMoveStartedListener; import com.google.android.gms.maps.internal.IOnInfoWindowClickListener; +import com.google.android.gms.maps.internal.IOnInfoWindowCloseListener; +import com.google.android.gms.maps.internal.IOnInfoWindowLongClickListener; import com.google.android.gms.maps.internal.IOnMapClickListener; import com.google.android.gms.maps.internal.IOnMapLoadedCallback; import com.google.android.gms.maps.internal.IOnMapLongClickListener; @@ -661,6 +663,16 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub } + @Override + public void setInfoWindowLongClickListener(IOnInfoWindowLongClickListener listener) throws RemoteException { + Log.d(TAG, "unimplemented Method: setInfoWindowLongClickListener"); + } + + @Override + public void setInfoWindowCloseListener(IOnInfoWindowCloseListener listener) throws RemoteException { + Log.d(TAG, "unimplemented Method: setInfoWindowCloseListener"); + } + @Override public void onStart() throws RemoteException { Log.d(TAG, "unimplemented Method: onStart"); -- GitLab From 40ed6a3ce4510b76493909da352c9ece73e263ed Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Mon, 23 Jan 2023 10:29:32 +0100 Subject: [PATCH 14/38] Fix crash with unimplemented method --- .../src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt index 38cd1f3b9..d0aa04dab 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt @@ -243,7 +243,7 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options } } - override fun setStrokePattern(pattern: IObjectWrapper) { + override fun setStrokePattern(pattern: IObjectWrapper?) { Log.d(TAG, "unimplemented method: set stroke pattern") } -- GitLab From 3e72859aafd4d70d889094de3c907081850bd69a Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Thu, 26 Jan 2023 11:47:26 +0000 Subject: [PATCH 15/38] Circles (part 1) --- .../gms/maps/internal/IGoogleMapDelegate.aidl | 3 +- .../maps/internal/IOnCircleClickListener.aidl | 7 + .../maps/model/internal/ICircleDelegate.aidl | 7 + .../android/gms/maps/model/CircleOptions.java | 22 ++ play-services-maps-core-mapbox/build.gradle | 2 + .../org/microg/gms/maps/mapbox/GoogleMap.kt | 59 ++++-- .../microg/gms/maps/mapbox/model/Circle.kt | 200 +++++++++++++++--- .../microg/gms/maps/vtm/GoogleMapImpl.java | 6 + .../gms/maps/vtm/markup/CircleImpl.java | 37 ++++ 9 files changed, 292 insertions(+), 51 deletions(-) create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnCircleClickListener.aidl diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl index fe592337f..bcb27314f 100644 --- a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl @@ -13,6 +13,7 @@ import com.google.android.gms.maps.internal.IOnCameraIdleListener; import com.google.android.gms.maps.internal.IOnCameraMoveCanceledListener; import com.google.android.gms.maps.internal.IOnCameraMoveListener; import com.google.android.gms.maps.internal.IOnCameraMoveStartedListener; +import com.google.android.gms.maps.internal.IOnCircleClickListener; import com.google.android.gms.maps.internal.IOnMapClickListener; import com.google.android.gms.maps.internal.IOnMapLongClickListener; import com.google.android.gms.maps.internal.IOnMarkerClickListener; @@ -126,7 +127,7 @@ interface IGoogleMapDelegate { //void setPolygonClickListener(IOnPolygonClickListener listener) = 84; void setInfoWindowCloseListener(IOnInfoWindowCloseListener listener) = 85; //void setPolylineClickListener(IOnPolylineClickListener listener) = 86; - //void setCircleClickListener(IOnCircleClickListener listener) = 88; + void setCircleClickListener(IOnCircleClickListener listener) = 88; boolean setMapStyle(in MapStyleOptions options) = 90; void setMinZoomPreference(float minZoom) = 91; diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnCircleClickListener.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnCircleClickListener.aidl new file mode 100644 index 000000000..cd7ad60e6 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnCircleClickListener.aidl @@ -0,0 +1,7 @@ +package com.google.android.gms.maps.internal; + +import com.google.android.gms.maps.model.internal.ICircleDelegate; + +interface IOnCircleClickListener { + void onCircleClick(ICircleDelegate circle); +} diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl index 719d8eab6..8f2277e9e 100644 --- a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl @@ -1,5 +1,6 @@ package com.google.android.gms.maps.model.internal; +import com.google.android.gms.dynamic.IObjectWrapper; import com.google.android.gms.maps.model.LatLng; interface ICircleDelegate { @@ -21,4 +22,10 @@ interface ICircleDelegate { boolean isVisible(); boolean equalsRemote(ICircleDelegate other); int hashCodeRemote(); + void setClickable(boolean clickable); + boolean isClickable(); + void setStrokePattern(IObjectWrapper object); + IObjectWrapper getStrokePattern(); + void setTag(IObjectWrapper object); + IObjectWrapper getTag(); } diff --git a/play-services-api/src/main/java/com/google/android/gms/maps/model/CircleOptions.java b/play-services-api/src/main/java/com/google/android/gms/maps/model/CircleOptions.java index 9f6110602..cb14f525d 100644 --- a/play-services-api/src/main/java/com/google/android/gms/maps/model/CircleOptions.java +++ b/play-services-api/src/main/java/com/google/android/gms/maps/model/CircleOptions.java @@ -43,6 +43,8 @@ public class CircleOptions extends AutoSafeParcelable { private float zIndex = 0; @SafeParceled(8) private boolean visible = true; + @SafeParceled(9) + private boolean clickable = false; /** * Creates circle options. @@ -144,6 +146,15 @@ public class CircleOptions extends AutoSafeParcelable { return visible; } + /** + * Gets the clickability setting for the circle. + * + * @return {@code true} if the circle is clickable; {@code false} if it is not. + */ + public boolean isClickable() { + return clickable; + } + /** * Sets the radius in meters. *

@@ -217,5 +228,16 @@ public class CircleOptions extends AutoSafeParcelable { return this; } + /** + * Specifies whether this circle is clickable. The default setting is {@code false}. + * + * @param clickable + * @return this {@code CircleOptions} object with a new clickability setting. + */ + public CircleOptions clickable(boolean clickable) { + this.clickable = clickable; + return this; + } + public static Creator CREATOR = new AutoCreator(CircleOptions.class); } diff --git a/play-services-maps-core-mapbox/build.gradle b/play-services-maps-core-mapbox/build.gradle index a5bbf5ae0..e0fcff51b 100644 --- a/play-services-maps-core-mapbox/build.gradle +++ b/play-services-maps-core-mapbox/build.gradle @@ -26,6 +26,8 @@ dependencies { implementation("org.maplibre.gl:android-plugin-annotation-v9:1.0.0") { exclude group: 'com.google.android.gms' } + implementation 'org.maplibre.gl:android-sdk-turf:5.9.0' + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" } diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index 87d5bdfa0..64da70428 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -103,6 +103,8 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) private var mapLongClickListener: IOnMapLongClickListener? = null private var markerClickListener: IOnMarkerClickListener? = null private var markerDragListener: IOnMarkerDragListener? = null + private var circleClickListener: IOnCircleClickListener? = null + private var infoWindowAdapter: IInfoWindowAdapter = DefaultInfoWindowAdapter(MapContext(context)) internal var onInfoWindowClickListener: IOnInfoWindowClickListener? = null internal var onInfoWindowLongClickListener: IOnInfoWindowLongClickListener? = null @@ -111,17 +113,14 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) var currentInfoWindow: InfoWindow? = null var lineManager: LineManager? = null - val pendingLines = mutableSetOf() + val pendingLines = mutableSetOf>() var lineId = 0L var fillManager: FillManager? = null - val pendingFills = mutableSetOf() + val pendingFills = mutableSetOf>() + val circles = mutableMapOf() var fillId = 0L - var circleManager: CircleManager? = null - val pendingCircles = mutableSetOf() - var circleId = 0L - var symbolManager: SymbolManager? = null val pendingMarkers = mutableSetOf() val markers = mutableMapOf() @@ -319,20 +318,25 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } override fun addCircle(options: CircleOptions): ICircleDelegate? { - val circle = CircleImpl(this, "c${circleId++}", options) + val circle = CircleImpl(this, "c${fillId++}", options) synchronized(this) { - val circleManager = circleManager - if (circleManager == null) { - pendingCircles.add(circle) + val fillManager = fillManager + if (fillManager == null) { + pendingFills.add(circle) + } else { + circle.update(fillManager) + } + val lineManager = lineManager + if (lineManager == null) { + pendingLines.add(circle.line) } else { - circle.update(circleManager) + circle.line.update(lineManager) } } return circle } override fun clear() { - circleManager?.let { clear(it) } lineManager?.let { clear(it) } fillManager?.let { clear(it) } symbolManager?.let { clear(it) } @@ -359,12 +363,10 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } fun applyMapType() { - val circles = circleManager?.annotations?.values() val lines = lineManager?.annotations?.values() val fills = fillManager?.annotations?.values() val symbols = symbolManager?.annotations?.values() val update: (Style) -> Unit = { - circles?.let { runCatching { circleManager?.update(it) } } lines?.let { runCatching { lineManager?.update(it) } } fills?.let { runCatching { fillManager?.update(it) } } symbols?.let { runCatching { symbolManager?.update(it) } } @@ -491,6 +493,10 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) markerDragListener = listener } + override fun setCircleClickListener(listener: IOnCircleClickListener?) { + circleClickListener = listener + } + override fun setOnInfoWindowClickListener(listener: IOnInfoWindowClickListener?) { onInfoWindowClickListener = listener } @@ -691,11 +697,9 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) if (loaded) return@let val symbolManager: SymbolManager val lineManager: LineManager - val circleManager: CircleManager val fillManager: FillManager synchronized(mapLock) { - circleManager = CircleManager(view, map, it) fillManager = FillManager(view, map, it) symbolManager = SymbolManager(view, map, it) lineManager = LineManager(view, map, it) @@ -703,7 +707,6 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) this.symbolManager = symbolManager this.lineManager = lineManager - this.circleManager = circleManager this.fillManager = fillManager } symbolManager.iconAllowOverlap = true @@ -743,15 +746,30 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } override fun onAnnotationDragFinished(annotation: Symbol?) { + mapView?.post { try { markers[annotation?.id]?.let { markerDragListener?.onMarkerDragEnd(it) } } catch (e: Exception) { Log.w(TAG, e) } + } } }) - pendingCircles.forEach { it.update(circleManager) } - pendingCircles.clear() + fillManager.addClickListener { fill -> + try { + circles[fill.id]?.let { circle -> + if (circle.isClickable) { + circleClickListener?.let { + it.onCircleClick(circle) + return@addClickListener true + } + } + } + } catch (e: Exception) { + Log.w(TAG, e) + } + false + } pendingFills.forEach { it.update(fillManager) } pendingFills.clear() pendingLines.forEach { it.update(lineManager) } @@ -806,14 +824,13 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) override fun onPause() = mapView?.onPause() ?: Unit override fun onDestroy() { Log.d(TAG, "destroy") - circleManager?.onDestroy() - circleManager = null lineManager?.onDestroy() lineManager = null fillManager?.onDestroy() fillManager = null + circles.clear() symbolManager?.onDestroy() symbolManager = null diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt index aa016ea80..d0aa04dab 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt @@ -18,78 +18,184 @@ package org.microg.gms.maps.mapbox.model import android.os.Parcel import android.util.Log +import com.google.android.gms.dynamic.IObjectWrapper +import com.google.android.gms.dynamic.ObjectWrapper +import com.google.android.gms.dynamic.unwrap import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.internal.ICircleDelegate -import com.mapbox.mapboxsdk.plugins.annotation.Circle -import com.mapbox.mapboxsdk.plugins.annotation.CircleOptions +import com.mapbox.geojson.LineString +import com.mapbox.geojson.Point +import com.mapbox.mapboxsdk.plugins.annotation.* import com.mapbox.mapboxsdk.utils.ColorUtils +import com.mapbox.turf.TurfConstants +import com.mapbox.turf.TurfMeasurement +import com.mapbox.turf.TurfMeta +import com.mapbox.turf.TurfTransformation import org.microg.gms.maps.mapbox.GoogleMapImpl -import org.microg.gms.maps.mapbox.utils.toMapbox import com.google.android.gms.maps.model.CircleOptions as GmsCircleOptions -class CircleImpl(private val map: GoogleMapImpl, private val id: String, options: GmsCircleOptions) : ICircleDelegate.Stub(), Markup { +val NORTH_POLE: Point = Point.fromLngLat(0.0, 90.0) +val SOUTH_POLE: Point = Point.fromLngLat(0.0, -90.0) + +/** + * Amount of points to be used in the polygon that approximates the circle. + */ +const val CIRCLE_POLYGON_STEPS = 256 + +class CircleImpl(private val map: GoogleMapImpl, private val id: String, options: GmsCircleOptions) : ICircleDelegate.Stub(), Markup { private var center: LatLng = options.center - private var radius: Double = options.radius + private var radius: Double = options.radius // in meters private var strokeWidth: Float = options.strokeWidth private var strokeColor: Int = options.strokeColor private var fillColor: Int = options.fillColor private var visible: Boolean = options.isVisible + private var clickable: Boolean = options.isClickable + private var tag: Any? = null + + internal val line: Markup = object : Markup { + override var annotation: Line? = null + override val annotationOptions: LineOptions + get() = LineOptions() + .withGeometry( + LineString.fromLngLats( + makeOutlineLatLngs() + ) + ).withLineWidth(strokeWidth / map.dpiFactor) + .withLineColor(ColorUtils.colorToRgbaString(strokeColor)) + .withLineOpacity(if (visible) 1f else 0f) + + override val removed: Boolean = false + } - override var annotation: Circle? = null + override var annotation: Fill? = null override var removed: Boolean = false - override val annotationOptions: CircleOptions - get() = CircleOptions() - .withLatLng(center.toMapbox()) - .withCircleColor(ColorUtils.colorToRgbaString(fillColor)) - .withCircleRadius(radius.toFloat()) - .withCircleStrokeColor(ColorUtils.colorToRgbaString(strokeColor)) - .withCircleStrokeWidth(strokeWidth / map.dpiFactor) - .withCircleOpacity(if (visible) 1f else 0f) - .withCircleStrokeOpacity(if (visible) 1f else 0f) + override val annotationOptions: FillOptions + get() = + FillOptions() + .withGeometry(makePolygon()) + .withFillColor(ColorUtils.colorToRgbaString(fillColor)) + .withFillOutlineColor(ColorUtils.colorToRgbaString(strokeColor)) + .withFillOpacity(if (visible && !wrapsAroundPoles()) 1f else 0f) + + private fun makePolygon() = TurfTransformation.circle( + Point.fromLngLat(center.longitude, center.latitude), radius, CIRCLE_POLYGON_STEPS, TurfConstants.UNIT_METERS + ) + + /** + * Google's "map renderer is unable to draw the circle fill if + * the circle encompasses either the North or South pole". + */ + private fun wrapsAroundPoles() = Point.fromLngLat(center.longitude, center.latitude).let { + TurfMeasurement.distance( + it, NORTH_POLE + ) * 1000 < radius || TurfMeasurement.distance( + it, SOUTH_POLE + ) * 1000 < radius + } + + private fun makeOutlineLatLngs(): MutableList { + val pointList = TurfMeta.coordAll( + makePolygon(), wrapsAroundPoles() + ) + // Circles around the poles are tricky to draw (https://github.com/mapbox/mapbox-gl-js/issues/11235). + // We modify our lines such to match the way Mapbox / MapLibre draws them. + // This results in a small gap somewhere in the line, but avoids an incorrect horizontal line. + + val centerPoint = Point.fromLngLat(center.longitude, center.latitude) + + if (!centerPoint.equals(NORTH_POLE) && TurfMeasurement.distance(centerPoint, NORTH_POLE) * 1000 < radius) { + // Wraps around North Pole + for (i in 0 until pointList.size) { + // We want to have the north-most points at the start and end + if (pointList[0].latitude() > pointList[1].latitude() && pointList[pointList.size - 1].latitude() > pointList[pointList.size - 2].latitude()) { + return pointList + } else { + // Cycle point list + val zero = pointList.removeFirst() + pointList.add(zero) + } + } + } + + if (!centerPoint.equals(SOUTH_POLE) && TurfMeasurement.distance(centerPoint, SOUTH_POLE) * 1000 < radius) { + // Wraps around South Pole + for (i in 0 until pointList.size) { + // We want to have the south-most points at the start and end + if (pointList[0].latitude() < pointList[1].latitude() && pointList[pointList.size - 1].latitude() < pointList[pointList.size - 2].latitude()) { + return pointList + } else { + // Cycle point list + val last = pointList.removeAt(pointList.size - 1) + pointList.add(0, last) + } + } + } + + // In this case no changes were made + return pointList + } + + private fun updateLatLngs() { + val polygon = makePolygon() + + // Extracts points from generated polygon in expected format + annotation?.latLngs = FillOptions().withGeometry(polygon).latLngs + + line.annotation?.latLngs = makeOutlineLatLngs().map { point -> + com.mapbox.mapboxsdk.geometry.LatLng( + point.latitude(), + point.longitude() + ) + } + + if (wrapsAroundPoles()) { + annotation?.fillOpacity = 0f + } + } override fun remove() { removed = true - map.circleManager?.let { update(it) } + map.fillManager?.let { update(it) } } override fun getId(): String = id override fun setCenter(center: LatLng) { this.center = center - annotation?.latLng = center.toMapbox() - map.circleManager?.let { update(it) } + updateLatLngs() + map.fillManager?.let { update(it) } } override fun getCenter(): LatLng = center override fun setRadius(radius: Double) { this.radius = radius - annotation?.circleRadius = radius.toFloat() - map.circleManager?.let { update(it) } + updateLatLngs() + map.fillManager?.let { update(it) } } override fun getRadius(): Double = radius override fun setStrokeWidth(width: Float) { this.strokeWidth = width - annotation?.circleStrokeWidth = width / map.dpiFactor - map.circleManager?.let { update(it) } + line.annotation?.lineWidth = width / map.dpiFactor + map.lineManager?.let { line.update(it) } } override fun getStrokeWidth(): Float = strokeWidth override fun setStrokeColor(color: Int) { this.strokeColor = color - annotation?.setCircleStrokeColor(color) - map.circleManager?.let { update(it) } + line.annotation?.setLineColor(color) + map.lineManager?.let { line.update(it) } } override fun getStrokeColor(): Int = strokeColor override fun setFillColor(color: Int) { this.fillColor = color - annotation?.setCircleColor(color) - map.circleManager?.let { update(it) } + annotation?.setFillColor(color) + map.fillManager?.let { update(it) } } override fun getFillColor(): Int = fillColor @@ -105,9 +211,8 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options override fun setVisible(visible: Boolean) { this.visible = visible - annotation?.circleOpacity = if (visible) 1f else 0f - annotation?.circleStrokeOpacity = if (visible) 1f else 0f - map.circleManager?.let { update(it) } + annotation?.fillOpacity = if (visible && !wrapsAroundPoles()) 1f else 0f + map.fillManager?.let { update(it) } } override fun isVisible(): Boolean = visible @@ -116,6 +221,43 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options override fun hashCodeRemote(): Int = hashCode() + override fun setClickable(clickable: Boolean) { + this.clickable = clickable + } + + override fun isClickable(): Boolean { + return clickable + } + + override fun update(manager: AnnotationManager<*, Fill, FillOptions, *, *, *>) { + synchronized(this) { + val id = annotation?.id + if (removed && id != null) { + map.circles.remove(id) + } + super.update(manager) + val annotation = annotation + if (annotation != null && id == null) { + map.circles[annotation.id] = this + } + } + } + + override fun setStrokePattern(pattern: IObjectWrapper?) { + Log.d(TAG, "unimplemented method: set stroke pattern") + } + + override fun getStrokePattern(): IObjectWrapper { + Log.d(TAG, "unimplemented method: getStrokePattern") + return ObjectWrapper.wrap(null) + } + + override fun setTag(o: IObjectWrapper) { + this.tag = o.unwrap() + } + + override fun getTag(): IObjectWrapper = ObjectWrapper.wrap(tag) + override fun hashCode(): Int { return id.hashCode() } diff --git a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/GoogleMapImpl.java b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/GoogleMapImpl.java index 301c7ed2e..8eae51a68 100644 --- a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/GoogleMapImpl.java +++ b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/GoogleMapImpl.java @@ -44,6 +44,7 @@ import com.google.android.gms.maps.internal.IOnCameraIdleListener; import com.google.android.gms.maps.internal.IOnCameraMoveCanceledListener; import com.google.android.gms.maps.internal.IOnCameraMoveListener; import com.google.android.gms.maps.internal.IOnCameraMoveStartedListener; +import com.google.android.gms.maps.internal.IOnCircleClickListener; import com.google.android.gms.maps.internal.IOnInfoWindowClickListener; import com.google.android.gms.maps.internal.IOnInfoWindowCloseListener; import com.google.android.gms.maps.internal.IOnInfoWindowLongClickListener; @@ -214,6 +215,11 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub } + @Override + public void setCircleClickListener(IOnCircleClickListener listener) throws RemoteException { + Log.d(TAG, "unimplemented Method: setCircleClickListener"); + } + @Override public boolean setMapStyle(MapStyleOptions options) throws RemoteException { Log.d(TAG, "unimplemented Method: setMapStyle"); diff --git a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java index 18b4a9994..9fe9a05ff 100644 --- a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java +++ b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java @@ -18,6 +18,9 @@ package org.microg.gms.maps.vtm.markup; import android.os.RemoteException; +import android.util.Log; +import com.google.android.gms.dynamic.IObjectWrapper; +import com.google.android.gms.dynamic.ObjectWrapper; import com.google.android.gms.maps.model.CircleOptions; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.internal.ICircleDelegate; @@ -30,6 +33,8 @@ import org.oscim.map.Map; public class CircleImpl extends ICircleDelegate.Stub implements DrawableMarkup { + private static final String TAG = "GmsMapCircle"; + private final String id; private final CircleOptions options; private final MarkupListener listener; @@ -139,6 +144,38 @@ public class CircleImpl extends ICircleDelegate.Stub implements DrawableMarkup { return id.hashCode(); } + @Override + public void setClickable(boolean clickable) throws RemoteException { + Log.d(TAG, "unimplemented method: setClickable"); + } + + @Override + public boolean isClickable() throws RemoteException { + return false; + } + + @Override + public void setStrokePattern(IObjectWrapper object) throws RemoteException { + Log.d(TAG, "unimplemented method: setStrokePattern"); + } + + @Override + public IObjectWrapper getStrokePattern() throws RemoteException { + Log.d(TAG, "unimplemented method: getStrokePattern"); + return ObjectWrapper.wrap(null); + } + + @Override + public void setTag(IObjectWrapper object) throws RemoteException { + Log.d(TAG, "unimplemented method: setTag"); + } + + @Override + public IObjectWrapper getTag() throws RemoteException { + Log.d(TAG, "unimplemented method: getTag"); + return ObjectWrapper.wrap(null); + } + @Override public boolean onClick() { return listener.onClick(this); -- GitLab From e763a60a600757be45f35110f96969744c587fb4 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sat, 24 Dec 2022 21:02:19 +0100 Subject: [PATCH 16/38] Maps: Add a few missing parts --- .../gms/maps/internal/IGoogleMapDelegate.aidl | 7 ++- .../internal/ILocationSourceDelegate.aidl | 4 ++ .../IOnIndoorStateChangeListener.aidl | 6 ++ .../internal/IOnLocationChangeListener.aidl | 7 +++ .../google/android/gms/maps/model/Cap.aidl | 3 + .../android/gms/maps/model/StyleSpan.aidl | 3 + .../internal/IIndoorBuildingDelegate.aidl | 10 ++++ .../model/internal/IIndoorLevelDelegate.aidl | 9 +++ .../maps/model/internal/IPolygonDelegate.aidl | 1 + .../model/internal/IPolylineDelegate.aidl | 49 ++++++++++----- .../google/android/gms/maps/model/Cap.java | 21 +++++++ .../android/gms/maps/model/PatternItem.java | 24 +++++++- .../gms/maps/model/PolylineOptions.java | 59 ++++++++++++------- .../android/gms/maps/model/StampStyle.java | 18 ++++++ .../android/gms/maps/model/StrokeStyle.java | 23 ++++++++ .../android/gms/maps/model/StyleSpan.java | 25 ++++++++ .../org/microg/gms/maps/mapbox/GoogleMap.kt | 42 +++++++++---- .../microg/gms/maps/mapbox/model/Polygon.kt | 5 +- .../microg/gms/maps/mapbox/model/Polyline.kt | 33 ++++++++++- .../gms/maps/mapbox/utils/MapContext.kt | 4 +- .../gms/maps/vtm/markup/PolygonImpl.java | 5 ++ .../gms/maps/vtm/markup/PolylineImpl.java | 43 ++++++++++++++ 22 files changed, 345 insertions(+), 56 deletions(-) create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnIndoorStateChangeListener.aidl create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnLocationChangeListener.aidl create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/model/Cap.aidl create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/model/StyleSpan.aidl create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IIndoorBuildingDelegate.aidl create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IIndoorLevelDelegate.aidl create mode 100644 play-services-api/src/main/java/com/google/android/gms/maps/model/Cap.java create mode 100644 play-services-api/src/main/java/com/google/android/gms/maps/model/StampStyle.java create mode 100644 play-services-api/src/main/java/com/google/android/gms/maps/model/StrokeStyle.java create mode 100644 play-services-api/src/main/java/com/google/android/gms/maps/model/StyleSpan.java diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl index bcb27314f..6759dbbd9 100644 --- a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl @@ -34,11 +34,12 @@ import com.google.android.gms.maps.model.MapStyleOptions; import com.google.android.gms.maps.model.PolygonOptions; import com.google.android.gms.maps.model.PolylineOptions; import com.google.android.gms.maps.model.TileOverlayOptions; -import com.google.android.gms.maps.model.internal.IPolylineDelegate; -import com.google.android.gms.maps.model.internal.IPolygonDelegate; -import com.google.android.gms.maps.model.internal.IMarkerDelegate; import com.google.android.gms.maps.model.internal.ICircleDelegate; import com.google.android.gms.maps.model.internal.IGroundOverlayDelegate; +import com.google.android.gms.maps.model.internal.IIndoorBuildingDelegate; +import com.google.android.gms.maps.model.internal.IMarkerDelegate; +import com.google.android.gms.maps.model.internal.IPolygonDelegate; +import com.google.android.gms.maps.model.internal.IPolylineDelegate; import com.google.android.gms.maps.model.internal.ITileOverlayDelegate; interface IGoogleMapDelegate { diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/ILocationSourceDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/ILocationSourceDelegate.aidl index 203ec69f1..3f1ed56fb 100644 --- a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/ILocationSourceDelegate.aidl +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/ILocationSourceDelegate.aidl @@ -1,4 +1,8 @@ package com.google.android.gms.maps.internal; +import com.google.android.gms.maps.internal.IOnLocationChangeListener; + interface ILocationSourceDelegate { + void activate(IOnLocationChangeListener listener) = 0; + void deactivate() = 1; } diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnIndoorStateChangeListener.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnIndoorStateChangeListener.aidl new file mode 100644 index 000000000..c224c58e2 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnIndoorStateChangeListener.aidl @@ -0,0 +1,6 @@ +package com.google.android.gms.maps.internal; + +interface IOnIndoorStateChangeListener { + void onIndoorBuildingFocused() = 0; + void onIndoorLevelActivated() = 1; +} diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnLocationChangeListener.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnLocationChangeListener.aidl new file mode 100644 index 000000000..7d3897dcf --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnLocationChangeListener.aidl @@ -0,0 +1,7 @@ +package com.google.android.gms.maps.internal; + +import android.location.Location; + +interface IOnLocationChangeListener { + void onLocationChanged(in Location location) = 1; +} diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Cap.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Cap.aidl new file mode 100644 index 000000000..802366f61 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Cap.aidl @@ -0,0 +1,3 @@ +package com.google.android.gms.maps.model; + +parcelable Cap; diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/StyleSpan.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/StyleSpan.aidl new file mode 100644 index 000000000..3dd85466b --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/StyleSpan.aidl @@ -0,0 +1,3 @@ +package com.google.android.gms.maps.model; + +parcelable StyleSpan; diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IIndoorBuildingDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IIndoorBuildingDelegate.aidl new file mode 100644 index 000000000..3ec555d78 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IIndoorBuildingDelegate.aidl @@ -0,0 +1,10 @@ +package com.google.android.gms.maps.model.internal; + +interface IIndoorBuildingDelegate { + int getActiveLevelIndex() = 0; + int getDefaultLevelIndex() = 1; + List getLevels() = 2; // IIndoorLevelDelegate's + boolean isUnderground() = 3; + boolean equalsRemote(IIndoorBuildingDelegate other) = 4; + int hashCodeRemote() = 5; +} diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IIndoorLevelDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IIndoorLevelDelegate.aidl new file mode 100644 index 000000000..8c48348e0 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IIndoorLevelDelegate.aidl @@ -0,0 +1,9 @@ +package com.google.android.gms.maps.model.internal; + +interface IIndoorLevelDelegate { + String getName() = 0; + String getShortName() = 1; + void activate() = 2; + boolean equalsRemote(IIndoorLevelDelegate other) = 3; + int hashCodeRemote() = 4; +} diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IPolygonDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IPolygonDelegate.aidl index 79292fc7a..ef1d273ab 100644 --- a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IPolygonDelegate.aidl +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IPolygonDelegate.aidl @@ -31,6 +31,7 @@ interface IPolygonDelegate { boolean equalsRemote(IPolygonDelegate other) = 18; int hashCodeRemote() = 19; void setClickable(boolean click) = 20; + boolean isClickable() = 21; void setStrokeJointType(int type) = 22; int getStrokeJointType() = 23; void setStrokePattern(in List items) = 24; diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IPolylineDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IPolylineDelegate.aidl index ebbb336bf..0e957b2ca 100644 --- a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IPolylineDelegate.aidl +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IPolylineDelegate.aidl @@ -1,22 +1,39 @@ package com.google.android.gms.maps.model.internal; +import com.google.android.gms.dynamic.IObjectWrapper; import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.PatternItem; +import com.google.android.gms.maps.model.StyleSpan; interface IPolylineDelegate { - void remove(); - String getId(); - void setPoints(in List points); - List getPoints(); - void setWidth(float width); - float getWidth(); - void setColor(int color); - int getColor(); - void setZIndex(float zIndex); - float getZIndex(); - void setVisible(boolean visible); - boolean isVisible(); - void setGeodesic(boolean geod); - boolean isGeodesic(); - boolean equalsRemote(IPolylineDelegate other); - int hashCodeRemote(); + void remove() = 0; + String getId() = 1; + void setPoints(in List points) = 2; + List getPoints() = 3; + void setWidth(float width) = 4; + float getWidth() = 5; + void setColor(int color) = 6; + int getColor() = 7; + void setZIndex(float zIndex) = 8; + float getZIndex() = 9; + void setVisible(boolean visible) = 10; + boolean isVisible() = 11; + void setGeodesic(boolean geod) = 12; + boolean isGeodesic() = 13; + boolean equalsRemote(IPolylineDelegate other) = 14; + int hashCodeRemote() = 15; + void setClickable(boolean clickable) = 16; + boolean isClickable() = 17; + //void setStartCap(Cap startCap) = 18; + //Cap getStartCap() = 19; + //void setEndCap(Cap endCap) = 20; + //Cap getEndCap() = 21; + void setJointType(int jointType) = 22; + int getJointType() = 23; + void setPattern(in List pattern) = 24; + List getPattern() = 25; + void setTag(IObjectWrapper tag) = 26; + IObjectWrapper getTag() = 27; + //void setSpans(in List spans) = 28; + //List getSpans() = 29 } diff --git a/play-services-api/src/main/java/com/google/android/gms/maps/model/Cap.java b/play-services-api/src/main/java/com/google/android/gms/maps/model/Cap.java new file mode 100644 index 000000000..d5d38d1f7 --- /dev/null +++ b/play-services-api/src/main/java/com/google/android/gms/maps/model/Cap.java @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2022 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.maps.model; + +import android.os.IBinder; + +import org.microg.safeparcel.AutoSafeParcelable; + +public class Cap extends AutoSafeParcelable { + @Field(2) + private int type; + @Field(3) + private IBinder bitmap; + private BitmapDescriptor bitmapDescriptor; + @Field(4) + private float bitmapRefWidth; + public static final Creator CREATOR = new AutoCreator<>(Cap.class); +} diff --git a/play-services-api/src/main/java/com/google/android/gms/maps/model/PatternItem.java b/play-services-api/src/main/java/com/google/android/gms/maps/model/PatternItem.java index c964cb86c..6f8e3f7ab 100644 --- a/play-services-api/src/main/java/com/google/android/gms/maps/model/PatternItem.java +++ b/play-services-api/src/main/java/com/google/android/gms/maps/model/PatternItem.java @@ -8,6 +8,8 @@ package com.google.android.gms.maps.model; +import android.os.Parcel; + import org.microg.gms.common.PublicApi; import org.microg.safeparcel.AutoSafeParcelable; @@ -19,7 +21,10 @@ public class PatternItem extends AutoSafeParcelable { @Field(2) private int type; @Field(3) - private Float length; + private float length; + + private PatternItem() { + } @PublicApi(exclude = true) PatternItem(int type, Float length) { @@ -32,5 +37,20 @@ public class PatternItem extends AutoSafeParcelable { return "[PatternItem: type=" + type + " length=" + length + "]"; } - public static final Creator CREATOR = new AutoCreator<>(PatternItem.class); + public static final Creator CREATOR = new AutoCreator(PatternItem.class) { + @Override + public PatternItem createFromParcel(Parcel parcel) { + PatternItem item = super.createFromParcel(parcel); + switch (item.type) { + case 0: + return new Dash(item.length); + case 1: + return new Dot(); + case 2: + return new Gap(item.length); + default: + return item; + } + } + }; } diff --git a/play-services-api/src/main/java/com/google/android/gms/maps/model/PolylineOptions.java b/play-services-api/src/main/java/com/google/android/gms/maps/model/PolylineOptions.java index d9a9dc5b4..5e2cda9b1 100644 --- a/play-services-api/src/main/java/com/google/android/gms/maps/model/PolylineOptions.java +++ b/play-services-api/src/main/java/com/google/android/gms/maps/model/PolylineOptions.java @@ -1,17 +1,6 @@ /* - * Copyright (C) 2013-2017 microG Project Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * SPDX-FileCopyrightText: 2015 microG Project Team + * SPDX-License-Identifier: Apache-2.0 */ package com.google.android.gms.maps.model; @@ -20,7 +9,6 @@ import android.graphics.Color; import org.microg.gms.common.PublicApi; import org.microg.safeparcel.AutoSafeParcelable; -import org.microg.safeparcel.SafeParceled; import java.util.ArrayList; import java.util.List; @@ -31,20 +19,32 @@ import java.util.List; */ @PublicApi public class PolylineOptions extends AutoSafeParcelable { - @SafeParceled(1) + @Field(1) private int versionCode = 1; - @SafeParceled(value = 2, subClass = LatLng.class) + @Field(value = 2, subClass = LatLng.class) private List points = new ArrayList(); - @SafeParceled(3) + @Field(3) private float width = 10; - @SafeParceled(4) + @Field(4) private int color = Color.BLACK; - @SafeParceled(5) + @Field(5) private float zIndex = 0; - @SafeParceled(6) + @Field(6) private boolean visible = true; - @SafeParceled(7) + @Field(7) private boolean geodesic = false; + @Field(8) + private boolean clickable = false; + @Field(9) + private Cap startCap; + @Field(10) + private Cap endCap; + @Field(11) + private int jointType = JointType.DEFAULT; + @Field(value = 12, subClass = PatternItem.class) + private List pattern = null; + @Field(value = 13, subClass = StyleSpan.class) + private List spans = null; public PolylineOptions() { } @@ -68,6 +68,11 @@ public class PolylineOptions extends AutoSafeParcelable { return this; } + public PolylineOptions clickable(boolean clickable) { + this.clickable = clickable; + return this; + } + public PolylineOptions color(int color) { this.color = color; return this; @@ -82,6 +87,14 @@ public class PolylineOptions extends AutoSafeParcelable { return color; } + public int getJointType() { + return jointType; + } + + public List getPattern() { + return pattern; + } + public List getPoints() { return points; } @@ -102,6 +115,10 @@ public class PolylineOptions extends AutoSafeParcelable { return visible; } + public boolean isClickable() { + return clickable; + } + public PolylineOptions visible(boolean visible) { this.visible = visible; return this; diff --git a/play-services-api/src/main/java/com/google/android/gms/maps/model/StampStyle.java b/play-services-api/src/main/java/com/google/android/gms/maps/model/StampStyle.java new file mode 100644 index 000000000..a0cf3aaff --- /dev/null +++ b/play-services-api/src/main/java/com/google/android/gms/maps/model/StampStyle.java @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2022 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.maps.model; + +import android.os.IBinder; + +import org.microg.safeparcel.AutoSafeParcelable; + +public class StampStyle extends AutoSafeParcelable { + @Field(2) + private IBinder stamp; + private BitmapDescriptor stampDescriptor; + + public static final Creator CREATOR = new AutoCreator<>(StampStyle.class); +} diff --git a/play-services-api/src/main/java/com/google/android/gms/maps/model/StrokeStyle.java b/play-services-api/src/main/java/com/google/android/gms/maps/model/StrokeStyle.java new file mode 100644 index 000000000..edc91583a --- /dev/null +++ b/play-services-api/src/main/java/com/google/android/gms/maps/model/StrokeStyle.java @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2022 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.maps.model; + +import org.microg.safeparcel.AutoSafeParcelable; + +public class StrokeStyle extends AutoSafeParcelable { + @Field(2) + private float width; + @Field(3) + private int color; + @Field(4) + private int toColor; + @Field(5) + private boolean isVisible; + @Field(6) + private StampStyle stamp; + + public static final Creator CREATOR = new AutoCreator<>(StrokeStyle.class); +} diff --git a/play-services-api/src/main/java/com/google/android/gms/maps/model/StyleSpan.java b/play-services-api/src/main/java/com/google/android/gms/maps/model/StyleSpan.java new file mode 100644 index 000000000..19e210141 --- /dev/null +++ b/play-services-api/src/main/java/com/google/android/gms/maps/model/StyleSpan.java @@ -0,0 +1,25 @@ +/* + * SPDX-FileCopyrightText: 2022 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.maps.model; + +import org.microg.safeparcel.AutoSafeParcelable; + +public class StyleSpan extends AutoSafeParcelable { + @Field(2) + private StrokeStyle style; + @Field(3) + private double segments; + + public double getSegments() { + return segments; + } + + public StrokeStyle getStyle() { + return style; + } + + public static final Creator CREATOR = new AutoCreator<>(StyleSpan.class); +} diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index 64da70428..2a5c662f4 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -59,6 +59,9 @@ import org.microg.gms.maps.mapbox.model.InfoWindow import org.microg.gms.maps.mapbox.model.getInfoWindowViewFor import com.mapbox.mapboxsdk.camera.CameraUpdateFactory import com.mapbox.mapboxsdk.maps.OnMapReadyCallback +import com.mapbox.mapboxsdk.location.engine.LocationEngineCallback +import com.mapbox.mapboxsdk.location.engine.LocationEngineResult +import com.mapbox.mapboxsdk.location.engine.LocationEngineRequest import org.microg.gms.maps.MapsConstants.* import org.microg.gms.maps.mapbox.model.* import org.microg.gms.maps.mapbox.utils.MapContext @@ -111,6 +114,19 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) internal var onInfoWindowCloseListener: IOnInfoWindowCloseListener? = null var currentInfoWindow: InfoWindow? = null + private var myLocationChangeListener: IOnMyLocationChangeListener? = null + + private val locationEngineCallback = object : LocationEngineCallback { + override fun onSuccess(result: LocationEngineResult?) { + result?.lastLocation?.let { location -> + Log.d(TAG, "myLocationChanged: $location") + myLocationChangeListener?.onMyLocationChanged(ObjectWrapper.wrap(location)) + } + } + override fun onFailure(e: Exception) { + Log.w(TAG, e) + } + } var lineManager: LineManager? = null val pendingLines = mutableSetOf>() @@ -143,6 +159,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) val fakeWatermark = View(mapContext) + fakeWatermark.tag = "GoogleWatermark" fakeWatermark.layoutParams = object : RelativeLayout.LayoutParams(0, 0) { @SuppressLint("RtlHardcoded") override fun addRule(verb: Int, subject: Int) { @@ -421,6 +438,15 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) try { if (locationComponent.isLocationComponentActivated) { locationComponent.isLocationComponentEnabled = myLocation + if (myLocation) { + locationComponent.locationEngine?.requestLocationUpdates( + locationComponent.locationEngineRequest, + locationEngineCallback, + null + ) + } else { + locationComponent.locationEngine?.removeLocationUpdates(locationEngineCallback) + } } } catch (e: SecurityException) { Log.w(TAG, e) @@ -431,8 +457,9 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } override fun getMyLocation(): Location? { - Log.d(TAG, "unimplemented Method: getMyLocation") - return null + synchronized(mapLock) { + return map?.locationComponent?.lastKnownLocation + } } override fun setLocationSource(locationSource: ILocationSourceDelegate?) { @@ -519,8 +546,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } override fun setOnMyLocationChangeListener(listener: IOnMyLocationChangeListener?) { - Log.d(TAG, "unimplemented Method: setOnMyLocationChangeListener") - + myLocationChangeListener = listener } override fun setOnMyLocationButtonClickListener(listener: IOnMyLocationButtonClickListener?) { @@ -787,13 +813,9 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) renderMode = RenderMode.COMPASS } + setMyLocationEnabled(locationEnabled) + synchronized(mapLock) { - try { - map.locationComponent.isLocationComponentEnabled = locationEnabled - } catch (e: SecurityException) { - Log.w(TAG, e) - locationEnabled = false - } loaded = true if (loadedCallback != null) { Log.d(TAG, "Invoking callback delayed, as map is loaded") diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polygon.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polygon.kt index c0de5468e..2c10af4a7 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polygon.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polygon.kt @@ -8,6 +8,7 @@ package org.microg.gms.maps.mapbox.model import android.os.Parcel import android.util.Log import com.google.android.gms.dynamic.IObjectWrapper +import com.google.android.gms.dynamic.ObjectWrapper import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.PatternItem import com.google.android.gms.maps.model.PolygonOptions @@ -143,6 +144,8 @@ class PolygonImpl(private val map: GoogleMapImpl, private val id: String, option clickable = click } + override fun isClickable(): Boolean = clickable + override fun setStrokeJointType(type: Int) { strokeJointType = type } @@ -159,7 +162,7 @@ class PolygonImpl(private val map: GoogleMapImpl, private val id: String, option tag = obj } - override fun getTag(): IObjectWrapper? = tag + override fun getTag(): IObjectWrapper = tag ?: ObjectWrapper.wrap(null) override fun hashCode(): Int { return id.hashCode() diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polyline.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polyline.kt index f9a8f91b9..15751f906 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polyline.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polyline.kt @@ -18,7 +18,10 @@ package org.microg.gms.maps.mapbox.model import android.os.Parcel import android.util.Log +import com.google.android.gms.dynamic.IObjectWrapper +import com.google.android.gms.dynamic.ObjectWrapper import com.google.android.gms.maps.model.LatLng +import com.google.android.gms.maps.model.PatternItem import com.google.android.gms.maps.model.internal.IPolylineDelegate import com.mapbox.mapboxsdk.plugins.annotation.Line import com.mapbox.mapboxsdk.plugins.annotation.LineOptions @@ -30,8 +33,12 @@ import com.google.android.gms.maps.model.PolylineOptions as GmsLineOptions class PolylineImpl(private val map: GoogleMapImpl, private val id: String, options: GmsLineOptions) : IPolylineDelegate.Stub(), Markup { private var points = ArrayList(options.points) private var width = options.width + private var jointType = options.jointType + private var pattern = ArrayList(options.pattern.orEmpty()) private var color = options.color private var visible: Boolean = options.isVisible + private var clickable: Boolean = options.isClickable + private var tag: IObjectWrapper? = null override var annotation: Line? = null override var removed: Boolean = false @@ -103,6 +110,30 @@ class PolylineImpl(private val map: GoogleMapImpl, private val id: String, optio override fun hashCodeRemote(): Int = hashCode() + override fun setClickable(clickable: Boolean) { + this.clickable = clickable + } + + override fun isClickable(): Boolean = clickable + + override fun setJointType(jointType: Int) { + this.jointType = jointType + } + + override fun getJointType(): Int = jointType + + override fun setPattern(pattern: MutableList?) { + this.pattern = ArrayList(pattern.orEmpty()) + } + + override fun getPattern(): MutableList = pattern + + override fun setTag(tag: IObjectWrapper?) { + this.tag = tag + } + + override fun getTag(): IObjectWrapper = tag ?: ObjectWrapper.wrap(null) + override fun hashCode(): Int { return id.hashCode() } @@ -128,4 +159,4 @@ class PolylineImpl(private val map: GoogleMapImpl, private val id: String, optio companion object { private val TAG = "GmsMapPolyline" } -} \ No newline at end of file +} diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/MapContext.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/MapContext.kt index 2b00202a4..a8ce14125 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/MapContext.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/MapContext.kt @@ -24,7 +24,7 @@ import android.view.LayoutInflater import org.microg.gms.common.Constants import java.io.File -class MapContext(private val context: Context) : ContextWrapper(context.createPackageContext(Constants.GMS_PACKAGE_NAME, Context.CONTEXT_INCLUDE_CODE and Context.CONTEXT_IGNORE_SECURITY)) { +class MapContext(private val context: Context) : ContextWrapper(context.createPackageContext(Constants.GMS_PACKAGE_NAME, Context.CONTEXT_INCLUDE_CODE or Context.CONTEXT_IGNORE_SECURITY)) { private var layoutInflater: LayoutInflater? = null private val appContext: Context get() = context.applicationContext ?: context @@ -77,4 +77,4 @@ class MapContext(private val context: Context) : ContextWrapper(context.createPa companion object { val TAG = "GmsMapContext" } -} \ No newline at end of file +} diff --git a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/PolygonImpl.java b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/PolygonImpl.java index cb1a55f53..23bcfc83c 100644 --- a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/PolygonImpl.java +++ b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/PolygonImpl.java @@ -205,6 +205,11 @@ public class PolygonImpl extends IPolygonDelegate.Stub implements DrawableMarkup } + @Override + public boolean isClickable() throws RemoteException { + return false; + } + @Override public void setStrokeJointType(int type) throws RemoteException { diff --git a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/PolylineImpl.java b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/PolylineImpl.java index b2ff4c2f3..7e098596e 100644 --- a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/PolylineImpl.java +++ b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/PolylineImpl.java @@ -19,7 +19,9 @@ package org.microg.gms.maps.vtm.markup; import android.os.RemoteException; import android.util.Log; +import com.google.android.gms.dynamic.IObjectWrapper; import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.PatternItem; import com.google.android.gms.maps.model.PolylineOptions; import com.google.android.gms.maps.model.internal.IPolylineDelegate; @@ -157,6 +159,47 @@ public class PolylineImpl extends IPolylineDelegate.Stub implements DrawableMark return id.hashCode(); } + // Not implemented + @Override + public void setClickable(boolean clickable) throws RemoteException { + + } + + @Override + public boolean isClickable() throws RemoteException { + return false; + } + + @Override + public void setJointType(int jointType) throws RemoteException { + + } + + @Override + public int getJointType() throws RemoteException { + return 0; + } + + @Override + public void setPattern(List pattern) throws RemoteException { + + } + + @Override + public List getPattern() throws RemoteException { + return null; + } + + @Override + public void setTag(IObjectWrapper tag) throws RemoteException { + + } + + @Override + public IObjectWrapper getTag() throws RemoteException { + return null; + } + @Override public Drawable getDrawable(Map map) { if (!isVisible() || removed) return null; -- GitLab From d49828be554b51d8559a9b801fc4d807e900c2e6 Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Mon, 6 Feb 2023 11:20:58 +0100 Subject: [PATCH 17/38] =?UTF-8?q?Circle=20outline=20=E2=80=93=20first=20im?= =?UTF-8?q?plementation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../google/android/gms/maps/model/Dash.aidl | 3 + .../google/android/gms/maps/model/Dot.aidl | 3 + .../google/android/gms/maps/model/Gap.aidl | 3 + .../maps/model/internal/ICircleDelegate.aidl | 5 +- .../android/gms/maps/model/CircleOptions.java | 25 ++++++ .../android/gms/maps/model/PatternItem.java | 2 +- .../org/microg/gms/maps/mapbox/GoogleMap.kt | 26 +++++- .../org/microg/gms/maps/mapbox/Pattern.kt | 88 +++++++++++++++++++ .../microg/gms/maps/mapbox/model/Circle.kt | 32 +++++-- .../gms/maps/vtm/markup/CircleImpl.java | 9 +- 10 files changed, 180 insertions(+), 16 deletions(-) create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/model/Dash.aidl create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/model/Dot.aidl create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/model/Gap.aidl create mode 100644 play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Dash.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Dash.aidl new file mode 100644 index 000000000..256aedac9 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Dash.aidl @@ -0,0 +1,3 @@ +package com.google.android.gms.maps.model; + +parcelable Dash; diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Dot.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Dot.aidl new file mode 100644 index 000000000..c8aa8afb0 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Dot.aidl @@ -0,0 +1,3 @@ +package com.google.android.gms.maps.model; + +parcelable Dot; diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Gap.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Gap.aidl new file mode 100644 index 000000000..fd4fde3ae --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Gap.aidl @@ -0,0 +1,3 @@ +package com.google.android.gms.maps.model; + +parcelable Gap; diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl index 8f2277e9e..0a2c088af 100644 --- a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl @@ -2,6 +2,7 @@ package com.google.android.gms.maps.model.internal; import com.google.android.gms.dynamic.IObjectWrapper; import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.PatternItem; interface ICircleDelegate { void remove(); @@ -24,8 +25,8 @@ interface ICircleDelegate { int hashCodeRemote(); void setClickable(boolean clickable); boolean isClickable(); - void setStrokePattern(IObjectWrapper object); - IObjectWrapper getStrokePattern(); + void setStrokePattern(in List items); + List getStrokePattern(); void setTag(IObjectWrapper object); IObjectWrapper getTag(); } diff --git a/play-services-api/src/main/java/com/google/android/gms/maps/model/CircleOptions.java b/play-services-api/src/main/java/com/google/android/gms/maps/model/CircleOptions.java index cb14f525d..63ff492a7 100644 --- a/play-services-api/src/main/java/com/google/android/gms/maps/model/CircleOptions.java +++ b/play-services-api/src/main/java/com/google/android/gms/maps/model/CircleOptions.java @@ -22,6 +22,10 @@ import org.microg.gms.common.PublicApi; import org.microg.safeparcel.AutoSafeParcelable; import org.microg.safeparcel.SafeParceled; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + /** * Defines options for a Circle. */ @@ -45,6 +49,8 @@ public class CircleOptions extends AutoSafeParcelable { private boolean visible = true; @SafeParceled(9) private boolean clickable = false; + @SafeParceled(10) + private List strokePattern = null; /** * Creates circle options. @@ -239,5 +245,24 @@ public class CircleOptions extends AutoSafeParcelable { return this; } + /** + * Specifies a stroke pattern for the circle's outline. The default stroke pattern is solid, represented by {@code null}. + * + * @return this {@link CircleOptions} object with a new stroke pattern set. + */ + public CircleOptions strokePattern(List pattern) { + this.strokePattern = pattern; + return this; + } + + /** + * Gets the stroke pattern set in this {@link CircleOptions} object for the circle's outline. + * + * @return the stroke pattern of the circle's outline. + */ + public List getStrokePattern() { + return strokePattern; + } + public static Creator CREATOR = new AutoCreator(CircleOptions.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/maps/model/PatternItem.java b/play-services-api/src/main/java/com/google/android/gms/maps/model/PatternItem.java index 6f8e3f7ab..1278df94d 100644 --- a/play-services-api/src/main/java/com/google/android/gms/maps/model/PatternItem.java +++ b/play-services-api/src/main/java/com/google/android/gms/maps/model/PatternItem.java @@ -21,7 +21,7 @@ public class PatternItem extends AutoSafeParcelable { @Field(2) private int type; @Field(3) - private float length; + private Float length; private PatternItem() { } diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index 2a5c662f4..3e93a9283 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -18,6 +18,7 @@ package org.microg.gms.maps.mapbox import android.annotation.SuppressLint import android.content.Context +import android.graphics.Bitmap import android.graphics.Point import android.location.Location import android.os.* @@ -61,7 +62,6 @@ import com.mapbox.mapboxsdk.camera.CameraUpdateFactory import com.mapbox.mapboxsdk.maps.OnMapReadyCallback import com.mapbox.mapboxsdk.location.engine.LocationEngineCallback import com.mapbox.mapboxsdk.location.engine.LocationEngineResult -import com.mapbox.mapboxsdk.location.engine.LocationEngineRequest import org.microg.gms.maps.MapsConstants.* import org.microg.gms.maps.mapbox.model.* import org.microg.gms.maps.mapbox.utils.MapContext @@ -142,6 +142,8 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) val markers = mutableMapOf() var markerId = 0L + val pendingBitmaps = mutableMapOf() + var groundId = 0L var tileId = 0L @@ -334,7 +336,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) return TileOverlayImpl(this, "t${tileId++}", options) } - override fun addCircle(options: CircleOptions): ICircleDelegate? { + override fun addCircle(options: CircleOptions): ICircleDelegate { val circle = CircleImpl(this, "c${fillId++}", options) synchronized(this) { val fillManager = fillManager @@ -349,6 +351,9 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } else { circle.line.update(lineManager) } + circle.strokePattern?.let { + addBitmap(it.getName(circle.strokeColor), it.makeBitmap(circle.strokeColor, circle.strokeWidth)) + } } return circle } @@ -803,6 +808,9 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) pendingMarkers.forEach { it.update(symbolManager) } pendingMarkers.clear() + pendingBitmaps.forEach { map -> it.addImage(map.key, map.value) } + pendingBitmaps.clear() + val mapContext = MapContext(context) map.locationComponent.apply { activateLocationComponent(LocationComponentActivationOptions.builder(mapContext, it) @@ -837,11 +845,21 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) return false } + internal fun addBitmap(name: String, bitmap: Bitmap) { + val map = map + if (map != null) { + map.getStyle { + it.addImage(name, bitmap) + } + } else { + pendingBitmaps[name] = bitmap + } + } + override fun useViewLifecycleWhenInFragment(): Boolean { Log.d(TAG, "unimplemented Method: useViewLifecycleWhenInFragment") return false } - override fun onResume() = mapView?.onResume() ?: Unit override fun onPause() = mapView?.onPause() ?: Unit override fun onDestroy() { @@ -892,8 +910,8 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) override fun onExitAmbient() { Log.d(TAG, "unimplemented Method: onExitAmbient") } - override fun onLowMemory() = mapView?.onLowMemory() ?: Unit + override fun onSaveInstanceState(outState: Bundle) { val newBundle = Bundle() mapView?.onSaveInstanceState(newBundle) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt new file mode 100644 index 000000000..30b85beba --- /dev/null +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt @@ -0,0 +1,88 @@ +package org.microg.gms.maps.mapbox + +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.Paint +import android.util.Log +import com.google.android.gms.maps.model.Dash +import com.google.android.gms.maps.model.Dot +import com.google.android.gms.maps.model.Gap +import com.google.android.gms.maps.model.PatternItem +import org.microg.gms.maps.mapbox.model.CircleImpl +import kotlin.math.max + +const val BITMAP_WIDTH = 128 + +fun PatternItem.getName(): String = when (this) { + is Dash -> "dash${this.length}" + is Gap -> "gap${this.length}" + is Dot -> "dot" + else -> this.javaClass.name +} + +/** + * Name of pattern, to identify it after it is added to map + */ +fun MutableList.getName(color: Int) = joinToString("-") { + it.getName() +} + "-${color}" + +/** + * Gets width that a bitmap for this pattern item would have if the pattern's + * bitmap were to have height 1. + */ +fun PatternItem.getVirtualWidth(strokeWidth: Float): Float = when (this) { + is Dash -> this.length + is Gap -> this.length + is Dot -> strokeWidth + else -> 1f +} + +/** + * Gets width that a bitmap for this pattern would have if it were to have + * height 1. + */ +fun MutableList.getVirtualWidth(strokeWidth: Float) = map { it.getVirtualWidth(strokeWidth) }.sum() + +fun MutableList.makeBitmap(color: Int, width: Float): Bitmap = makeBitmap(Paint().apply { + setColor(color) + style = Paint.Style.FILL +}, width) + + +fun MutableList.makeBitmap(paint: Paint, width: Float): Bitmap { + + val virtualWidth = getVirtualWidth(width) + val scale = BITMAP_WIDTH / virtualWidth + Log.d("GmsMapPattern", "vWidth: $virtualWidth, scale: $scale") + + val bitmap = Bitmap.createBitmap(BITMAP_WIDTH, width.toInt(), Bitmap.Config.ARGB_8888) + val canvas = Canvas(bitmap) + + var drawCursor = 0f + for (item in this) { + when (item) { + is Dash -> canvas.drawRect( + drawCursor, + 0f, + drawCursor + item.length * scale, + width, + paint + ) + + // is Gap -> do nothing, only move cursor + + is Dot -> canvas.drawOval( + drawCursor, + 0f, + drawCursor + item.getVirtualWidth(width) * scale, + width, + paint + ) + } + + drawCursor += item.getVirtualWidth(width) * scale + } + + return bitmap +} diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt index d0aa04dab..cff8d333b 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt @@ -22,6 +22,7 @@ import com.google.android.gms.dynamic.IObjectWrapper import com.google.android.gms.dynamic.ObjectWrapper import com.google.android.gms.dynamic.unwrap import com.google.android.gms.maps.model.LatLng +import com.google.android.gms.maps.model.PatternItem import com.google.android.gms.maps.model.internal.ICircleDelegate import com.mapbox.geojson.LineString import com.mapbox.geojson.Point @@ -32,6 +33,8 @@ import com.mapbox.turf.TurfMeasurement import com.mapbox.turf.TurfMeta import com.mapbox.turf.TurfTransformation import org.microg.gms.maps.mapbox.GoogleMapImpl +import org.microg.gms.maps.mapbox.getName +import org.microg.gms.maps.mapbox.makeBitmap import com.google.android.gms.maps.model.CircleOptions as GmsCircleOptions val NORTH_POLE: Point = Point.fromLngLat(0.0, 90.0) @@ -50,6 +53,7 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options private var fillColor: Int = options.fillColor private var visible: Boolean = options.isVisible private var clickable: Boolean = options.isClickable + private var strokePattern: MutableList? = options.strokePattern private var tag: Any? = null internal val line: Markup = object : Markup { @@ -63,6 +67,11 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options ).withLineWidth(strokeWidth / map.dpiFactor) .withLineColor(ColorUtils.colorToRgbaString(strokeColor)) .withLineOpacity(if (visible) 1f else 0f) + .apply { + strokePattern?.let { + withLinePattern(it.getName(strokeColor)) + } + } override val removed: Boolean = false } @@ -74,7 +83,6 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options FillOptions() .withGeometry(makePolygon()) .withFillColor(ColorUtils.colorToRgbaString(fillColor)) - .withFillOutlineColor(ColorUtils.colorToRgbaString(strokeColor)) .withFillOpacity(if (visible && !wrapsAroundPoles()) 1f else 0f) private fun makePolygon() = TurfTransformation.circle( @@ -179,6 +187,10 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options override fun setStrokeWidth(width: Float) { this.strokeWidth = width line.annotation?.lineWidth = width / map.dpiFactor + strokePattern?.let { + map.addBitmap(it.getName(strokeColor), it.makeBitmap(strokeColor, width)) + line.annotation?.linePattern = it.getName(strokeColor) + } map.lineManager?.let { line.update(it) } } @@ -187,6 +199,10 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options override fun setStrokeColor(color: Int) { this.strokeColor = color line.annotation?.setLineColor(color) + strokePattern?.let { + map.addBitmap(it.getName(color), it.makeBitmap(color, strokeWidth)) + line.annotation?.linePattern = it.getName(color) + } map.lineManager?.let { line.update(it) } } @@ -243,13 +259,17 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options } } - override fun setStrokePattern(pattern: IObjectWrapper?) { - Log.d(TAG, "unimplemented method: set stroke pattern") + override fun setStrokePattern(pattern: MutableList?) { + this.strokePattern = pattern + line.annotation?.linePattern = pattern?.getName(strokeColor) + pattern?.let { + map.addBitmap(it.getName(strokeColor), it.makeBitmap(strokeColor, strokeWidth)) + } + map.lineManager?.let { line.update(it) } } - override fun getStrokePattern(): IObjectWrapper { - Log.d(TAG, "unimplemented method: getStrokePattern") - return ObjectWrapper.wrap(null) + override fun getStrokePattern(): MutableList? { + return strokePattern } override fun setTag(o: IObjectWrapper) { diff --git a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java index 9fe9a05ff..8a30cd21e 100644 --- a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java +++ b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java @@ -23,6 +23,7 @@ import com.google.android.gms.dynamic.IObjectWrapper; import com.google.android.gms.dynamic.ObjectWrapper; import com.google.android.gms.maps.model.CircleOptions; import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.PatternItem; import com.google.android.gms.maps.model.internal.ICircleDelegate; import org.microg.gms.maps.vtm.GmsMapsTypeHelper; @@ -31,6 +32,8 @@ import org.oscim.layers.vector.geometries.Drawable; import org.oscim.layers.vector.geometries.Style; import org.oscim.map.Map; +import java.util.List; + public class CircleImpl extends ICircleDelegate.Stub implements DrawableMarkup { private static final String TAG = "GmsMapCircle"; @@ -155,14 +158,14 @@ public class CircleImpl extends ICircleDelegate.Stub implements DrawableMarkup { } @Override - public void setStrokePattern(IObjectWrapper object) throws RemoteException { + public void setStrokePattern(List object) throws RemoteException { Log.d(TAG, "unimplemented method: setStrokePattern"); } @Override - public IObjectWrapper getStrokePattern() throws RemoteException { + public List getStrokePattern() throws RemoteException { Log.d(TAG, "unimplemented method: getStrokePattern"); - return ObjectWrapper.wrap(null); + return null; } @Override -- GitLab From b3641c4b7ab3afc30624c934d046a10e0ae9c383 Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Mon, 13 Feb 2023 12:21:09 +0100 Subject: [PATCH 18/38] Bump MapLibre to 10.0.0-pre.0 --- play-services-maps-core-mapbox/build.gradle | 2 +- .../org/microg/gms/maps/mapbox/GoogleMap.kt | 4 ++-- .../org/microg/gms/maps/mapbox/Projection.kt | 22 ++++++++++++------- .../gms/maps/mapbox/utils/typeConverter.kt | 4 ++-- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/play-services-maps-core-mapbox/build.gradle b/play-services-maps-core-mapbox/build.gradle index e0fcff51b..b4a2779f4 100644 --- a/play-services-maps-core-mapbox/build.gradle +++ b/play-services-maps-core-mapbox/build.gradle @@ -20,7 +20,7 @@ apply plugin: 'kotlin-android' dependencies { implementation project(':play-services-api') implementation project(':play-services-base-core') - implementation("org.maplibre.gl:android-sdk:9.6.0") { + implementation("org.maplibre.gl:android-sdk:10.0.0-pre.0") { exclude group: 'com.google.android.gms' } implementation("org.maplibre.gl:android-plugin-annotation-v9:1.0.0") { diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index 297dc873a..30450843b 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -547,9 +547,9 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) CameraUpdateFactory.paddingTo(left.toDouble(), top.toDouble(), right.toDouble(), bottom.toDouble()) .let { map.moveCamera(it) } - val fourDp = mapView?.context?.resources?.getDimension(R.dimen.mapbox_four_dp)?.toInt() + val fourDp = mapView?.context?.resources?.getDimension(R.dimen.maplibre_four_dp)?.toInt() ?: 0 - val ninetyTwoDp = mapView?.context?.resources?.getDimension(R.dimen.mapbox_ninety_two_dp)?.toInt() + val ninetyTwoDp = mapView?.context?.resources?.getDimension(R.dimen.maplibre_ninety_two_dp)?.toInt() ?: 0 map.uiSettings.setLogoMargins(left + fourDp, top + fourDp, right + fourDp, bottom + fourDp) map.uiSettings.setCompassMargins(left + fourDp, top + fourDp, right + fourDp, bottom + fourDp) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Projection.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Projection.kt index d4ed42f91..a8c0e4a86 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Projection.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Projection.kt @@ -30,21 +30,25 @@ import org.microg.gms.maps.mapbox.utils.toGms import org.microg.gms.maps.mapbox.utils.toMapbox import kotlin.math.roundToInt +val ZERO_LAT_LNG = com.mapbox.mapboxsdk.geometry.LatLng(0.0, 0.0) + // TODO: Do calculations using backed up locations instead of live (which requires UI thread) class ProjectionImpl(private val projection: Projection, private val withoutTiltOrBearing: Boolean) : IProjectionDelegate.Stub() { private val visibleRegion = projection.getVisibleRegion(false) - private val farLeft = projection.toScreenLocation(visibleRegion.farLeft) - private val farRight = projection.toScreenLocation(visibleRegion.farRight) - private val nearLeft = projection.toScreenLocation(visibleRegion.nearLeft) - private val nearRight = projection.toScreenLocation(visibleRegion.nearRight) + private val farLeft = projection.toScreenLocation(visibleRegion.farLeft?: ZERO_LAT_LNG) + private val farRight = projection.toScreenLocation(visibleRegion.farRight?: ZERO_LAT_LNG) + private val nearLeft = projection.toScreenLocation(visibleRegion.nearLeft?: ZERO_LAT_LNG) + private val nearRight = projection.toScreenLocation(visibleRegion.nearRight?: ZERO_LAT_LNG) override fun fromScreenLocation(obj: IObjectWrapper?): LatLng? = try { obj.unwrap()?.let { if (withoutTiltOrBearing) { val xPercent = (it.x.toFloat() - farLeft.x) / (farRight.x - farLeft.x) val yPercent = (it.y.toFloat() - farLeft.y) / (nearLeft.y - farLeft.y) - val lon = visibleRegion.farLeft.longitude + xPercent * (visibleRegion.farRight.longitude - visibleRegion.farLeft.longitude) - val lat = visibleRegion.farLeft.latitude + yPercent * (visibleRegion.nearLeft.latitude - visibleRegion.farLeft.latitude) + val lon = (visibleRegion.farLeft?.longitude ?: 0.0) + xPercent * + ((visibleRegion.farRight?.longitude ?: 0.0) - (visibleRegion.farLeft?.longitude ?: 0.0)) + val lat = (visibleRegion.farLeft?.latitude?: 0.0) + yPercent * + ((visibleRegion.nearLeft?.latitude?: 0.0) - (visibleRegion.farLeft?.latitude?: 0.0)) LatLng(lat, lon) } else { projection.fromScreenLocation(PointF(it)).toGms() @@ -58,8 +62,10 @@ class ProjectionImpl(private val projection: Projection, private val withoutTilt override fun toScreenLocation(latLng: LatLng?): IObjectWrapper = try { ObjectWrapper.wrap(latLng?.toMapbox()?.let { if (withoutTiltOrBearing) { - val xPercent = (it.longitude - visibleRegion.farLeft.longitude) / (visibleRegion.farRight.longitude - visibleRegion.farLeft.longitude) - val yPercent = (it.latitude - visibleRegion.farLeft.latitude) / (visibleRegion.nearLeft.latitude - visibleRegion.farLeft.latitude) + val xPercent = (it.longitude - (visibleRegion.farLeft?.longitude ?: 0.0)) / + ((visibleRegion.farRight?.longitude ?: 0.0) - (visibleRegion.farLeft?.longitude ?: 0.0)) + val yPercent = (it.latitude - (visibleRegion.farLeft?.longitude ?: 0.0)) / + ((visibleRegion.nearLeft?.longitude ?: 0.0) - (visibleRegion.farLeft?.longitude ?: 0.0)) val x = farLeft.x + xPercent * (farRight.x - farLeft.x) val y = farLeft.y + yPercent * (nearLeft.y - farLeft.y) Point(x.roundToInt(), y.roundToInt()) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/typeConverter.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/typeConverter.kt index 9664aea6f..1a27c3a07 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/typeConverter.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/typeConverter.kt @@ -71,7 +71,7 @@ fun LatLng.toGms(): GmsLatLng = GmsLatLng(latitude, longitude) fun LatLngBounds.toGms(): GmsLatLngBounds = GmsLatLngBounds(southWest.toGms(), northEast.toGms()) fun CameraPosition.toGms(): GmsCameraPosition = - GmsCameraPosition(target.toGms(), zoom.toFloat() + 1.0f, tilt.toFloat(), bearing.toFloat()) + GmsCameraPosition(target?.toGms(), zoom.toFloat() + 1.0f, tilt.toFloat(), bearing.toFloat()) fun Bundle.toGms(): Bundle { val newBundle = Bundle(this) @@ -91,4 +91,4 @@ fun Bundle.toGms(): Bundle { } fun VisibleRegion.toGms(): GmsVisibleRegion = - GmsVisibleRegion(nearLeft.toGms(), nearRight.toGms(), farLeft.toGms(), farRight.toGms(), latLngBounds.toGms()) + GmsVisibleRegion(nearLeft?.toGms(), nearRight?.toGms(), farLeft?.toGms(), farRight?.toGms(), latLngBounds.toGms()) -- GitLab From 9e4de6b3e2290f9fe99dab2db5c012b06183f2a1 Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Tue, 14 Feb 2023 20:00:58 +0100 Subject: [PATCH 19/38] Use pattern's width as stroke pattern bitmap width --- .../org/microg/gms/maps/mapbox/GoogleMap.kt | 5 ++- .../org/microg/gms/maps/mapbox/Pattern.kt | 45 +++++++++---------- .../microg/gms/maps/mapbox/model/Circle.kt | 16 ++++--- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index 3e93a9283..7b831cbf8 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -352,7 +352,10 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) circle.line.update(lineManager) } circle.strokePattern?.let { - addBitmap(it.getName(circle.strokeColor), it.makeBitmap(circle.strokeColor, circle.strokeWidth)) + addBitmap( + it.getName(circle.strokeColor, circle.strokeWidth), + it.makeBitmap(circle.strokeColor, circle.strokeWidth) + ) } } return circle diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt index 30b85beba..646a0906a 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt @@ -3,15 +3,10 @@ package org.microg.gms.maps.mapbox import android.graphics.Bitmap import android.graphics.Canvas import android.graphics.Paint -import android.util.Log import com.google.android.gms.maps.model.Dash import com.google.android.gms.maps.model.Dot import com.google.android.gms.maps.model.Gap import com.google.android.gms.maps.model.PatternItem -import org.microg.gms.maps.mapbox.model.CircleImpl -import kotlin.math.max - -const val BITMAP_WIDTH = 128 fun PatternItem.getName(): String = when (this) { is Dash -> "dash${this.length}" @@ -23,15 +18,15 @@ fun PatternItem.getName(): String = when (this) { /** * Name of pattern, to identify it after it is added to map */ -fun MutableList.getName(color: Int) = joinToString("-") { +fun MutableList.getName(color: Int, strokeWidth: Float) = joinToString("-") { it.getName() -} + "-${color}" +} + "-${color}-width${strokeWidth}" /** - * Gets width that a bitmap for this pattern item would have if the pattern's - * bitmap were to have height 1. + * Gets width that a bitmap for this pattern item would have if the pattern's bitmap + * were to be drawn with respect to aspect ratio onto a canvas with height 1. */ -fun PatternItem.getVirtualWidth(strokeWidth: Float): Float = when (this) { +fun PatternItem.getWidth(strokeWidth: Float): Float = when (this) { is Dash -> this.length is Gap -> this.length is Dot -> strokeWidth @@ -39,24 +34,24 @@ fun PatternItem.getVirtualWidth(strokeWidth: Float): Float = when (this) { } /** - * Gets width that a bitmap for this pattern would have if it were to have - * height 1. + * Gets width that a bitmap for this pattern would have if it were to be drawn + * with respect to aspect ratio onto a canvas with height 1. */ -fun MutableList.getVirtualWidth(strokeWidth: Float) = map { it.getVirtualWidth(strokeWidth) }.sum() +fun MutableList.getWidth(strokeWidth: Float) = map { it.getWidth(strokeWidth) }.sum() -fun MutableList.makeBitmap(color: Int, width: Float): Bitmap = makeBitmap(Paint().apply { +fun MutableList.makeBitmap(color: Int, strokeWidth: Float): Bitmap = makeBitmap(Paint().apply { setColor(color) style = Paint.Style.FILL -}, width) +}, strokeWidth) -fun MutableList.makeBitmap(paint: Paint, width: Float): Bitmap { +fun MutableList.makeBitmap(paint: Paint, strokeWidth: Float): Bitmap { - val virtualWidth = getVirtualWidth(width) - val scale = BITMAP_WIDTH / virtualWidth - Log.d("GmsMapPattern", "vWidth: $virtualWidth, scale: $scale") + // Pattern aspect ratio is not respected by renderer + val width = getWidth(strokeWidth).toInt() + val height = strokeWidth.toInt() // avoids squished image bugs - val bitmap = Bitmap.createBitmap(BITMAP_WIDTH, width.toInt(), Bitmap.Config.ARGB_8888) + val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) val canvas = Canvas(bitmap) var drawCursor = 0f @@ -65,8 +60,8 @@ fun MutableList.makeBitmap(paint: Paint, width: Float): Bitmap { is Dash -> canvas.drawRect( drawCursor, 0f, - drawCursor + item.length * scale, - width, + drawCursor + item.length, + strokeWidth, paint ) @@ -75,13 +70,13 @@ fun MutableList.makeBitmap(paint: Paint, width: Float): Bitmap { is Dot -> canvas.drawOval( drawCursor, 0f, - drawCursor + item.getVirtualWidth(width) * scale, - width, + drawCursor + item.getWidth(strokeWidth), + strokeWidth, paint ) } - drawCursor += item.getVirtualWidth(width) * scale + drawCursor += item.getWidth(strokeWidth) } return bitmap diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt index cff8d333b..9a3cb2570 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt @@ -69,7 +69,7 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options .withLineOpacity(if (visible) 1f else 0f) .apply { strokePattern?.let { - withLinePattern(it.getName(strokeColor)) + withLinePattern(it.getName(strokeColor, strokeWidth)) } } @@ -188,8 +188,9 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options this.strokeWidth = width line.annotation?.lineWidth = width / map.dpiFactor strokePattern?.let { - map.addBitmap(it.getName(strokeColor), it.makeBitmap(strokeColor, width)) - line.annotation?.linePattern = it.getName(strokeColor) + val bitmapName = it.getName(strokeColor, strokeWidth) + map.addBitmap(bitmapName, it.makeBitmap(strokeColor, width)) + line.annotation?.linePattern = bitmapName } map.lineManager?.let { line.update(it) } } @@ -200,8 +201,9 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options this.strokeColor = color line.annotation?.setLineColor(color) strokePattern?.let { - map.addBitmap(it.getName(color), it.makeBitmap(color, strokeWidth)) - line.annotation?.linePattern = it.getName(color) + val bitmapName = it.getName(color, strokeWidth) + map.addBitmap(bitmapName, it.makeBitmap(color, strokeWidth)) + line.annotation?.linePattern = bitmapName } map.lineManager?.let { line.update(it) } } @@ -261,9 +263,9 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options override fun setStrokePattern(pattern: MutableList?) { this.strokePattern = pattern - line.annotation?.linePattern = pattern?.getName(strokeColor) + line.annotation?.linePattern = pattern?.getName(strokeColor, strokeWidth) pattern?.let { - map.addBitmap(it.getName(strokeColor), it.makeBitmap(strokeColor, strokeWidth)) + map.addBitmap(it.getName(strokeColor, strokeWidth), it.makeBitmap(strokeColor, strokeWidth)) } map.lineManager?.let { line.update(it) } } -- GitLab From 811a797816577e120e1c2adfa8fef2b4ff5450bb Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Thu, 16 Feb 2023 21:24:30 +0100 Subject: [PATCH 20/38] MapLibre version 10.0.0 --- play-services-maps-core-mapbox/build.gradle | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/play-services-maps-core-mapbox/build.gradle b/play-services-maps-core-mapbox/build.gradle index b4a2779f4..535ac97cd 100644 --- a/play-services-maps-core-mapbox/build.gradle +++ b/play-services-maps-core-mapbox/build.gradle @@ -20,9 +20,7 @@ apply plugin: 'kotlin-android' dependencies { implementation project(':play-services-api') implementation project(':play-services-base-core') - implementation("org.maplibre.gl:android-sdk:10.0.0-pre.0") { - exclude group: 'com.google.android.gms' - } + implementation("org.maplibre.gl:android-sdk:10.0.0") implementation("org.maplibre.gl:android-plugin-annotation-v9:1.0.0") { exclude group: 'com.google.android.gms' } -- GitLab From 1c73e283bb39123a334edbc75bc6e14dd469ec75 Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Mon, 6 Mar 2023 11:30:17 +0100 Subject: [PATCH 21/38] Custom styles implementation frame --- .../assets/style-mapbox-outdoors-v12.json | 13549 ++++++++++++++++ .../src/main/assets/style-microg-normal.json | 2394 +++ .../main/assets/style-microg-satellite.json | 2361 +++ .../org/microg/gms/maps/mapbox/GoogleMap.kt | 20 +- .../org/microg/gms/maps/mapbox/Styles.kt | 76 + 5 files changed, 18389 insertions(+), 11 deletions(-) create mode 100644 play-services-maps-core-mapbox/src/main/assets/style-mapbox-outdoors-v12.json create mode 100644 play-services-maps-core-mapbox/src/main/assets/style-microg-normal.json create mode 100644 play-services-maps-core-mapbox/src/main/assets/style-microg-satellite.json create mode 100644 play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt diff --git a/play-services-maps-core-mapbox/src/main/assets/style-mapbox-outdoors-v12.json b/play-services-maps-core-mapbox/src/main/assets/style-mapbox-outdoors-v12.json new file mode 100644 index 000000000..4924428b8 --- /dev/null +++ b/play-services-maps-core-mapbox/src/main/assets/style-mapbox-outdoors-v12.json @@ -0,0 +1,13549 @@ +{ + "name": "Mapbox Outdoors", + "sprite": "mapbox://sprites/mapbox/outdoors-v12", + "glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf", + "center": [ + 9.1, + 42.2 + ], + "zoom": 7.5, + "fog": { + "range": [ + 1, + 20 + ], + "color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 4, + "hsl(200, 100%, 100%)", + 6, + "hsl(200, 50%, 90%)" + ], + "high-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 4, + "hsl(200, 100%, 60%)", + 6, + "hsl(310, 60%, 80%)" + ], + "space-color": [ + "interpolate", + [ + "exponential", + 1.2 + ], + [ + "zoom" + ], + 4, + "hsl(205, 10%, 10%)", + 6, + "hsl(205, 60%, 50%)" + ], + "horizon-blend": [ + "interpolate", + [ + "exponential", + 1.2 + ], + [ + "zoom" + ], + 4, + 0.01, + 6, + 0.1 + ], + "star-intensity": [ + "interpolate", + [ + "exponential", + 1.2 + ], + [ + "zoom" + ], + 4, + 0.1, + 6, + 0 + ] + }, + "projection": { + "name": "globe" + }, + "visibility": "public", + "version": 8, + "layers": [ + { + "id": "land", + "type": "background", + "layout": {}, + "minzoom": 0, + "paint": { + "background-color": "hsl(60, 20%, 85%)" + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, land" + } + }, + { + "id": "landcover", + "type": "fill", + "source": "composite", + "source-layer": "landcover", + "minzoom": 0, + "maxzoom": 12, + "layout": {}, + "paint": { + "fill-color": [ + "match", + [ + "get", + "class" + ], + "wood", + "hsla(103, 50%, 60%, 0.8)", + "scrub", + "hsla(98, 47%, 68%, 0.6)", + "crop", + "hsla(68, 55%, 70%, 0.6)", + "grass", + "hsla(98, 50%, 74%, 0.6)", + "snow", + "hsl(205, 45%, 95%)", + "hsl(98, 48%, 67%)" + ], + "fill-opacity": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 8, + 0.8, + 12, + 0 + ], + "fill-antialias": false + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, land" + } + }, + { + "id": "national-park", + "type": "fill", + "source": "composite", + "source-layer": "landuse_overlay", + "minzoom": 5, + "filter": [ + "==", + [ + "get", + "class" + ], + "national_park" + ], + "layout": {}, + "paint": { + "fill-color": "hsl(98, 38%, 68%)", + "fill-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 5, + 0, + 6, + 0.6, + 12, + 0.2 + ] + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, land" + } + }, + { + "id": "national-park_tint-band", + "type": "line", + "source": "composite", + "source-layer": "landuse_overlay", + "minzoom": 9, + "filter": [ + "==", + [ + "get", + "class" + ], + "national_park" + ], + "layout": {}, + "paint": { + "line-color": "hsl(98, 38%, 68%)", + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 9, + 1, + 14, + 8 + ], + "line-blur": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 9, + 1, + 14, + 8 + ] + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, land" + } + }, + { + "id": "landuse", + "type": "fill", + "source": "composite", + "source-layer": "landuse", + "minzoom": 5, + "filter": [ + "all", + [ + ">=", + [ + "to-number", + [ + "get", + "sizerank" + ] + ], + 0 + ], + [ + "match", + [ + "get", + "class" + ], + [ + "agriculture", + "wood", + "grass", + "scrub", + "glacier", + "pitch", + "sand" + ], + [ + "step", + [ + "zoom" + ], + false, + 11, + true + ], + "residential", + [ + "step", + [ + "zoom" + ], + true, + 10, + false + ], + [ + "park", + "airport" + ], + [ + "step", + [ + "zoom" + ], + false, + 8, + [ + "case", + [ + "==", + [ + "get", + "sizerank" + ], + 1 + ], + true, + false + ], + 10, + true + ], + [ + "facility", + "industrial" + ], + [ + "step", + [ + "zoom" + ], + false, + 12, + true + ], + "rock", + [ + "step", + [ + "zoom" + ], + false, + 11, + true + ], + "cemetery", + [ + "step", + [ + "zoom" + ], + false, + 11, + true + ], + "school", + [ + "step", + [ + "zoom" + ], + false, + 11, + true + ], + "hospital", + [ + "step", + [ + "zoom" + ], + false, + 11, + true + ], + "commercial_area", + [ + "step", + [ + "zoom" + ], + false, + 11, + true + ], + false + ], + [ + "<=", + [ + "-", + [ + "to-number", + [ + "get", + "sizerank" + ] + ], + [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0, + 18, + 14 + ] + ], + 14 + ] + ], + "layout": {}, + "paint": { + "fill-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + [ + "match", + [ + "get", + "class" + ], + "wood", + "hsla(103, 50%, 60%, 0.8)", + "scrub", + "hsla(98, 47%, 68%, 0.6)", + "agriculture", + "hsla(98, 50%, 74%, 0.6)", + "park", + [ + "match", + [ + "get", + "type" + ], + [ + "garden", + "playground", + "zoo" + ], + "hsl(98, 38%, 68%)", + "hsl(98, 55%, 70%)" + ], + "grass", + "hsla(98, 50%, 74%, 0.6)", + "airport", + "hsl(230, 40%, 82%)", + "cemetery", + "hsl(98, 45%, 75%)", + "glacier", + "hsl(205, 45%, 95%)", + "hospital", + "hsl(20, 45%, 82%)", + "pitch", + "hsl(88, 65%, 75%)", + "sand", + "hsl(69, 60%, 72%)", + "rock", + "hsl(60, 0%, 85%)", + "school", + "hsl(40, 45%, 78%)", + "commercial_area", + "hsl(55, 45%, 85%)", + "residential", + "hsl(60, 7%, 87%)", + [ + "facility", + "industrial" + ], + "hsl(230, 20%, 85%)", + "hsl(60, 22%, 72%)" + ], + 16, + [ + "match", + [ + "get", + "class" + ], + "wood", + "hsla(103, 50%, 60%, 0.8)", + "scrub", + "hsla(98, 47%, 68%, 0.6)", + "agriculture", + "hsla(98, 50%, 74%, 0.6)", + "park", + [ + "match", + [ + "get", + "type" + ], + [ + "garden", + "playground", + "zoo" + ], + "hsl(98, 38%, 68%)", + "hsl(98, 55%, 70%)" + ], + "grass", + "hsla(98, 50%, 74%, 0.6)", + "airport", + "hsl(230, 40%, 82%)", + "cemetery", + "hsl(98, 45%, 75%)", + "glacier", + "hsl(205, 45%, 95%)", + "hospital", + "hsl(20, 45%, 82%)", + "pitch", + "hsl(88, 65%, 75%)", + "sand", + "hsl(69, 60%, 72%)", + "rock", + "hsla(60, 0%, 85%, 0.5)", + "school", + "hsl(40, 45%, 78%)", + "commercial_area", + "hsla(55, 45%, 85%, 0.5)", + [ + "facility", + "industrial" + ], + "hsl(230, 20%, 85%)", + "hsl(60, 22%, 72%)" + ] + ], + "fill-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 8, + [ + "match", + [ + "get", + "class" + ], + "residential", + 0.8, + 0.2 + ], + 10, + [ + "match", + [ + "get", + "class" + ], + "residential", + 0, + 1 + ] + ], + "fill-antialias": false + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, land" + } + }, + { + "id": "pitch-outline", + "type": "line", + "source": "composite", + "source-layer": "landuse", + "minzoom": 15, + "filter": [ + "==", + [ + "get", + "class" + ], + "pitch" + ], + "layout": {}, + "paint": { + "line-color": "hsl(88, 60%, 65%)" + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, land" + } + }, + { + "id": "waterway-shadow", + "type": "line", + "source": "composite", + "source-layer": "waterway", + "minzoom": 10, + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 11, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 11, + "round" + ] + }, + "paint": { + "line-color": "hsl(224, 79%, 69%)", + "line-width": [ + "interpolate", + [ + "exponential", + 1.3 + ], + [ + "zoom" + ], + 9, + [ + "match", + [ + "get", + "class" + ], + [ + "canal", + "river" + ], + 0.1, + 0 + ], + 20, + [ + "match", + [ + "get", + "class" + ], + [ + "canal", + "river" + ], + 8, + 3 + ] + ], + "line-translate": [ + "interpolate", + [ + "exponential", + 1.2 + ], + [ + "zoom" + ], + 7, + [ + "literal", + [ + 0, + 0 + ] + ], + 16, + [ + "literal", + [ + -1, + -1 + ] + ] + ], + "line-translate-anchor": "viewport", + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 8, + 0, + 8.5, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, water" + } + }, + { + "id": "water-shadow", + "type": "fill", + "source": "composite", + "source-layer": "water", + "minzoom": 10, + "layout": {}, + "paint": { + "fill-color": "hsl(224, 79%, 69%)", + "fill-translate": [ + "interpolate", + [ + "exponential", + 1.2 + ], + [ + "zoom" + ], + 7, + [ + "literal", + [ + 0, + 0 + ] + ], + 16, + [ + "literal", + [ + -1, + -1 + ] + ] + ], + "fill-translate-anchor": "viewport" + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, water" + } + }, + { + "id": "waterway", + "type": "line", + "source": "composite", + "source-layer": "waterway", + "minzoom": 8, + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 11, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 11, + "round" + ] + }, + "paint": { + "line-color": "hsl(205, 75%, 70%)", + "line-width": [ + "interpolate", + [ + "exponential", + 1.3 + ], + [ + "zoom" + ], + 9, + [ + "match", + [ + "get", + "class" + ], + [ + "canal", + "river" + ], + 0.1, + 0 + ], + 20, + [ + "match", + [ + "get", + "class" + ], + [ + "canal", + "river" + ], + 8, + 3 + ] + ], + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 8, + 0, + 8.5, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, water" + } + }, + { + "id": "water", + "type": "fill", + "source": "composite", + "source-layer": "water", + "minzoom": 0, + "layout": {}, + "paint": { + "fill-color": "hsl(205, 75%, 70%)" + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, water" + } + }, + { + "id": "water-depth", + "type": "fill", + "source": "composite", + "source-layer": "depth", + "minzoom": 0, + "maxzoom": 8, + "layout": {}, + "paint": { + "fill-antialias": false, + "fill-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 6, + [ + "interpolate", + [ + "linear" + ], + [ + "get", + "min_depth" + ], + 0, + "hsla(205, 75%, 70%, 0.35)", + 200, + "hsla(205, 75%, 63%, 0.35)", + 7000, + "hsla(205, 75%, 56%, 0.35)" + ], + 8, + [ + "interpolate", + [ + "linear" + ], + [ + "get", + "min_depth" + ], + 0, + "hsla(205, 75%, 70%, 0)", + 200, + "hsla(205, 75%, 63%, 0)", + 7000, + "hsla(205, 75%, 53%, 0)" + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, water" + } + }, + { + "id": "wetland", + "type": "fill", + "source": "composite", + "source-layer": "landuse_overlay", + "minzoom": 5, + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "wetland", + "wetland_noveg" + ], + true, + false + ], + "paint": { + "fill-color": "hsl(194, 38%, 74%)", + "fill-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 0.25, + 10.5, + 0.15 + ] + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, water" + } + }, + { + "id": "wetland-pattern", + "type": "fill", + "source": "composite", + "source-layer": "landuse_overlay", + "minzoom": 5, + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "wetland", + "wetland_noveg" + ], + true, + false + ], + "paint": { + "fill-color": "hsl(194, 38%, 74%)", + "fill-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 0, + 10.5, + 1 + ], + "fill-pattern": "wetland", + "fill-translate-anchor": "viewport" + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, water" + } + }, + { + "id": "hillshade", + "type": "fill", + "source": "composite", + "source-layer": "hillshade", + "filter": [ + "all", + [ + "step", + [ + "zoom" + ], + [ + "==", + [ + "get", + "class" + ], + "shadow" + ], + 11, + true + ], + [ + "match", + [ + "get", + "level" + ], + 89, + true, + 78, + [ + "step", + [ + "zoom" + ], + false, + 5, + true + ], + 67, + [ + "step", + [ + "zoom" + ], + false, + 9, + true + ], + 56, + [ + "step", + [ + "zoom" + ], + false, + 6, + true + ], + 94, + [ + "step", + [ + "zoom" + ], + false, + 11, + true + ], + 90, + [ + "step", + [ + "zoom" + ], + false, + 12, + true + ], + false + ] + ], + "minzoom": 0, + "maxzoom": 16, + "layout": {}, + "paint": { + "fill-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 14, + [ + "match", + [ + "get", + "class" + ], + "shadow", + "hsla(66, 38%, 17%, 0.08)", + "hsla(60, 20%, 95%, 0.14)" + ], + 16, + [ + "match", + [ + "get", + "class" + ], + "shadow", + "hsla(66, 38%, 17%, 0)", + "hsla(60, 20%, 95%, 0)" + ] + ], + "fill-antialias": false + }, + "metadata": { + "mapbox:featureComponent": "terrain", + "mapbox:group": "Terrain, land" + } + }, + { + "id": "contour-line", + "type": "line", + "source": "composite", + "source-layer": "contour", + "minzoom": 11, + "filter": [ + "!=", + [ + "get", + "index" + ], + -1 + ], + "layout": {}, + "paint": { + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 11, + [ + "match", + [ + "get", + "index" + ], + [ + 1, + 2 + ], + 0.15, + 0.3 + ], + 13, + [ + "match", + [ + "get", + "index" + ], + [ + 1, + 2 + ], + 0.3, + 0.5 + ] + ], + "line-color": "hsl(60, 10%, 35%)", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 13, + [ + "match", + [ + "get", + "index" + ], + [ + 1, + 2 + ], + 0.5, + 0.6 + ], + 16, + [ + "match", + [ + "get", + "index" + ], + [ + 1, + 2 + ], + 0.8, + 1.2 + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "terrain", + "mapbox:group": "Terrain, land" + } + }, + { + "id": "land-structure-polygon", + "type": "fill", + "source": "composite", + "source-layer": "structure", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "land" + ], + [ + "==", + [ + "geometry-type" + ], + "Polygon" + ] + ], + "layout": {}, + "paint": { + "fill-color": "hsl(60, 20%, 85%)" + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, built" + } + }, + { + "id": "land-structure-line", + "type": "line", + "source": "composite", + "source-layer": "structure", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "land" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": "square" + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.99 + ], + [ + "zoom" + ], + 14, + 0.75, + 20, + 40 + ], + "line-color": "hsl(60, 20%, 85%)" + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, built" + } + }, + { + "id": "aeroway-polygon", + "type": "fill", + "source": "composite", + "source-layer": "aeroway", + "minzoom": 11, + "filter": [ + "all", + [ + "match", + [ + "get", + "type" + ], + [ + "runway", + "taxiway", + "helipad" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "Polygon" + ] + ], + "paint": { + "fill-color": "hsl(230, 36%, 74%)", + "fill-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 0, + 11, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, built" + } + }, + { + "id": "aeroway-line", + "type": "line", + "source": "composite", + "source-layer": "aeroway", + "minzoom": 9, + "filter": [ + "==", + [ + "geometry-type" + ], + "LineString" + ], + "paint": { + "line-color": "hsl(230, 36%, 74%)", + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 9, + [ + "match", + [ + "get", + "type" + ], + "runway", + 1, + 0.5 + ], + 18, + [ + "match", + [ + "get", + "type" + ], + "runway", + 80, + 20 + ] + ], + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 0, + 11, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, built" + } + }, + { + "id": "building", + "type": "fill", + "source": "composite", + "source-layer": "building", + "minzoom": 15, + "filter": [ + "all", + [ + "!=", + [ + "get", + "type" + ], + "building:part" + ], + [ + "==", + [ + "get", + "underground" + ], + "false" + ] + ], + "layout": {}, + "paint": { + "fill-color": "hsl(50, 15%, 75%)", + "fill-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + 0, + 16, + 1 + ], + "fill-outline-color": "hsl(60, 10%, 65%)" + }, + "metadata": { + "mapbox:featureComponent": "buildings", + "mapbox:group": "Buildings, built" + } + }, + { + "id": "building-underground", + "type": "fill", + "source": "composite", + "source-layer": "building", + "minzoom": 15, + "filter": [ + "all", + [ + "==", + [ + "get", + "underground" + ], + "true" + ], + [ + "==", + [ + "geometry-type" + ], + "Polygon" + ] + ], + "layout": {}, + "paint": { + "fill-color": "hsl(260, 60%, 85%)", + "fill-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + 0, + 16, + 0.5 + ] + }, + "metadata": { + "mapbox:featureComponent": "buildings", + "mapbox:group": "Buildings, built" + } + }, + { + "id": "tunnel-minor-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "track" + ], + true, + "service", + [ + "step", + [ + "zoom" + ], + false, + 14, + true + ], + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 3%, 57%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 18, + 10, + 22, + 100 + ], + "line-dasharray": [ + 3, + 3 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels-case" + } + }, + { + "id": "tunnel-street-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "street", + "street_limited" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 3%, 57%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.5, + 18, + 20, + 22, + 200 + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 14, + 1 + ], + "line-dasharray": [ + 3, + 3 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels-case" + } + }, + { + "id": "tunnel-minor-link-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "primary_link", + "secondary_link", + "tertiary_link" + ], + true, + false + ], + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.4, + 18, + 18, + 22, + 180 + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 11, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels-case" + } + }, + { + "id": "tunnel-secondary-tertiary-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 11, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "secondary", + "tertiary" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 22, + 2 + ], + "line-color": "hsl(60, 3%, 57%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0, + 18, + 26, + 22, + 260 + ], + "line-dasharray": [ + 3, + 3 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels-case" + } + }, + { + "id": "tunnel-primary-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 10, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "get", + "class" + ], + "primary" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 22, + 2 + ], + "line-color": "hsl(60, 3%, 57%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 28, + 22, + 280 + ], + "line-dasharray": [ + 3, + 3 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels-case" + } + }, + { + "id": "tunnel-major-link-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.8, + 18, + 20, + 22, + 200 + ], + "line-dasharray": [ + 3, + 3 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels-case" + } + }, + { + "id": "tunnel-motorway-trunk-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 82%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 30, + 22, + 300 + ], + "line-dasharray": [ + 3, + 3 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels-case" + } + }, + { + "id": "tunnel-path-trail", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "match", + [ + "get", + "type" + ], + [ + "hiking", + "mountain_bike", + "trail" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": {}, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 18, + 4 + ], + "line-color": "hsl(60, 32%, 90%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 5, + 0.5 + ] + ], + 15, + [ + "literal", + [ + 4, + 0.5 + ] + ], + 16, + [ + "literal", + [ + 4, + 0.45 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., tunnels" + } + }, + { + "id": "tunnel-path-cycleway-piste", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "match", + [ + "get", + "type" + ], + [ + "cycleway", + "piste" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": {}, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 18, + 4 + ], + "line-color": "hsl(60, 32%, 90%)", + "line-dasharray": [ + 10, + 0 + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., tunnels" + } + }, + { + "id": "tunnel-path", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "!=", + [ + "get", + "type" + ], + "steps" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": {}, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 18, + 4 + ], + "line-color": "hsl(60, 32%, 90%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 1, + 0 + ] + ], + 15, + [ + "literal", + [ + 1.75, + 1 + ] + ], + 16, + [ + "literal", + [ + 1, + 0.75 + ] + ], + 17, + [ + "literal", + [ + 1, + 0.5 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., tunnels" + } + }, + { + "id": "tunnel-steps", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "get", + "type" + ], + "steps" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 16, + 1.6, + 18, + 6 + ], + "line-color": "hsl(60, 32%, 90%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 1, + 0 + ] + ], + 15, + [ + "literal", + [ + 1.75, + 1 + ] + ], + 16, + [ + "literal", + [ + 1, + 0.75 + ] + ], + 17, + [ + "literal", + [ + 0.3, + 0.3 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., tunnels" + } + }, + { + "id": "tunnel-pedestrian", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "get", + "class" + ], + "pedestrian" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.5, + 18, + 12 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 1, + 0 + ] + ], + 15, + [ + "literal", + [ + 1.5, + 0.4 + ] + ], + 16, + [ + "literal", + [ + 1, + 0.2 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., tunnels" + } + }, + { + "id": "tunnel-construction", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "get", + "class" + ], + "construction" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 2, + 18, + 20, + 22, + 200 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 0.4, + 0.8 + ] + ], + 15, + [ + "literal", + [ + 0.3, + 0.6 + ] + ], + 16, + [ + "literal", + [ + 0.2, + 0.3 + ] + ], + 17, + [ + "literal", + [ + 0.2, + 0.25 + ] + ], + 18, + [ + "literal", + [ + 0.15, + 0.15 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-minor", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "track" + ], + true, + "service", + [ + "step", + [ + "zoom" + ], + false, + 14, + true + ], + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 18, + 10, + 22, + 100 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "street_limited", + "hsl(60, 22%, 80%)", + "hsl(0, 0%, 95%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-minor-link", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "primary_link", + "secondary_link", + "tertiary_link" + ], + true, + false + ], + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 13, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 13, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.4, + 18, + 18, + 22, + 180 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-major-link", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.8, + 18, + 20, + 22, + 200 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "motorway_link", + "hsl(15, 100%, 85%)", + "hsl(35, 78%, 85%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-street", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "street", + "street_limited" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.5, + 18, + 20, + 22, + 200 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "street_limited", + "hsl(60, 22%, 80%)", + "hsl(0, 0%, 95%)" + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 14, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-street-low", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "maxzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "street", + "street_limited" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.5, + 18, + 20, + 22, + 200 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-secondary-tertiary", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "secondary", + "tertiary" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0, + 18, + 26, + 22, + 260 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-primary", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "get", + "class" + ], + "primary" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 28, + 22, + 280 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-motorway-trunk", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 30, + 22, + 300 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "motorway", + "hsl(15, 100%, 85%)", + "hsl(35, 78%, 85%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-oneway-arrow-blue", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "get", + "oneway" + ], + "true" + ], + [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "primary", + "secondary", + "street", + "street_limited", + "tertiary" + ], + true, + false + ], + 16, + [ + "match", + [ + "get", + "class" + ], + [ + "primary", + "secondary", + "tertiary", + "street", + "street_limited", + "primary_link", + "secondary_link", + "tertiary_link", + "service", + "track" + ], + true, + false + ] + ] + ], + "layout": { + "symbol-placement": "line", + "icon-image": [ + "step", + [ + "zoom" + ], + "oneway-small", + 18, + "oneway-large" + ], + "symbol-spacing": 200, + "icon-rotation-alignment": "map", + "icon-allow-overlap": true, + "icon-ignore-placement": true + }, + "paint": {}, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-oneway-arrow-white", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "motorway_link", + "trunk", + "trunk_link" + ], + true, + false + ], + [ + "==", + [ + "get", + "oneway" + ], + "true" + ] + ], + "layout": { + "symbol-placement": "line", + "icon-image": [ + "step", + [ + "zoom" + ], + "oneway-white-small", + 18, + "oneway-white-large" + ], + "symbol-spacing": 200, + "icon-rotation-alignment": "map", + "icon-allow-overlap": true, + "icon-ignore-placement": true + }, + "paint": {}, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "cliff", + "type": "line", + "source": "composite", + "source-layer": "structure", + "minzoom": 15, + "filter": [ + "==", + [ + "get", + "class" + ], + "cliff" + ], + "layout": { + "line-cap": "round", + "line-join": "round" + }, + "paint": { + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + 0, + 15.25, + 1 + ], + "line-width": 10, + "line-pattern": "cliff" + }, + "metadata": { + "mapbox:featureComponent": "terrain", + "mapbox:group": "Terrain, surface" + } + }, + { + "id": "ferry", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 8, + "filter": [ + "==", + [ + "get", + "type" + ], + "ferry" + ], + "paint": { + "line-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + "hsl(214, 68%, 63%)", + 17, + "hsl(239, 68%, 63%)" + ], + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.5, + 20, + 1 + ], + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 1, + 0 + ] + ], + 13, + [ + "literal", + [ + 12, + 4 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, ferries" + } + }, + { + "id": "ferry-auto", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 8, + "filter": [ + "==", + [ + "get", + "type" + ], + "ferry_auto" + ], + "paint": { + "line-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + "hsl(214, 68%, 63%)", + 17, + "hsl(239, 68%, 63%)" + ], + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.5, + 20, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, ferries" + } + }, + { + "id": "road-pedestrian-polygon-fill", + "type": "fill", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "path", + "pedestrian" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "case", + [ + "has", + "layer" + ], + [ + ">=", + [ + "get", + "layer" + ], + 0 + ], + true + ], + [ + "==", + [ + "geometry-type" + ], + "Polygon" + ] + ], + "paint": { + "fill-color": "hsl(60, 20%, 85%)" + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-pedestrian-polygon-pattern", + "type": "fill", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "path", + "pedestrian" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "case", + [ + "has", + "layer" + ], + [ + ">=", + [ + "get", + "layer" + ], + 0 + ], + true + ], + [ + "==", + [ + "geometry-type" + ], + "Polygon" + ] + ], + "paint": { + "fill-pattern": "pedestrian-polygon", + "fill-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 16, + 0, + 17, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-path-bg", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "step", + [ + "zoom" + ], + [ + "!", + [ + "match", + [ + "get", + "type" + ], + [ + "steps", + "sidewalk", + "crossing" + ], + true, + false + ] + ], + 16, + [ + "!=", + [ + "get", + "type" + ], + "steps" + ] + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 2, + 18, + 7 + ], + "line-color": [ + "match", + [ + "get", + "type" + ], + "piste", + "hsl(215, 80%, 48%)", + [ + "mountain_bike", + "hiking", + "trail", + "cycleway", + "footway", + "path", + "bridleway" + ], + "hsl(35, 80%, 48%)", + "hsl(60, 1%, 64%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-steps-bg", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "type" + ], + "steps" + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-join": "round" + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 2, + 17, + 4.6, + 18, + 7 + ], + "line-color": "hsl(35, 80%, 48%)", + "line-opacity": 0.75 + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-pedestrian-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "pedestrian" + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "case", + [ + "has", + "layer" + ], + [ + ">=", + [ + "get", + "layer" + ], + 0 + ], + true + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 2, + 18, + 14.5 + ], + "line-color": "hsl(60, 10%, 70%)" + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-path-trail", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "match", + [ + "get", + "type" + ], + [ + "hiking", + "mountain_bike", + "trail" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 18, + 4 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 5, + 0.5 + ] + ], + 15, + [ + "literal", + [ + 4, + 0.5 + ] + ], + 16, + [ + "literal", + [ + 4, + 0.45 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-path-cycleway-piste", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "match", + [ + "get", + "type" + ], + [ + "cycleway", + "piste" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 18, + 4 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + 10, + 0 + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-path", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "step", + [ + "zoom" + ], + [ + "!", + [ + "match", + [ + "get", + "type" + ], + [ + "steps", + "sidewalk", + "crossing" + ], + true, + false + ] + ], + 16, + [ + "!=", + [ + "get", + "type" + ], + "steps" + ] + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 13, + 0.5, + 14, + 1, + 15, + 1, + 18, + 4 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 4, + 0.3 + ] + ], + 15, + [ + "literal", + [ + 1.75, + 0.3 + ] + ], + 16, + [ + "literal", + [ + 1, + 0.3 + ] + ], + 17, + [ + "literal", + [ + 1, + 0.25 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-steps", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "type" + ], + "steps" + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-join": "round" + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 16, + 1.6, + 18, + 6 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 1, + 0 + ] + ], + 15, + [ + "literal", + [ + 1.75, + 1 + ] + ], + 16, + [ + "literal", + [ + 1, + 0.75 + ] + ], + 17, + [ + "literal", + [ + 0.3, + 0.3 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-pedestrian", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "pedestrian" + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "case", + [ + "has", + "layer" + ], + [ + ">=", + [ + "get", + "layer" + ], + 0 + ], + true + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.5, + 18, + 12 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 1, + 0 + ] + ], + 15, + [ + "literal", + [ + 1.5, + 0.4 + ] + ], + 16, + [ + "literal", + [ + 1, + 0.2 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "golf-hole-line", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "==", + [ + "get", + "class" + ], + "golf" + ], + "paint": { + "line-color": "hsl(98, 26%, 56%)" + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-polygon", + "type": "fill", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "primary", + "secondary", + "tertiary", + "primary_link", + "secondary_link", + "tertiary_link", + "trunk", + "trunk_link", + "street", + "street_limited", + "track", + "service" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "Polygon" + ] + ], + "paint": { + "fill-color": "hsl(0, 0%, 95%)", + "fill-outline-color": "hsl(60, 10%, 70%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "turning-feature-outline", + "type": "circle", + "source": "composite", + "source-layer": "road", + "minzoom": 15, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "turning_circle", + "turning_loop" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "Point" + ] + ], + "paint": { + "circle-radius": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 4.5, + 16, + 8, + 18, + 20, + 22, + 200 + ], + "circle-color": "hsl(0, 0%, 95%)", + "circle-stroke-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + 0.8, + 16, + 1.2, + 18, + 2 + ], + "circle-stroke-color": "hsl(60, 10%, 70%)", + "circle-pitch-alignment": "map" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-minor-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "track" + ], + true, + "service", + [ + "step", + [ + "zoom" + ], + false, + 14, + true + ], + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "track", + "hsl(35, 80%, 48%)", + "hsl(60, 10%, 70%)" + ], + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 18, + 10, + 22, + 100 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-street-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "street", + "street_limited" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.5, + 18, + 20, + 22, + 200 + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 14, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-minor-link-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "primary_link", + "secondary_link", + "tertiary_link" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.4, + 18, + 18, + 22, + 180 + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 11, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-secondary-tertiary-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 11, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "secondary", + "tertiary" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0, + 18, + 26, + 22, + 260 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-primary-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 10, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "primary" + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 28, + 22, + 280 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-major-link-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 82%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.8, + 18, + 20, + 22, + 200 + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 11, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-motorway-trunk-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 3, + "filter": [ + "all", + [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + 5, + [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ] + ] + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 82%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 30, + 22, + 300 + ], + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 0, + 3.5, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "turning-feature", + "type": "circle", + "source": "composite", + "source-layer": "road", + "minzoom": 15, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "turning_circle", + "turning_loop" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "Point" + ] + ], + "paint": { + "circle-radius": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 4.5, + 16, + 8, + 18, + 20, + 22, + 200 + ], + "circle-color": "hsl(0, 0%, 95%)", + "circle-pitch-alignment": "map" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-construction", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "construction" + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 2, + 18, + 20, + 22, + 200 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 0.4, + 0.8 + ] + ], + 15, + [ + "literal", + [ + 0.3, + 0.6 + ] + ], + 16, + [ + "literal", + [ + 0.2, + 0.3 + ] + ], + 17, + [ + "literal", + [ + 0.2, + 0.25 + ] + ], + 18, + [ + "literal", + [ + 0.15, + 0.15 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-minor", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "track" + ], + true, + "service", + [ + "step", + [ + "zoom" + ], + false, + 14, + true + ], + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 18, + 10, + 22, + 100 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-minor-link", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "primary_link", + "secondary_link", + "tertiary_link" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 13, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 13, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.4, + 18, + 18, + 22, + 180 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-major-link", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 13, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 13, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.8, + 18, + 20, + 22, + 200 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "motorway_link", + "hsl(15, 100%, 75%)", + "hsl(35, 89%, 75%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-street", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "street", + "street_limited" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.5, + 18, + 20, + 22, + 200 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "street_limited", + "hsl(60, 22%, 80%)", + "hsl(0, 0%, 95%)" + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 14, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-street-low", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 11, + "maxzoom": 14, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "street", + "street_limited" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.5, + 18, + 20, + 22, + 200 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-secondary-tertiary", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 9, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "secondary", + "tertiary" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0, + 18, + 26, + 22, + 260 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-primary", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 6, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "primary" + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 28, + 22, + 280 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-motorway-trunk", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 3, + "filter": [ + "all", + [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + 5, + [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ] + ] + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 13, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 13, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 30, + 22, + 300 + ], + "line-color": [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "class" + ], + "motorway", + "hsl(15, 88%, 69%)", + "trunk", + "hsl(35, 81%, 59%)", + "hsl(60, 18%, 85%)" + ], + 9, + [ + "match", + [ + "get", + "class" + ], + "motorway", + "hsl(15, 100%, 75%)", + "hsl(35, 89%, 75%)" + ] + ], + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 0, + 3.5, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-rail", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "major_rail", + "minor_rail" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ] + ], + "paint": { + "line-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 13, + "hsl(75, 25%, 68%)", + 16, + "hsl(60, 0%, 56%)" + ], + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.5, + 20, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, surface" + } + }, + { + "id": "road-rail-tracks", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "major_rail", + "minor_rail" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ] + ], + "paint": { + "line-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 13, + "hsl(75, 25%, 68%)", + 16, + "hsl(60, 0%, 56%)" + ], + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 4, + 20, + 8 + ], + "line-dasharray": [ + 0.1, + 15 + ], + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 13.75, + 0, + 14, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, surface" + } + }, + { + "id": "level-crossing", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "==", + [ + "get", + "class" + ], + "level_crossing" + ], + "layout": { + "icon-image": "level-crossing", + "icon-rotation-alignment": "map", + "icon-allow-overlap": true, + "icon-ignore-placement": true + }, + "paint": {}, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface-icons" + } + }, + { + "id": "road-oneway-arrow-blue", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "all", + [ + "==", + [ + "get", + "oneway" + ], + "true" + ], + [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "primary", + "secondary", + "tertiary", + "street", + "street_limited" + ], + true, + false + ], + 16, + [ + "match", + [ + "get", + "class" + ], + [ + "primary", + "secondary", + "tertiary", + "street", + "street_limited", + "primary_link", + "secondary_link", + "tertiary_link", + "service", + "track" + ], + true, + false + ] + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ] + ], + "layout": { + "symbol-placement": "line", + "icon-image": [ + "step", + [ + "zoom" + ], + "oneway-small", + 18, + "oneway-large" + ], + "symbol-spacing": 200, + "icon-rotation-alignment": "map", + "icon-allow-overlap": true, + "icon-ignore-placement": true + }, + "paint": {}, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface-icons" + } + }, + { + "id": "road-oneway-arrow-white", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "all", + [ + "==", + [ + "get", + "oneway" + ], + "true" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk", + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ] + ], + "layout": { + "symbol-placement": "line", + "icon-image": [ + "step", + [ + "zoom" + ], + "oneway-white-small", + 18, + "oneway-white-large" + ], + "symbol-spacing": 200, + "icon-rotation-alignment": "map", + "icon-allow-overlap": true, + "icon-ignore-placement": true + }, + "paint": {}, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface-icons" + } + }, + { + "id": "crosswalks", + "type": "symbol", + "source": "composite", + "source-layer": "structure", + "minzoom": 17, + "filter": [ + "all", + [ + "==", + [ + "get", + "type" + ], + "crosswalk" + ], + [ + "==", + [ + "geometry-type" + ], + "Point" + ] + ], + "layout": { + "icon-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 16, + 0.1, + 18, + 0.2, + 19, + 0.5, + 22, + 1.5 + ], + "icon-image": [ + "step", + [ + "zoom" + ], + "crosswalk-small", + 18, + "crosswalk-large" + ], + "icon-rotate": [ + "get", + "direction" + ], + "icon-rotation-alignment": "map", + "icon-allow-overlap": true, + "icon-ignore-placement": true + }, + "paint": {}, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface-icons" + } + }, + { + "id": "gate-fence-hedge", + "type": "line", + "source": "composite", + "source-layer": "structure", + "minzoom": 16, + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "gate", + "fence", + "hedge" + ], + true, + false + ], + "layout": {}, + "paint": { + "line-color": [ + "match", + [ + "get", + "class" + ], + "hedge", + "hsl(98, 32%, 56%)", + "hsl(60, 25%, 63%)" + ], + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 16, + 1, + 20, + 3 + ], + "line-opacity": [ + "match", + [ + "get", + "class" + ], + "gate", + 0.5, + 1 + ], + "line-dasharray": [ + 1, + 2, + 5, + 2, + 1, + 2 + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "bridge-path-bg", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "step", + [ + "zoom" + ], + [ + "!", + [ + "match", + [ + "get", + "type" + ], + [ + "steps", + "sidewalk", + "crossing" + ], + true, + false + ] + ], + 16, + [ + "!=", + [ + "get", + "type" + ], + "steps" + ] + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 2, + 18, + 7 + ], + "line-color": [ + "match", + [ + "get", + "type" + ], + "piste", + "hsl(215, 80%, 48%)", + [ + "mountain_bike", + "hiking", + "trail", + "cycleway", + "footway", + "path", + "bridleway" + ], + "hsl(35, 80%, 48%)", + "hsl(60, 1%, 64%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "bridge-steps-bg", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "type" + ], + "steps" + ], + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 2, + 17, + 4.6, + 18, + 7 + ], + "line-color": "hsl(35, 80%, 48%)", + "line-opacity": 0.75 + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "bridge-pedestrian-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "class" + ], + "pedestrian" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 2, + 18, + 14.5 + ], + "line-color": "hsl(60, 10%, 70%)" + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "bridge-path-trail", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "match", + [ + "get", + "type" + ], + [ + "hiking", + "mountain_bike", + "trail" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": {}, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 18, + 4 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 5, + 0.5 + ] + ], + 15, + [ + "literal", + [ + 4, + 0.5 + ] + ], + 16, + [ + "literal", + [ + 4, + 0.45 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "bridge-path-cycleway-piste", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "match", + [ + "get", + "type" + ], + [ + "cycleway", + "piste" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": {}, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 18, + 4 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + 10, + 0 + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "bridge-path", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "!=", + [ + "get", + "type" + ], + "steps" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": {}, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 18, + 4 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 4, + 0.3 + ] + ], + 15, + [ + "literal", + [ + 1.75, + 0.3 + ] + ], + 16, + [ + "literal", + [ + 1, + 0.3 + ] + ], + 17, + [ + "literal", + [ + 1, + 0.25 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "bridge-steps", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "type" + ], + "steps" + ], + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 16, + 1.6, + 18, + 6 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 1, + 0 + ] + ], + 15, + [ + "literal", + [ + 1.75, + 1 + ] + ], + 16, + [ + "literal", + [ + 1, + 0.75 + ] + ], + 17, + [ + "literal", + [ + 0.3, + 0.3 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "bridge-pedestrian", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "class" + ], + "pedestrian" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.5, + 18, + 12 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 1, + 0 + ] + ], + 15, + [ + "literal", + [ + 1.5, + 0.4 + ] + ], + 16, + [ + "literal", + [ + 1, + 0.2 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "gate-label", + "type": "symbol", + "source": "composite", + "source-layer": "structure", + "minzoom": 16, + "filter": [ + "==", + [ + "get", + "class" + ], + "gate" + ], + "layout": { + "icon-image": [ + "match", + [ + "get", + "type" + ], + "gate", + "gate", + "lift_gate", + "lift-gate", + "" + ] + }, + "paint": {}, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "bridge-minor-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "track" + ], + true, + "service", + [ + "step", + [ + "zoom" + ], + false, + 14, + true + ], + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "track", + "hsl(35, 80%, 48%)", + "hsl(60, 10%, 70%)" + ], + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 18, + 10, + 22, + 100 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-street-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "street", + "street_limited" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "track", + "hsl(35, 80%, 48%)", + "hsl(60, 10%, 70%)" + ], + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.5, + 18, + 20, + 22, + 200 + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 14, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-minor-link-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "primary_link", + "secondary_link", + "tertiary_link" + ], + true, + false + ], + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.4, + 18, + 18, + 22, + 180 + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 11, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-secondary-tertiary-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 11, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "secondary", + "tertiary" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0, + 18, + 26, + 22, + 260 + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 10, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-primary-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 10, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "class" + ], + "primary" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 28, + 22, + 280 + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 10, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-major-link-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "<=", + [ + "get", + "layer" + ], + 1 + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 82%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.8, + 18, + 20, + 22, + 200 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-motorway-trunk-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + [ + "<=", + [ + "get", + "layer" + ], + 1 + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 82%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 30, + 22, + 300 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-construction", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "class" + ], + "construction" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 2, + 18, + 20, + 22, + 200 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 0.4, + 0.8 + ] + ], + 15, + [ + "literal", + [ + 0.3, + 0.6 + ] + ], + 16, + [ + "literal", + [ + 0.2, + 0.3 + ] + ], + 17, + [ + "literal", + [ + 0.2, + 0.25 + ] + ], + 18, + [ + "literal", + [ + 0.15, + 0.15 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-minor", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "track" + ], + true, + "service", + [ + "step", + [ + "zoom" + ], + false, + 14, + true + ], + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 18, + 10, + 22, + 100 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-minor-link", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "primary_link", + "secondary_link", + "tertiary_link" + ], + true, + false + ], + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.4, + 18, + 18, + 22, + 180 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-major-link", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "<=", + [ + "get", + "layer" + ], + 1 + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 13, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.8, + 18, + 20, + 22, + 200 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "motorway_link", + "hsl(15, 100%, 75%)", + "hsl(35, 89%, 75%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-street", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "street", + "street_limited" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.5, + 18, + 20, + 22, + 200 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "street_limited", + "hsl(60, 22%, 80%)", + "hsl(0, 0%, 95%)" + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 14, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-street-low", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "maxzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "street", + "street_limited" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.5, + 18, + 20, + 22, + 200 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-secondary-tertiary", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "secondary", + "tertiary" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0, + 18, + 26, + 22, + 260 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-primary", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "class" + ], + "primary" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 28, + 22, + 280 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-motorway-trunk", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + [ + "<=", + [ + "get", + "layer" + ], + 1 + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 30, + 22, + 300 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "motorway", + "hsl(15, 100%, 75%)", + "hsl(35, 89%, 75%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-major-link-2-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + ">=", + [ + "get", + "layer" + ], + 2 + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 82%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.8, + 18, + 20, + 22, + 200 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-motorway-trunk-2-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + ">=", + [ + "get", + "layer" + ], + 2 + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 82%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 30, + 22, + 300 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-major-link-2", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + ">=", + [ + "get", + "layer" + ], + 2 + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 13, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.8, + 18, + 20, + 22, + 200 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "motorway_link", + "hsl(15, 100%, 75%)", + "hsl(35, 89%, 75%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-motorway-trunk-2", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + ">=", + [ + "get", + "layer" + ], + 2 + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 30, + 22, + 300 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "motorway", + "hsl(15, 100%, 75%)", + "hsl(35, 89%, 75%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-oneway-arrow-blue", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "oneway" + ], + "true" + ], + [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "primary", + "secondary", + "tertiary", + "street", + "street_limited" + ], + true, + false + ], + 16, + [ + "match", + [ + "get", + "class" + ], + [ + "primary", + "secondary", + "tertiary", + "street", + "street_limited", + "primary_link", + "secondary_link", + "tertiary_link", + "service", + "track" + ], + true, + false + ] + ] + ], + "layout": { + "symbol-placement": "line", + "icon-image": [ + "step", + [ + "zoom" + ], + "oneway-small", + 18, + "oneway-large" + ], + "symbol-spacing": 200, + "icon-rotation-alignment": "map", + "icon-allow-overlap": true, + "icon-ignore-placement": true + }, + "paint": {}, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-oneway-arrow-white", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk", + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "==", + [ + "get", + "oneway" + ], + "true" + ] + ], + "layout": { + "symbol-placement": "line", + "icon-image": "oneway-white-small", + "symbol-spacing": 200, + "icon-rotation-alignment": "map", + "icon-allow-overlap": true, + "icon-ignore-placement": true + }, + "paint": {}, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-rail", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "major_rail", + "minor_rail" + ], + true, + false + ] + ], + "paint": { + "line-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 13, + "hsl(75, 25%, 68%)", + 16, + "hsl(60, 0%, 56%)" + ], + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.5, + 20, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, bridges" + } + }, + { + "id": "bridge-rail-tracks", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "major_rail", + "minor_rail" + ], + true, + false + ] + ], + "paint": { + "line-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 13, + "hsl(75, 25%, 68%)", + 16, + "hsl(60, 0%, 56%)" + ], + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 4, + 20, + 8 + ], + "line-dasharray": [ + 0.1, + 15 + ], + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 13.75, + 0, + 14, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, bridges" + } + }, + { + "id": "aerialway", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "==", + [ + "get", + "class" + ], + "aerialway" + ], + "paint": { + "line-color": "hsl(230, 50%, 60%)", + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 20, + 2 + ], + "line-dasharray": [ + 4, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, elevated" + } + }, + { + "id": "admin-1-boundary-bg", + "type": "line", + "source": "composite", + "source-layer": "admin", + "minzoom": 7, + "filter": [ + "all", + [ + "==", + [ + "get", + "admin_level" + ], + 1 + ], + [ + "==", + [ + "get", + "maritime" + ], + "false" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ] + ], + "paint": { + "line-color": "hsl(350, 90%, 88%)", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 3, + 12, + 6 + ], + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 7, + 0, + 8, + 0.5 + ], + "line-dasharray": [ + 1, + 0 + ], + "line-blur": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 0, + 12, + 3 + ] + }, + "metadata": { + "mapbox:featureComponent": "admin-boundaries", + "mapbox:group": "Administrative boundaries, admin" + } + }, + { + "id": "admin-0-boundary-bg", + "type": "line", + "source": "composite", + "source-layer": "admin", + "minzoom": 1, + "filter": [ + "all", + [ + "==", + [ + "get", + "admin_level" + ], + 0 + ], + [ + "==", + [ + "get", + "maritime" + ], + "false" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 4, + 12, + 8 + ], + "line-color": "hsl(350, 90%, 88%)", + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 0, + 4, + 0.5 + ], + "line-blur": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 0, + 12, + 2 + ] + }, + "metadata": { + "mapbox:featureComponent": "admin-boundaries", + "mapbox:group": "Administrative boundaries, admin" + } + }, + { + "id": "admin-1-boundary", + "type": "line", + "source": "composite", + "source-layer": "admin", + "minzoom": 2, + "filter": [ + "all", + [ + "==", + [ + "get", + "admin_level" + ], + 1 + ], + [ + "==", + [ + "get", + "maritime" + ], + "false" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ] + ], + "layout": {}, + "paint": { + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 2, + 0 + ] + ], + 7, + [ + "literal", + [ + 2, + 2, + 6, + 2 + ] + ] + ], + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 0.3, + 12, + 1.5 + ], + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 2, + 0, + 3, + 1 + ], + "line-color": "hsl(350, 30%, 55%)" + }, + "metadata": { + "mapbox:featureComponent": "admin-boundaries", + "mapbox:group": "Administrative boundaries, admin" + } + }, + { + "id": "admin-0-boundary", + "type": "line", + "source": "composite", + "source-layer": "admin", + "minzoom": 1, + "filter": [ + "all", + [ + "==", + [ + "get", + "admin_level" + ], + 0 + ], + [ + "==", + [ + "get", + "disputed" + ], + "false" + ], + [ + "==", + [ + "get", + "maritime" + ], + "false" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ] + ], + "layout": {}, + "paint": { + "line-color": "hsl(350, 30%, 50%)", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 0.5, + 12, + 2 + ], + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 2, + 0 + ] + ], + 7, + [ + "literal", + [ + 2, + 2, + 6, + 2 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "admin-boundaries", + "mapbox:group": "Administrative boundaries, admin" + } + }, + { + "id": "admin-0-boundary-disputed", + "type": "line", + "source": "composite", + "source-layer": "admin", + "minzoom": 1, + "filter": [ + "all", + [ + "==", + [ + "get", + "disputed" + ], + "true" + ], + [ + "==", + [ + "get", + "admin_level" + ], + 0 + ], + [ + "==", + [ + "get", + "maritime" + ], + "false" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ] + ], + "paint": { + "line-color": "hsl(350, 30%, 50%)", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 0.5, + 12, + 2 + ], + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 3, + 2, + 5 + ] + ], + 7, + [ + "literal", + [ + 2, + 1.5 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "admin-boundaries", + "mapbox:group": "Administrative boundaries, admin" + } + }, + { + "id": "contour-label", + "type": "symbol", + "source": "composite", + "source-layer": "contour", + "minzoom": 11, + "filter": [ + "any", + [ + "==", + [ + "get", + "index" + ], + 10 + ], + [ + "==", + [ + "get", + "index" + ], + 5 + ] + ], + "layout": { + "text-field": [ + "concat", + [ + "get", + "ele" + ], + " m" + ], + "symbol-placement": "line", + "text-pitch-alignment": "viewport", + "text-max-angle": 25, + "text-padding": 5, + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + 9.5, + 20, + 12 + ] + }, + "paint": { + "text-color": "hsl(60, 10%, 35%)", + "text-halo-width": 1, + "text-halo-color": "hsl(60, 10%, 85%)" + }, + "metadata": { + "mapbox:featureComponent": "terrain", + "mapbox:group": "Terrain, terrain-labels" + } + }, + { + "id": "building-entrance", + "type": "symbol", + "source": "composite", + "source-layer": "structure", + "minzoom": 18, + "filter": [ + "==", + [ + "get", + "class" + ], + "entrance" + ], + "layout": { + "icon-image": "marker", + "text-field": [ + "get", + "ref" + ], + "text-size": 10, + "text-offset": [ + 0, + -0.5 + ], + "text-font": [ + "DIN Pro Italic", + "Arial Unicode MS Regular" + ] + }, + "paint": { + "text-color": "hsl(60, 8%, 38%)", + "text-halo-color": "hsl(60, 13%, 77%)", + "text-halo-width": 1, + "icon-opacity": 0.4 + }, + "metadata": { + "mapbox:featureComponent": "buildings", + "mapbox:group": "Buildings, building-labels" + } + }, + { + "id": "building-number-label", + "type": "symbol", + "source": "composite", + "source-layer": "housenum_label", + "minzoom": 17, + "layout": { + "text-field": [ + "get", + "house_num" + ], + "text-font": [ + "DIN Pro Italic", + "Arial Unicode MS Regular" + ], + "text-padding": 4, + "text-max-width": 7, + "text-size": 10 + }, + "paint": { + "text-color": "hsl(60, 8%, 38%)", + "text-halo-color": "hsl(60, 13%, 77%)", + "text-halo-width": 1 + }, + "metadata": { + "mapbox:featureComponent": "buildings", + "mapbox:group": "Buildings, building-labels" + } + }, + { + "id": "block-number-label", + "type": "symbol", + "source": "composite", + "source-layer": "place_label", + "minzoom": 16, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "settlement_subdivision" + ], + [ + "==", + [ + "get", + "type" + ], + "block" + ] + ], + "layout": { + "text-field": [ + "get", + "name" + ], + "text-font": [ + "DIN Pro Italic", + "Arial Unicode MS Regular" + ], + "text-max-width": 7, + "text-size": 11 + }, + "paint": { + "text-color": "hsl(60, 18%, 44%)", + "text-halo-color": "hsl(60, 17%, 84%)", + "text-halo-width": 0.5, + "text-halo-blur": 0.5 + }, + "metadata": { + "mapbox:featureComponent": "buildings", + "mapbox:group": "Buildings, building-labels" + } + }, + { + "id": "road-label", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 10, + "filter": [ + "all", + [ + "has", + "name" + ], + [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk", + "primary", + "secondary", + "tertiary" + ], + true, + false + ], + 12, + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk", + "primary", + "secondary", + "tertiary", + "street", + "street_limited", + "track" + ], + true, + false + ], + 15, + [ + "match", + [ + "get", + "class" + ], + [ + "path", + "pedestrian", + "golf", + "ferry", + "aerialway" + ], + false, + true + ] + ] + ], + "layout": { + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk", + "primary", + "secondary", + "tertiary" + ], + 10, + [ + "motorway_link", + "trunk_link", + "primary_link", + "secondary_link", + "tertiary_link", + "street", + "street_limited", + "track" + ], + 9, + 6.5 + ], + 18, + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk", + "primary", + "secondary", + "tertiary" + ], + 16, + [ + "motorway_link", + "trunk_link", + "primary_link", + "secondary_link", + "tertiary_link", + "street", + "street_limited", + "track" + ], + 14, + 13 + ] + ], + "text-max-angle": 30, + "text-font": [ + "DIN Pro Regular", + "Arial Unicode MS Regular" + ], + "symbol-placement": "line", + "text-padding": 1, + "text-rotation-alignment": "map", + "text-pitch-alignment": "viewport", + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-letter-spacing": 0.01 + }, + "paint": { + "text-color": "hsl(0,0%, 0%)", + "text-halo-color": [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + "hsla(60, 25%, 100%, 0.75)", + "hsl(60, 25%, 100%)" + ], + "text-halo-width": 1, + "text-halo-blur": 1 + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, road-labels" + } + }, + { + "id": "road-intersection", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 15, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "intersection" + ], + [ + "has", + "name" + ] + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "icon-image": "intersection", + "icon-text-fit": "both", + "icon-text-fit-padding": [ + 1, + 2, + 1, + 2 + ], + "text-size": [ + "interpolate", + [ + "exponential", + 1.2 + ], + [ + "zoom" + ], + 15, + 9, + 18, + 12 + ], + "text-font": [ + "DIN Pro Bold", + "Arial Unicode MS Bold" + ] + }, + "paint": { + "text-color": "hsl(230, 36%, 64%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, road-labels" + } + }, + { + "id": "road-number-shield", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 6, + "filter": [ + "all", + [ + "has", + "reflen" + ], + [ + "<=", + [ + "get", + "reflen" + ], + 6 + ], + [ + "match", + [ + "get", + "class" + ], + [ + "pedestrian", + "service" + ], + false, + true + ], + [ + "step", + [ + "zoom" + ], + [ + "==", + [ + "geometry-type" + ], + "Point" + ], + 11, + [ + ">", + [ + "get", + "len" + ], + 5000 + ], + 12, + [ + ">", + [ + "get", + "len" + ], + 2500 + ], + 13, + [ + ">", + [ + "get", + "len" + ], + 1000 + ], + 14, + true + ] + ], + "layout": { + "text-size": 9, + "icon-image": [ + "case", + [ + "has", + "shield_beta" + ], + [ + "coalesce", + [ + "image", + [ + "concat", + [ + "get", + "shield_beta" + ], + "-", + [ + "to-string", + [ + "get", + "reflen" + ] + ] + ] + ], + [ + "image", + [ + "concat", + "default-", + [ + "to-string", + [ + "get", + "reflen" + ] + ] + ] + ] + ], + [ + "concat", + [ + "get", + "shield" + ], + "-", + [ + "to-string", + [ + "get", + "reflen" + ] + ] + ] + ], + "icon-rotation-alignment": "viewport", + "text-max-angle": 38, + "symbol-spacing": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 11, + 400, + 14, + 600 + ], + "text-font": [ + "DIN Pro Bold", + "Arial Unicode MS Bold" + ], + "symbol-placement": [ + "step", + [ + "zoom" + ], + "point", + 11, + "line" + ], + "text-rotation-alignment": "viewport", + "text-field": [ + "get", + "ref" + ], + "text-letter-spacing": 0.05 + }, + "paint": { + "text-color": [ + "case", + [ + "all", + [ + "has", + "shield_text_color_beta" + ], + [ + "to-boolean", + [ + "coalesce", + [ + "image", + [ + "concat", + [ + "get", + "shield_beta" + ], + "-", + [ + "to-string", + [ + "get", + "reflen" + ] + ] + ] + ], + "" + ] + ] + ], + [ + "match", + [ + "get", + "shield_text_color_beta" + ], + "white", + "hsl(0, 0%, 100%)", + "yellow", + "hsl(50, 63%, 70%)", + "orange", + "hsl(25, 63%, 75%)", + "blue", + "hsl(230, 36%, 44%)", + "red", + "hsl(0, 54%, 59%)", + "green", + "hsl(140, 46%, 37%)", + "hsl(230, 11%, 13%)" + ], + [ + "match", + [ + "get", + "shield_text_color" + ], + "white", + "hsl(0, 0%, 100%)", + "yellow", + "hsl(50, 63%, 70%)", + "orange", + "hsl(25, 63%, 75%)", + "blue", + "hsl(230, 36%, 44%)", + "red", + "hsl(0, 54%, 59%)", + "green", + "hsl(140, 46%, 37%)", + "hsl(230, 11%, 13%)" + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, road-labels" + } + }, + { + "id": "road-exit-shield", + "type": "symbol", + "source": "composite", + "source-layer": "motorway_junction", + "minzoom": 14, + "filter": [ + "all", + [ + "has", + "reflen" + ], + [ + "<=", + [ + "get", + "reflen" + ], + 9 + ] + ], + "layout": { + "text-field": [ + "get", + "ref" + ], + "text-size": 9, + "icon-image": [ + "concat", + "motorway-exit-", + [ + "to-string", + [ + "get", + "reflen" + ] + ] + ], + "text-font": [ + "DIN Pro Bold", + "Arial Unicode MS Bold" + ] + }, + "paint": { + "text-color": "hsl(0, 0%, 100%)", + "text-translate": [ + 0, + 0 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, road-labels" + } + }, + { + "id": "path-pedestrian-label", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "case", + [ + "has", + "layer" + ], + [ + ">=", + [ + "get", + "layer" + ], + 0 + ], + true + ], + [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "pedestrian" + ], + true, + false + ], + 15, + [ + "match", + [ + "get", + "class" + ], + [ + "path", + "pedestrian" + ], + true, + false + ] + ] + ], + "layout": { + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + [ + "match", + [ + "get", + "class" + ], + "pedestrian", + 9, + 6.5 + ], + 18, + [ + "match", + [ + "get", + "class" + ], + "pedestrian", + 14, + 13 + ] + ], + "text-max-angle": 30, + "text-font": [ + "DIN Pro Regular", + "Arial Unicode MS Regular" + ], + "symbol-placement": "line", + "text-padding": 1, + "text-rotation-alignment": "map", + "text-pitch-alignment": "viewport", + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-letter-spacing": 0.01 + }, + "paint": { + "text-color": "hsl(0,0%, 0%)", + "text-halo-color": "hsl(60, 25%, 100%)", + "text-halo-width": 1, + "text-halo-blur": 1 + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., walking-cycling-labels" + } + }, + { + "id": "golf-hole-label", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "==", + [ + "get", + "class" + ], + "golf" + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "text-size": 12 + }, + "paint": { + "text-halo-color": "hsl(98, 60%, 55%)", + "text-halo-width": 0.5, + "text-halo-blur": 0.5, + "text-color": "hsl(100, 80%, 18%)" + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., walking-cycling-labels" + } + }, + { + "id": "ferry-aerialway-label", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 15, + "filter": [ + "match", + [ + "get", + "class" + ], + "aerialway", + true, + "ferry", + true, + false + ], + "layout": { + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 6.5, + 18, + 13 + ], + "text-max-angle": 30, + "text-font": [ + "DIN Pro Regular", + "Arial Unicode MS Regular" + ], + "symbol-placement": "line", + "text-padding": 1, + "text-rotation-alignment": "map", + "text-pitch-alignment": "viewport", + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-letter-spacing": 0.01 + }, + "paint": { + "text-color": [ + "match", + [ + "get", + "class" + ], + "ferry", + "hsl(205, 43%, 100%)", + "hsl(230, 50%, 60%)" + ], + "text-halo-color": [ + "match", + [ + "get", + "class" + ], + "ferry", + "hsl(205, 75%, 70%)", + "hsl(60, 20%, 100%)" + ], + "text-halo-width": 1, + "text-halo-blur": 1 + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, ferry-aerialway-labels" + } + }, + { + "id": "waterway-label", + "type": "symbol", + "source": "composite", + "source-layer": "natural_label", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "canal", + "river", + "stream", + "disputed_canal", + "disputed_river", + "disputed_stream" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "text-font": [ + "DIN Pro Italic", + "Arial Unicode MS Regular" + ], + "text-max-angle": 30, + "symbol-spacing": [ + "interpolate", + [ + "linear", + 1 + ], + [ + "zoom" + ], + 15, + 250, + 17, + 400 + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 13, + 12, + 18, + 18 + ], + "symbol-placement": "line", + "text-pitch-alignment": "viewport", + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] + }, + "paint": { + "text-color": "hsl(205, 43%, 90%)", + "text-halo-color": "hsla(60, 17%, 84%, 0.5)" + }, + "metadata": { + "mapbox:featureComponent": "natural-features", + "mapbox:group": "Natural features, natural-labels" + } + }, + { + "id": "natural-line-label", + "type": "symbol", + "metadata": { + "mapbox:featureComponent": "natural-features", + "mapbox:group": "Natural features, natural-labels" + }, + "source": "composite", + "source-layer": "natural_label", + "minzoom": 4, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "glacier", + "landform", + "disputed_glacier", + "disputed_landform" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false + ], + [ + "<=", + [ + "get", + "filterrank" + ], + 4 + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "text-size": [ + "step", + [ + "zoom" + ], + [ + "step", + [ + "get", + "sizerank" + ], + 18, + 5, + 12 + ], + 17, + [ + "step", + [ + "get", + "sizerank" + ], + 18, + 13, + 12 + ] + ], + "text-max-angle": 30, + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "symbol-placement": "line-center", + "text-pitch-alignment": "viewport" + }, + "paint": { + "text-halo-width": 0.5, + "text-halo-color": "hsl(60, 17%, 84%)", + "text-halo-blur": 0.5, + "text-color": "hsl(340, 10%, 38%)" + } + }, + { + "id": "natural-point-label", + "type": "symbol", + "source": "composite", + "source-layer": "natural_label", + "minzoom": 4, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "dock", + "glacier", + "landform", + "water_feature", + "wetland", + "disputed_dock", + "disputed_glacier", + "disputed_landform", + "disputed_water_feature", + "disputed_wetland" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false + ], + [ + "<=", + [ + "get", + "filterrank" + ], + 4 + ], + [ + "==", + [ + "geometry-type" + ], + "Point" + ] + ], + "layout": { + "text-size": [ + "step", + [ + "zoom" + ], + [ + "step", + [ + "get", + "sizerank" + ], + 18, + 5, + 12 + ], + 17, + [ + "step", + [ + "get", + "sizerank" + ], + 18, + 13, + 12 + ] + ], + "icon-image": [ + "get", + "maki" + ], + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "text-offset": [ + "step", + [ + "zoom" + ], + [ + "step", + [ + "get", + "sizerank" + ], + [ + "literal", + [ + 0, + 0 + ] + ], + 5, + [ + "literal", + [ + 0, + 0.8 + ] + ] + ], + 17, + [ + "step", + [ + "get", + "sizerank" + ], + [ + "literal", + [ + 0, + 0 + ] + ], + 13, + [ + "literal", + [ + 0, + 0.8 + ] + ] + ] + ], + "text-anchor": [ + "step", + [ + "zoom" + ], + [ + "step", + [ + "get", + "sizerank" + ], + "center", + 5, + "top" + ], + 17, + [ + "step", + [ + "get", + "sizerank" + ], + "center", + 13, + "top" + ] + ], + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] + }, + "paint": { + "icon-opacity": [ + "step", + [ + "zoom" + ], + [ + "step", + [ + "get", + "sizerank" + ], + 0, + 5, + 1 + ], + 17, + [ + "step", + [ + "get", + "sizerank" + ], + 0, + 13, + 1 + ] + ], + "text-halo-color": "hsl(60, 20%, 100%)", + "text-halo-width": 0.5, + "text-halo-blur": 0.5, + "text-color": "hsl(340, 10%, 38%)" + }, + "metadata": { + "mapbox:featureComponent": "natural-features", + "mapbox:group": "Natural features, natural-labels" + } + }, + { + "id": "water-line-label", + "type": "symbol", + "metadata": { + "mapbox:featureComponent": "natural-features", + "mapbox:group": "Natural features, natural-labels" + }, + "source": "composite", + "source-layer": "natural_label", + "minzoom": 1, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "bay", + "ocean", + "reservoir", + "sea", + "water", + "disputed_bay", + "disputed_ocean", + "disputed_reservoir", + "disputed_sea", + "disputed_water" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 0, + [ + "*", + [ + "-", + 16, + [ + "sqrt", + [ + "get", + "sizerank" + ] + ] + ], + 1 + ], + 22, + [ + "*", + [ + "-", + 22, + [ + "sqrt", + [ + "get", + "sizerank" + ] + ] + ], + 1 + ] + ], + "text-max-angle": 30, + "text-letter-spacing": [ + "match", + [ + "get", + "class" + ], + "ocean", + 0.25, + [ + "sea", + "bay" + ], + 0.15, + 0 + ], + "text-font": [ + "DIN Pro Italic", + "Arial Unicode MS Regular" + ], + "symbol-placement": "line-center", + "text-pitch-alignment": "viewport", + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] + }, + "paint": { + "text-color": [ + "match", + [ + "get", + "class" + ], + [ + "bay", + "ocean", + "sea" + ], + "hsl(205, 71%, 90%)", + "hsl(205, 43%, 90%)" + ], + "text-halo-color": "hsla(60, 17%, 84%, 0.5)" + } + }, + { + "id": "water-point-label", + "type": "symbol", + "source": "composite", + "source-layer": "natural_label", + "minzoom": 1, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "bay", + "ocean", + "reservoir", + "sea", + "water", + "disputed_bay", + "disputed_ocean", + "disputed_reservoir", + "disputed_sea", + "disputed_water" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false + ], + [ + "==", + [ + "geometry-type" + ], + "Point" + ] + ], + "layout": { + "text-line-height": 1.3, + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 0, + [ + "*", + [ + "-", + 16, + [ + "sqrt", + [ + "get", + "sizerank" + ] + ] + ], + 1 + ], + 22, + [ + "*", + [ + "-", + 22, + [ + "sqrt", + [ + "get", + "sizerank" + ] + ] + ], + 1 + ] + ], + "text-font": [ + "DIN Pro Italic", + "Arial Unicode MS Regular" + ], + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-letter-spacing": [ + "match", + [ + "get", + "class" + ], + "ocean", + 0.25, + [ + "bay", + "sea" + ], + 0.15, + 0.01 + ], + "text-max-width": [ + "match", + [ + "get", + "class" + ], + "ocean", + 4, + "sea", + 5, + [ + "bay", + "water" + ], + 7, + 10 + ] + }, + "paint": { + "text-color": [ + "match", + [ + "get", + "class" + ], + [ + "bay", + "ocean", + "sea" + ], + "hsl(205, 71%, 90%)", + "hsl(205, 43%, 90%)" + ], + "text-halo-color": "hsla(60, 17%, 84%, 0.5)" + }, + "metadata": { + "mapbox:featureComponent": "natural-features", + "mapbox:group": "Natural features, natural-labels" + } + }, + { + "id": "poi-label", + "type": "symbol", + "source": "composite", + "source-layer": "poi_label", + "minzoom": 6, + "filter": [ + "<=", + [ + "get", + "filterrank" + ], + [ + "+", + [ + "step", + [ + "zoom" + ], + 0, + 16, + 1, + 17, + 2 + ], + [ + "match", + [ + "get", + "class" + ], + "food_and_drink_stores", + 3, + "historic", + 3, + "landmark", + 3, + "medical", + 3, + "motorist", + 3, + "park_like", + 4, + "sport_and_leisure", + 4, + "visitor_amenities", + 4, + 2 + ] + ] + ], + "layout": { + "text-size": [ + "step", + [ + "zoom" + ], + [ + "step", + [ + "get", + "sizerank" + ], + 18, + 5, + 12 + ], + 17, + [ + "step", + [ + "get", + "sizerank" + ], + 18, + 13, + 12 + ] + ], + "icon-image": [ + "case", + [ + "has", + "maki_beta" + ], + [ + "coalesce", + [ + "image", + [ + "get", + "maki_beta" + ] + ], + [ + "image", + [ + "get", + "maki" + ] + ] + ], + [ + "image", + [ + "get", + "maki" + ] + ] + ], + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "text-offset": [ + "step", + [ + "zoom" + ], + [ + "step", + [ + "get", + "sizerank" + ], + [ + "literal", + [ + 0, + 0 + ] + ], + 5, + [ + "literal", + [ + 0, + 0.8 + ] + ] + ], + 17, + [ + "step", + [ + "get", + "sizerank" + ], + [ + "literal", + [ + 0, + 0 + ] + ], + 13, + [ + "literal", + [ + 0, + 0.8 + ] + ] + ] + ], + "text-anchor": [ + "step", + [ + "zoom" + ], + [ + "step", + [ + "get", + "sizerank" + ], + "center", + 5, + "top" + ], + 17, + [ + "step", + [ + "get", + "sizerank" + ], + "center", + 13, + "top" + ] + ], + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] + }, + "paint": { + "icon-opacity": [ + "step", + [ + "zoom" + ], + [ + "step", + [ + "get", + "sizerank" + ], + 0, + 5, + 1 + ], + 17, + [ + "step", + [ + "get", + "sizerank" + ], + 0, + 13, + 1 + ] + ], + "text-halo-color": "hsl(60, 20%, 100%)", + "text-halo-width": 0.5, + "text-halo-blur": 0.5, + "text-color": [ + "match", + [ + "get", + "class" + ], + "food_and_drink", + "hsl(35, 80%, 38%)", + "park_like", + "hsl(100, 80%, 18%)", + "education", + "hsl(30, 60%, 28%)", + "medical", + "hsl(10, 60%, 43%)", + "sport_and_leisure", + "hsl(210, 60%, 38%)", + "hsl(340, 10%, 38%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "point-of-interest-labels", + "mapbox:group": "Point of interest labels, poi-labels" + } + }, + { + "id": "transit-label", + "type": "symbol", + "source": "composite", + "source-layer": "transit_stop_label", + "minzoom": 12, + "filter": [ + "step", + [ + "zoom" + ], + [ + "all", + [ + "<=", + [ + "get", + "filterrank" + ], + 4 + ], + [ + "match", + [ + "get", + "mode" + ], + "rail", + true, + "metro_rail", + true, + false + ], + [ + "!=", + [ + "get", + "stop_type" + ], + "entrance" + ] + ], + 14, + [ + "all", + [ + "match", + [ + "get", + "mode" + ], + "rail", + true, + "metro_rail", + true, + false + ], + [ + "!=", + [ + "get", + "stop_type" + ], + "entrance" + ] + ], + 15, + [ + "all", + [ + "match", + [ + "get", + "mode" + ], + "rail", + true, + "metro_rail", + true, + "ferry", + true, + "light_rail", + true, + false + ], + [ + "!=", + [ + "get", + "stop_type" + ], + "entrance" + ] + ], + 16, + [ + "all", + [ + "match", + [ + "get", + "mode" + ], + "bus", + false, + true + ], + [ + "!=", + [ + "get", + "stop_type" + ], + "entrance" + ] + ], + 17, + [ + "!=", + [ + "get", + "stop_type" + ], + "entrance" + ], + 19, + true + ], + "layout": { + "text-size": 12, + "icon-image": [ + "get", + "network" + ], + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "text-justify": [ + "match", + [ + "get", + "stop_type" + ], + "entrance", + "left", + "center" + ], + "text-offset": [ + "match", + [ + "get", + "stop_type" + ], + "entrance", + [ + "literal", + [ + 1, + 0 + ] + ], + [ + "literal", + [ + 0, + 0.8 + ] + ] + ], + "text-anchor": [ + "match", + [ + "get", + "stop_type" + ], + "entrance", + "left", + "top" + ], + "text-field": [ + "step", + [ + "zoom" + ], + "", + 13, + [ + "match", + [ + "get", + "mode" + ], + [ + "rail", + "metro_rail" + ], + [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "" + ], + 14, + [ + "match", + [ + "get", + "mode" + ], + [ + "bus", + "bicycle" + ], + "", + [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] + ], + 18, + [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] + ], + "text-letter-spacing": 0.01, + "text-max-width": [ + "match", + [ + "get", + "stop_type" + ], + "entrance", + 15, + 9 + ] + }, + "paint": { + "text-halo-color": "hsl(60, 20%, 100%)", + "text-color": [ + "match", + [ + "get", + "network" + ], + "tokyo-metro", + "hsl(180, 30%, 30%)", + "mexico-city-metro", + "hsl(25, 63%, 63%)", + [ + "barcelona-metro", + "delhi-metro", + "hong-kong-mtr", + "milan-metro", + "osaka-subway" + ], + "hsl(0, 57%, 47%)", + [ + "boston-t", + "washington-metro" + ], + "hsl(230, 11%, 20%)", + [ + "chongqing-rail-transit", + "kiev-metro", + "singapore-mrt", + "taipei-metro" + ], + "hsl(140, 56%, 25%)", + "hsl(230, 50%, 60%)" + ], + "text-halo-blur": 0.5, + "text-halo-width": 0.5 + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, transit-labels" + } + }, + { + "id": "airport-label", + "type": "symbol", + "source": "composite", + "source-layer": "airport_label", + "minzoom": 8, + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "military", + "civil", + "disputed_military", + "disputed_civil" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false + ], + "layout": { + "text-line-height": 1.1, + "text-size": [ + "step", + [ + "get", + "sizerank" + ], + 18, + 9, + 12 + ], + "icon-image": [ + "get", + "maki" + ], + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "text-offset": [ + 0, + 0.8 + ], + "text-rotation-alignment": "viewport", + "text-anchor": "top", + "text-field": [ + "step", + [ + "get", + "sizerank" + ], + [ + "case", + [ + "has", + "ref" + ], + [ + "concat", + [ + "get", + "ref" + ], + " -\n", + [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] + ], + [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] + ], + 15, + [ + "get", + "ref" + ] + ], + "text-letter-spacing": 0.01, + "text-max-width": 9 + }, + "paint": { + "text-color": "hsl(230, 40%, 55%)", + "text-halo-color": "hsl(60, 20%, 100%)", + "text-halo-width": 1 + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, transit-labels" + } + }, + { + "id": "settlement-subdivision-label", + "type": "symbol", + "source": "composite", + "source-layer": "place_label", + "minzoom": 10, + "maxzoom": 15, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "settlement_subdivision", + "disputed_settlement_subdivision" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false + ], + [ + "<=", + [ + "get", + "filterrank" + ], + 3 + ] + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-transform": "uppercase", + "text-font": [ + "DIN Pro Regular", + "Arial Unicode MS Regular" + ], + "text-letter-spacing": [ + "match", + [ + "get", + "type" + ], + "suburb", + 0.15, + 0.05 + ], + "text-max-width": 7, + "text-padding": 3, + "text-size": [ + "interpolate", + [ + "cubic-bezier", + 0.5, + 0, + 1, + 1 + ], + [ + "zoom" + ], + 11, + [ + "match", + [ + "get", + "type" + ], + "suburb", + 11, + 10.5 + ], + 15, + [ + "match", + [ + "get", + "type" + ], + "suburb", + 15, + 14 + ] + ] + }, + "paint": { + "text-halo-color": "hsla(60, 25%, 100%, 0.75)", + "text-halo-width": 1, + "text-color": "hsl(230, 29%, 36%)", + "text-halo-blur": 0.5 + }, + "metadata": { + "mapbox:featureComponent": "place-labels", + "mapbox:group": "Place labels, place-labels" + } + }, + { + "id": "settlement-minor-label", + "type": "symbol", + "source": "composite", + "source-layer": "place_label", + "minzoom": 2, + "maxzoom": 13, + "filter": [ + "all", + [ + "<=", + [ + "get", + "filterrank" + ], + 3 + ], + [ + "match", + [ + "get", + "class" + ], + [ + "settlement", + "disputed_settlement" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false + ], + [ + "step", + [ + "zoom" + ], + [ + ">", + [ + "get", + "symbolrank" + ], + 6 + ], + 4, + [ + ">=", + [ + "get", + "symbolrank" + ], + 7 + ], + 6, + [ + ">=", + [ + "get", + "symbolrank" + ], + 8 + ], + 7, + [ + ">=", + [ + "get", + "symbolrank" + ], + 10 + ], + 10, + [ + ">=", + [ + "get", + "symbolrank" + ], + 11 + ], + 11, + [ + ">=", + [ + "get", + "symbolrank" + ], + 13 + ], + 12, + [ + ">=", + [ + "get", + "symbolrank" + ], + 15 + ] + ] + ], + "layout": { + "symbol-sort-key": [ + "get", + "symbolrank" + ], + "icon-image": [ + "step", + [ + "zoom" + ], + [ + "case", + [ + "==", + [ + "get", + "capital" + ], + 2 + ], + "border-dot-13", + [ + "step", + [ + "get", + "symbolrank" + ], + "dot-11", + 9, + "dot-10", + 11, + "dot-9" + ] + ], + 8, + "" + ], + "text-font": [ + "DIN Pro Regular", + "Arial Unicode MS Regular" + ], + "text-radial-offset": [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "capital" + ], + 2, + 0.6, + 0.55 + ], + 8, + 0 + ], + "text-anchor": [ + "step", + [ + "zoom" + ], + [ + "get", + "text_anchor" + ], + 8, + "center" + ], + "text-justify": "auto", + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-max-width": 7, + "text-line-height": 1.1, + "text-size": [ + "interpolate", + [ + "cubic-bezier", + 0.2, + 0, + 0.9, + 1 + ], + [ + "zoom" + ], + 3, + [ + "step", + [ + "get", + "symbolrank" + ], + 11, + 9, + 10 + ], + 6, + [ + "step", + [ + "get", + "symbolrank" + ], + 14, + 9, + 12, + 12, + 10 + ], + 8, + [ + "step", + [ + "get", + "symbolrank" + ], + 16, + 9, + 14, + 12, + 12, + 15, + 10 + ], + 13, + [ + "step", + [ + "get", + "symbolrank" + ], + 22, + 9, + 20, + 12, + 16, + 15, + 14 + ] + ] + }, + "paint": { + "text-color": "hsl(230, 29%, 0%)", + "text-halo-color": "hsl(60, 25%, 100%)", + "text-halo-width": 1, + "text-halo-blur": 1 + }, + "metadata": { + "mapbox:featureComponent": "place-labels", + "mapbox:group": "Place labels, place-labels" + } + }, + { + "id": "settlement-major-label", + "type": "symbol", + "source": "composite", + "source-layer": "place_label", + "minzoom": 2, + "maxzoom": 15, + "filter": [ + "all", + [ + "<=", + [ + "get", + "filterrank" + ], + 3 + ], + [ + "match", + [ + "get", + "class" + ], + [ + "settlement", + "disputed_settlement" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false + ], + [ + "step", + [ + "zoom" + ], + false, + 2, + [ + "<=", + [ + "get", + "symbolrank" + ], + 6 + ], + 4, + [ + "<", + [ + "get", + "symbolrank" + ], + 7 + ], + 6, + [ + "<", + [ + "get", + "symbolrank" + ], + 8 + ], + 7, + [ + "<", + [ + "get", + "symbolrank" + ], + 10 + ], + 10, + [ + "<", + [ + "get", + "symbolrank" + ], + 11 + ], + 11, + [ + "<", + [ + "get", + "symbolrank" + ], + 13 + ], + 12, + [ + "<", + [ + "get", + "symbolrank" + ], + 15 + ], + 13, + [ + ">=", + [ + "get", + "symbolrank" + ], + 11 + ], + 14, + [ + ">=", + [ + "get", + "symbolrank" + ], + 15 + ] + ] + ], + "layout": { + "symbol-sort-key": [ + "get", + "symbolrank" + ], + "icon-image": [ + "step", + [ + "zoom" + ], + [ + "case", + [ + "==", + [ + "get", + "capital" + ], + 2 + ], + "border-dot-13", + [ + "step", + [ + "get", + "symbolrank" + ], + "dot-11", + 9, + "dot-10", + 11, + "dot-9" + ] + ], + 8, + "" + ], + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "text-radial-offset": [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "capital" + ], + 2, + 0.6, + 0.55 + ], + 8, + 0 + ], + "text-anchor": [ + "step", + [ + "zoom" + ], + [ + "get", + "text_anchor" + ], + 8, + "center" + ], + "text-justify": [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "text_anchor" + ], + [ + "left", + "bottom-left", + "top-left" + ], + "left", + [ + "right", + "bottom-right", + "top-right" + ], + "right", + "center" + ], + 8, + "center" + ], + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-max-width": 7, + "text-line-height": 1.1, + "text-size": [ + "interpolate", + [ + "cubic-bezier", + 0.2, + 0, + 0.9, + 1 + ], + [ + "zoom" + ], + 3, + [ + "step", + [ + "get", + "symbolrank" + ], + 13, + 6, + 11 + ], + 6, + [ + "step", + [ + "get", + "symbolrank" + ], + 18, + 6, + 16, + 7, + 14 + ], + 8, + [ + "step", + [ + "get", + "symbolrank" + ], + 20, + 9, + 16, + 10, + 14 + ], + 15, + [ + "step", + [ + "get", + "symbolrank" + ], + 24, + 9, + 20, + 12, + 16, + 15, + 14 + ] + ] + }, + "paint": { + "text-color": "hsl(230, 29%, 0%)", + "text-halo-color": "hsl(60, 25%, 100%)", + "text-halo-width": 1, + "text-halo-blur": 1 + }, + "metadata": { + "mapbox:featureComponent": "place-labels", + "mapbox:group": "Place labels, place-labels" + } + }, + { + "id": "state-label", + "type": "symbol", + "source": "composite", + "source-layer": "place_label", + "minzoom": 3, + "maxzoom": 9, + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "state", + "disputed_state" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false + ], + "layout": { + "text-size": [ + "interpolate", + [ + "cubic-bezier", + 0.85, + 0.7, + 0.65, + 1 + ], + [ + "zoom" + ], + 4, + [ + "step", + [ + "get", + "symbolrank" + ], + 9, + 6, + 8, + 7, + 7 + ], + 9, + [ + "step", + [ + "get", + "symbolrank" + ], + 21, + 6, + 16, + 7, + 14 + ] + ], + "text-transform": "uppercase", + "text-font": [ + "DIN Pro Bold", + "Arial Unicode MS Bold" + ], + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-letter-spacing": 0.15, + "text-max-width": 6 + }, + "paint": { + "text-color": "hsl(230, 29%, 0%)", + "text-halo-color": "hsl(60, 25%, 100%)", + "text-halo-width": 1, + "text-opacity": 0.5 + }, + "metadata": { + "mapbox:featureComponent": "place-labels", + "mapbox:group": "Place labels, place-labels" + } + }, + { + "id": "country-label", + "type": "symbol", + "source": "composite", + "source-layer": "place_label", + "minzoom": 1, + "maxzoom": 10, + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "country", + "disputed_country" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false + ], + "layout": { + "icon-image": "", + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-line-height": 1.1, + "text-max-width": 6, + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "text-radial-offset": [ + "step", + [ + "zoom" + ], + 0.6, + 8, + 0 + ], + "text-justify": [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "text_anchor" + ], + [ + "left", + "bottom-left", + "top-left" + ], + "left", + [ + "right", + "bottom-right", + "top-right" + ], + "right", + "center" + ], + 7, + "auto" + ], + "text-size": [ + "interpolate", + [ + "cubic-bezier", + 0.2, + 0, + 0.7, + 1 + ], + [ + "zoom" + ], + 1, + [ + "step", + [ + "get", + "symbolrank" + ], + 11, + 4, + 9, + 5, + 8 + ], + 9, + [ + "step", + [ + "get", + "symbolrank" + ], + 22, + 4, + 19, + 5, + 17 + ] + ] + }, + "paint": { + "icon-opacity": [ + "step", + [ + "zoom" + ], + [ + "case", + [ + "has", + "text_anchor" + ], + 1, + 0 + ], + 7, + 0 + ], + "text-color": "hsl(230, 29%, 0%)", + "text-halo-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 2, + "hsla(60, 25%, 100%, 0.75)", + 3, + "hsl(60, 25%, 100%)" + ], + "text-halo-width": 1.25 + }, + "metadata": { + "mapbox:featureComponent": "place-labels", + "mapbox:group": "Place labels, place-labels" + } + }, + { + "id": "continent-label", + "type": "symbol", + "source": "composite", + "source-layer": "natural_label", + "minzoom": 0.75, + "maxzoom": 3, + "filter": [ + "==", + [ + "get", + "class" + ], + "continent" + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-line-height": 1.1, + "text-max-width": 6, + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "text-size": [ + "interpolate", + [ + "exponential", + 0.5 + ], + [ + "zoom" + ], + 0, + 10, + 2.5, + 15 + ], + "text-transform": "uppercase", + "text-letter-spacing": 0.05 + }, + "paint": { + "text-color": "hsl(230, 29%, 0%)", + "text-halo-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 0, + "hsla(60, 25%, 100%, 0.75)", + 3, + "hsl(60, 25%, 100%)" + ], + "text-halo-width": 1.5, + "text-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 0, + 0.8, + 1.5, + 0.5, + 2.5, + 0 + ] + }, + "metadata": { + "mapbox:featureComponent": "place-labels", + "mapbox:group": "Place labels, place-labels" + } + } + ], + "sources": { + "composite": { + "url": "mapbox://mapbox.mapbox-streets-v8,mapbox.mapbox-terrain-v2,mapbox.mapbox-bathymetry-v2", + "type": "vector" + } + }, + "created": "1970-01-01T00:00:00.000Z", + "modified": "1970-01-01T00:00:00.000Z", + "owner": "mapbox", + "id": "outdoors-v12", + "draft": false +} diff --git a/play-services-maps-core-mapbox/src/main/assets/style-microg-normal.json b/play-services-maps-core-mapbox/src/main/assets/style-microg-normal.json new file mode 100644 index 000000000..ed39d1b6c --- /dev/null +++ b/play-services-maps-core-mapbox/src/main/assets/style-microg-normal.json @@ -0,0 +1,2394 @@ +{ + "version": 8, + "name": "Mountain View Full", + "metadata": { + "mapbox:origin": "basic-template", + "mapbox:autocomposite": true, + "mapbox:type": "template", + "mapbox:sdk-support": { + "js": "0.50.0", + "android": "6.7.0", + "ios": "4.6.0" + }, + "mapbox:trackposition": false, + "mapbox:groups": { + "f51b507d2a17e572c70a5db74b0fec7e": { + "name": "Base", + "collapsed": false + }, + "3f48b8dc54ff2e6544b9ef9cedbf2990": { + "name": "Streets", + "collapsed": true + }, + "29bb589e8d1b9b402583363648b70302": { + "name": "Buildings", + "collapsed": true + }, + "3c26e9cbc75335c6f0ba8de5439cf1fa": { + "name": "Country borders", + "collapsed": true + }, + "7b44201d7f1682d99f7140188aff23ce": { + "name": "Labels", + "collapsed": true + }, + "24306bdccbff03e2ee08d5d1a4ca7312": { + "name": "Street name", + "collapsed": true + }, + "124a9d7a8e5226775d947c592110dfad": { + "name": "POI", + "collapsed": true + } + }, + "mapbox:uiParadigm": "layers" + }, + "center": [12.819420849458652, 50.03325860617235], + "zoom": 3.315829104862067, + "bearing": 0, + "pitch": 1.5, + "light": { + "intensity": 0.5, + "color": "hsl(0, 0%, 100%)", + "anchor": "viewport" + }, + "sources": { + "composite": { + "url": "mapbox://mapbox.mapbox-streets-v8,mapbox.mapbox-terrain-v2", + "type": "vector" + } + }, + "sprite": "mapbox://sprites/microg/cjui4020201oo1fmca7yuwbor/8fkcj5fgn4mftlzuak3guz1f9", + "glyphs": "mapbox://fonts/microg/{fontstack}/{range}.pbf", + "layers": [ + { + "id": "background", + "type": "background", + "layout": {}, + "paint": { + "background-color": [ + "interpolate", + ["linear"], + ["zoom"], + 4, + "hsl(43, 30%, 91%)", + 5, + "hsl(0, 0%, 96%)", + 8, + "hsl(0, 0%, 96%)", + 9, + "#efeee8", + 16, + "hsl(0, 0%, 95%)", + 18, + "#f8f9fb" + ] + } + }, + { + "id": "grass", + "type": "fill", + "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "source": "composite", + "source-layer": "landcover", + "filter": ["match", ["get", "class"], ["grass"], true, false], + "layout": {}, + "paint": { + "fill-color": [ + "interpolate", + ["linear"], + ["zoom"], + 9, + "hsl(124, 30%, 90%)", + 11, + "hsl(107, 30%, 94%)", + 12.5, + "hsl(107, 30%, 94%)", + 13.5, + "hsl(45, 12%, 93%)" + ] + } + }, + { + "id": "forrest", + "type": "fill", + "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "source": "composite", + "source-layer": "landcover", + "filter": [ + "match", + ["get", "class"], + ["wood", "scrub"], + true, + false + ], + "layout": {}, + "paint": { + "fill-color": [ + "interpolate", + ["linear"], + ["zoom"], + 9, + "hsl(124, 42%, 86%)", + 11, + "hsl(107, 47%, 94%)", + 12.5, + "hsl(107, 47%, 94%)", + 13.5, + "hsl(45, 12%, 93%)" + ] + } + }, + { + "id": "national_park", + "type": "fill", + "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "source": "composite", + "source-layer": "landuse_overlay", + "filter": [ + "match", + ["get", "class"], + ["national_park"], + true, + false + ], + "layout": {}, + "paint": {"fill-color": "hsl(106, 58%, 85%)"} + }, + { + "id": "snow", + "type": "fill", + "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "source": "composite", + "source-layer": "landcover", + "filter": ["match", ["get", "class"], ["snow"], true, false], + "layout": {}, + "paint": {"fill-color": "#f9fafc"} + }, + { + "id": "hillshade", + "type": "fill", + "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "source": "composite", + "source-layer": "hillshade", + "layout": {}, + "paint": { + "fill-opacity": [ + "interpolate", + ["linear"], + ["zoom"], + 9, + 0.03, + 13, + 0 + ] + } + }, + { + "id": "park", + "type": "fill", + "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "source": "composite", + "source-layer": "landuse", + "filter": [ + "match", + ["get", "class"], + ["park", "scrub"], + true, + false + ], + "layout": {}, + "paint": {"fill-color": "#c1ecaf"} + }, + { + "id": "pitch", + "type": "fill", + "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "source": "composite", + "source-layer": "landuse", + "filter": ["match", ["get", "class"], ["pitch"], true, false], + "layout": {}, + "paint": {"fill-color": "#c8efbb"} + }, + { + "id": "landuse", + "type": "fill", + "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "source": "composite", + "source-layer": "landuse", + "filter": [ + "match", + ["get", "class"], + ["airport", "school", "hospital"], + true, + false + ], + "layout": {}, + "paint": {"fill-color": "hsl(202, 26%, 94%)"} + }, + { + "id": "river", + "type": "fill", + "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "source": "composite", + "source-layer": "water", + "layout": {}, + "paint": {"fill-color": "hsl(206, 100%, 83%)"} + }, + { + "id": "path", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + ["match", ["get", "class"], ["path"], true, false], + ["match", ["get", "type"], ["platform", "steps"], false, true] + ], + "layout": {}, + "paint": { + "line-color": "hsl(118, 34%, 66%)", + "line-dasharray": [4, 2] + } + }, + { + "id": "steps", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + ["match", ["get", "class"], ["path"], true, false], + ["match", ["get", "type"], ["steps"], true, false] + ], + "layout": {}, + "paint": { + "line-color": "hsl(118, 5%, 66%)", + "line-dasharray": [1, 1], + "line-gap-width": 1 + } + }, + { + "id": "platform", + "type": "fill", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + ["match", ["get", "type"], ["platform"], true, false], + ["match", ["get", "structure"], ["tunnel"], false, true] + ], + "layout": {}, + "paint": { + "fill-color": [ + "interpolate", + ["linear"], + ["zoom"], + 15, + "hsl(2, 20%, 92%)", + 16, + "hsl(2, 95%, 92%)" + ], + "fill-outline-color": [ + "interpolate", + ["linear"], + ["zoom"], + 15, + "hsl(1, 10%, 76%)", + 16, + "hsl(1, 74%, 76%)" + ], + "fill-opacity": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 0, + 16, + 1 + ] + } + }, + { + "id": "primary_tunnel_border", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ + "match", + ["get", "class"], + ["primary_link", "primary", "motorway_link"], + true, + false + ], + ["match", ["get", "structure"], ["tunnel"], true, false] + ], + "layout": {}, + "paint": { + "line-gap-width": [ + "interpolate", + ["linear"], + ["zoom"], + 7, + 0, + 8, + 1, + 12, + 4, + 14, + 6, + 16, + 10, + 22, + 64 + ], + "line-color": "#cbcccd" + } + }, + { + "id": "primary_tunnel", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ + "match", + ["get", "class"], + ["primary_link", "primary", "motorway_link"], + true, + false + ], + ["match", ["get", "structure"], ["tunnel"], true, false] + ], + "layout": {}, + "paint": { + "line-width": [ + "interpolate", + ["linear"], + ["zoom"], + 8, + 1, + 12, + 4, + 14, + 6, + 16, + 10, + 22, + 64 + ], + "line-color": "hsl(0, 0%, 89%)" + } + }, + { + "id": "aeroway", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "aeroway", + "layout": {}, + "paint": {"line-color": "hsla(0, 0%, 0%, 0.1)"} + }, + { + "id": "service_road", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": ["match", ["get", "class"], ["service"], true, false], + "layout": {}, + "paint": {"line-color": "hsla(0, 0%, 0%, 0.1)"} + }, + { + "id": "pedestrian_border", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + ["match", ["get", "class"], ["pedestrian"], true, false], + ["has", "name"] + ], + "layout": {}, + "paint": { + "line-gap-width": [ + "interpolate", + ["linear"], + ["zoom"], + 13, + 1, + 16, + 4, + 22, + 32 + ], + "line-color": "#e3e3e3", + "line-opacity": [ + "interpolate", + ["linear"], + ["zoom"], + 12.5, + 0, + 13.5, + 1 + ] + } + }, + { + "id": "street_border", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": ["match", ["get", "class"], ["street"], true, false], + "layout": {}, + "paint": { + "line-gap-width": [ + "interpolate", + ["linear"], + ["zoom"], + 12, + 1, + 16, + 6, + 22, + 40 + ], + "line-color": "#e3e3e3" + } + }, + { + "id": "secondary_border", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "match", + ["get", "class"], + [ + "secondary", + "secondary_link", + "tertiary_link", + "tertiary", + "trunk_link", + "trunk" + ], + true, + false + ], + "layout": {}, + "paint": { + "line-gap-width": [ + "interpolate", + ["linear"], + ["zoom"], + 10, + 1, + 17, + 10, + 22, + 48 + ], + "line-color": "#e3e3e3", + "line-width": [ + "interpolate", + ["linear"], + ["zoom"], + 16, + 1, + 20, + 2 + ] + } + }, + { + "id": "primary_border", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ + "match", + ["get", "class"], + ["primary_link", "primary", "motorway_link"], + true, + false + ], + ["match", ["get", "structure"], ["tunnel"], false, true] + ], + "layout": {"line-cap": "round"}, + "paint": { + "line-gap-width": [ + "interpolate", + ["linear"], + ["zoom"], + 9, + 1, + 16, + 8, + 22, + 64 + ], + "line-color": "#ecd283" + } + }, + { + "id": "motorway_border", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": ["match", ["get", "class"], ["motorway"], true, false], + "layout": {}, + "paint": { + "line-gap-width": [ + "interpolate", + ["linear"], + ["zoom"], + 8, + 1, + 15.5, + 8, + 22, + 78 + ], + "line-color": "#ecd283", + "line-width": ["interpolate", ["linear"], ["zoom"], 8, 1, 15, 2] + } + }, + { + "id": "railway", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ + "match", + ["get", "class"], + ["major_rail", "minor_rail", "service_rail"], + true, + false + ], + ["match", ["get", "structure"], ["tunnel"], false, true] + ], + "layout": {}, + "paint": {"line-color": "hsl(220, 4%, 85%)"} + }, + { + "id": "pedestrian", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + ["match", ["get", "class"], ["pedestrian"], true, false], + ["has", "name"], + ["match", ["get", "type"], ["platform"], false, true] + ], + "layout": {}, + "paint": { + "line-color": "#ffffff", + "line-width": [ + "interpolate", + ["linear"], + ["zoom"], + 13, + 1, + 16, + 4, + 22, + 32 + ], + "line-opacity": [ + "interpolate", + ["linear"], + ["zoom"], + 12.5, + 0, + 13.5, + 1 + ] + } + }, + { + "id": "street", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": ["match", ["get", "class"], ["street"], true, false], + "layout": {}, + "paint": { + "line-color": "#ffffff", + "line-width": [ + "interpolate", + ["linear"], + ["zoom"], + 12, + 1, + 16, + 6, + 22, + 40 + ] + } + }, + { + "id": "secondary", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "match", + ["get", "class"], + [ + "secondary", + "secondary_link", + "trunk_link", + "tertiary", + "tertiary_link", + "trunk" + ], + true, + false + ], + "layout": {}, + "paint": { + "line-color": "#ffffff", + "line-width": [ + "interpolate", + ["linear"], + ["zoom"], + 10, + 1, + 17, + 10, + 22, + 48 + ] + } + }, + { + "id": "primary", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ + "match", + ["get", "class"], + ["primary_link", "primary", "motorway_link"], + true, + false + ], + ["match", ["get", "structure"], ["tunnel"], false, true] + ], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": [ + "step", + ["zoom"], + "hsl(50, 100%, 75%)", + 7, + "hsl(50, 100%, 85%)" + ], + "line-width": [ + "interpolate", + ["linear"], + ["zoom"], + 9, + 1, + 16, + 8, + 22, + 64 + ] + } + }, + { + "id": "motorway", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": ["match", ["get", "class"], ["motorway"], true, false], + "layout": {}, + "paint": { + "line-color": "#ffeba3", + "line-width": [ + "interpolate", + ["linear"], + ["zoom"], + 8, + 1, + 15.5, + 8, + 22, + 78 + ] + } + }, + { + "id": "primary_bridge_border", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ + "match", + ["get", "class"], + ["primary_link", "primary", "motorway_link"], + true, + false + ], + ["match", ["get", "structure"], ["bridge"], true, false] + ], + "layout": {}, + "paint": { + "line-gap-width": [ + "interpolate", + ["linear"], + ["zoom"], + 9, + 1, + 16, + 8, + 22, + 64 + ], + "line-color": "hsl(45, 73%, 72%)" + } + }, + { + "id": "primary_bridge", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ + "match", + ["get", "class"], + ["primary_link", "primary", "motorway_link"], + true, + false + ], + ["match", ["get", "structure"], ["bridge"], true, false] + ], + "layout": {}, + "paint": { + "line-color": [ + "step", + ["zoom"], + "hsl(50, 100%, 75%)", + 7, + "hsl(50, 100%, 85%)" + ], + "line-width": [ + "interpolate", + ["linear"], + ["zoom"], + 9, + 1, + 16, + 8, + 22, + 64 + ] + } + }, + { + "id": "building", + "type": "fill", + "metadata": {"mapbox:group": "29bb589e8d1b9b402583363648b70302"}, + "source": "composite", + "source-layer": "building", + "filter": ["match", ["get", "type"], ["roof"], false, true], + "layout": {}, + "paint": { + "fill-color": [ + "match", + ["get", "type"], + [ + "store", + "retail", + "church", + "kiosk", + "civic", + "hotel", + "supermarket", + "pub", + "dormitory" + ], + "hsl(33, 100%, 96%)", + "#ededed" + ], + "fill-opacity": [ + "interpolate", + ["linear"], + ["zoom"], + 15, + 0, + 17, + 1 + ] + } + }, + { + "id": "building_border", + "type": "line", + "metadata": {"mapbox:group": "29bb589e8d1b9b402583363648b70302"}, + "source": "composite", + "source-layer": "building", + "filter": ["match", ["get", "type"], ["roof"], false, true], + "layout": {}, + "paint": { + "line-color": [ + "match", + ["get", "type"], + [ + "store", + "retail", + "church", + "kiosk", + "civic", + "commercial", + "hotel", + "supermarket", + "pub" + ], + "#f8e1c7", + "#dcdcdc" + ], + "line-opacity": [ + "interpolate", + ["linear"], + ["zoom"], + 15, + 0, + 17, + 1 + ] + } + }, + { + "id": "building_3d", + "type": "fill-extrusion", + "metadata": {"mapbox:group": "29bb589e8d1b9b402583363648b70302"}, + "source": "composite", + "source-layer": "building", + "filter": ["match", ["get", "extrude"], ["true"], true, false], + "layout": {}, + "paint": { + "fill-extrusion-height": [ + "interpolate", + ["linear"], + ["zoom"], + 15, + 0, + 16, + ["get", "height"] + ], + "fill-extrusion-opacity": 0.3, + "fill-extrusion-color": "hsl(0, 0%, 93%)" + } + }, + { + "id": "admin_0", + "type": "line", + "metadata": {"mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa"}, + "source": "composite", + "source-layer": "admin", + "filter": [ + "all", + ["match", ["get", "maritime"], ["false"], true, false], + ["match", ["get", "admin_level"], [0], true, false] + ], + "layout": {}, + "paint": { + "line-color": [ + "case", + ["==", ["get", "disputed"], true], + "hsl(0, 24%, 48%)", + "#787a7b" + ] + } + }, + { + "id": "admin_1", + "type": "line", + "metadata": {"mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa"}, + "source": "composite", + "source-layer": "admin", + "filter": [ + "all", + ["match", ["get", "maritime"], ["false"], true, false], + ["match", ["get", "admin_level"], [1], true, false] + ], + "layout": {}, + "paint": { + "line-color": [ + "case", + ["==", ["get", "disputed"], true], + "hsl(0, 24%, 48%)", + "#787a7b" + ], + "line-dasharray": [1, 1] + } + }, + { + "id": "river_name", + "type": "symbol", + "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "source": "composite", + "source-layer": "natural_label", + "filter": ["match", ["get", "class"], ["river"], true, false], + "layout": { + "text-field": ["to-string", ["get", "name"]], + "symbol-placement": "line", + "symbol-spacing": 500, + "text-font": ["Roboto Regular"] + }, + "paint": { + "text-color": "#5083c1", + "text-halo-color": "#5083c1", + "text-halo-blur": 1 + } + }, + { + "id": "city_label_right", + "type": "symbol", + "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "source": "composite", + "source-layer": "place_label", + "maxzoom": 8, + "filter": [ + "all", + ["<=", ["get", "filterrank"], ["/", ["zoom"], 3]], + [ + "match", + ["get", "class"], + ["settlement", "settlement_subdivision"], + true, + false + ] + ], + "layout": { + "text-optional": true, + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 0, + ["-", 14, ["max", 0, ["-", ["get", "symbolrank"], 8]]], + 22, + ["-", 20, ["/", ["get", "symbolrank"], 4]] + ], + "icon-image": [ + "match", + ["get", "capital"], + [0, 2], + "capital", + "city" + ], + "text-font": [ + "step", + ["get", "symbolrank"], + ["literal", ["Roboto Medium"]], + 10, + ["literal", ["Roboto Regular"]] + ], + "text-justify": "left", + "text-offset": [0.5, 0.1], + "icon-size": ["/", 5, ["get", "symbolrank"]], + "text-anchor": "left", + "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]] + }, + "paint": { + "text-color": [ + "interpolate", + ["linear"], + ["zoom"], + 0, + [ + "concat", + "hsl(213, 11%, ", + ["+", ["*", ["get", "symbolrank"], 2], 5], + "%)" + ], + 22, + [ + "concat", + "hsl(213, 11%, ", + ["+", ["get", "symbolrank"], 25], + "%)" + ] + ], + "text-halo-width": 1, + "text-halo-blur": 1, + "text-halo-color": "hsl(0, 0%, 100%)", + "icon-opacity": 0.8 + } + }, + { + "id": "city_label_left", + "type": "symbol", + "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "source": "composite", + "source-layer": "place_label", + "maxzoom": 8, + "filter": [ + "all", + ["<=", ["get", "filterrank"], ["/", ["zoom"], 3]], + [ + "match", + ["get", "class"], + ["settlement", "settlement_subdivision"], + true, + false + ] + ], + "layout": { + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 0, + ["-", 14, ["max", 0, ["-", ["get", "symbolrank"], 8]]], + 22, + ["-", 20, ["/", ["get", "symbolrank"], 4]] + ], + "icon-image": [ + "match", + ["get", "capital"], + [0, 2], + "capital", + "city" + ], + "text-font": [ + "step", + ["get", "symbolrank"], + ["literal", ["Roboto Medium"]], + 10, + ["literal", ["Roboto Regular"]] + ], + "text-justify": "right", + "text-offset": [-0.5, 0.1], + "icon-size": ["/", 5, ["get", "symbolrank"]], + "text-anchor": "right", + "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]] + }, + "paint": { + "text-color": [ + "interpolate", + ["linear"], + ["zoom"], + 0, + [ + "concat", + "hsl(213, 11%, ", + ["+", ["*", ["get", "symbolrank"], 2], 5], + "%)" + ], + 22, + [ + "concat", + "hsl(213, 11%, ", + ["+", ["get", "symbolrank"], 25], + "%)" + ] + ], + "text-halo-width": 1, + "text-halo-blur": 1, + "text-halo-color": "hsl(0, 0%, 100%)", + "icon-opacity": 0.8 + } + }, + { + "id": "city_label_below", + "type": "symbol", + "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "source": "composite", + "source-layer": "place_label", + "maxzoom": 8, + "filter": [ + "all", + ["<=", ["get", "filterrank"], ["/", ["zoom"], 3]], + [ + "match", + ["get", "class"], + ["settlement", "settlement_subdivision"], + true, + false + ] + ], + "layout": { + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 0, + ["-", 14, ["max", 0, ["-", ["get", "symbolrank"], 8]]], + 22, + ["-", 20, ["/", ["get", "symbolrank"], 4]] + ], + "icon-image": [ + "match", + ["get", "capital"], + [0, 2], + "capital", + "city" + ], + "text-font": [ + "step", + ["get", "symbolrank"], + ["literal", ["Roboto Medium"]], + 10, + ["literal", ["Roboto Regular"]] + ], + "text-offset": [0, 0.4], + "icon-size": ["/", 5, ["get", "symbolrank"]], + "text-anchor": "top", + "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]] + }, + "paint": { + "text-color": [ + "interpolate", + ["linear"], + ["zoom"], + 0, + [ + "concat", + "hsl(213, 11%, ", + ["+", ["*", ["get", "symbolrank"], 2], 5], + "%)" + ], + 22, + [ + "concat", + "hsl(213, 11%, ", + ["+", ["get", "symbolrank"], 25], + "%)" + ] + ], + "text-halo-width": 1, + "text-halo-blur": 1, + "text-halo-color": "hsl(0, 0%, 100%)", + "icon-opacity": 0.8 + } + }, + { + "id": "city_name", + "type": "symbol", + "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "source": "composite", + "source-layer": "place_label", + "filter": [ + "all", + ["<=", ["get", "filterrank"], ["/", ["zoom"], 3]], + [ + "match", + ["get", "class"], + ["settlement", "settlement_subdivision"], + true, + false + ] + ], + "layout": { + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 0, + ["-", 14, ["max", 0, ["-", ["get", "symbolrank"], 8]]], + 22, + ["-", 20, ["/", ["get", "symbolrank"], 4]] + ], + "icon-image": [ + "step", + ["zoom"], + ["match", ["get", "capital"], [0, 2], "capital", "city"], + 8, + "" + ], + "text-transform": [ + "step", + ["get", "symbolrank"], + "none", + 15, + "uppercase" + ], + "text-font": [ + "step", + ["get", "symbolrank"], + ["literal", ["Roboto Medium"]], + 10, + ["literal", ["Roboto Regular"]] + ], + "text-offset": [ + "step", + ["zoom"], + ["literal", [0, -0.2]], + 8, + ["literal", [0, 0]] + ], + "icon-size": ["/", 5, ["get", "symbolrank"]], + "text-anchor": ["step", ["zoom"], "bottom", 8, "center"], + "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]], + "text-letter-spacing": [ + "interpolate", + ["linear"], + ["get", "symbolrank"], + 0, + 0, + 8, + 0, + 12, + 0.1, + 16, + 0.2 + ] + }, + "paint": { + "text-color": [ + "interpolate", + ["linear"], + ["zoom"], + 0, + [ + "concat", + "hsl(213, 11%, ", + ["+", ["*", ["get", "symbolrank"], 2], 5], + "%)" + ], + 22, + [ + "concat", + "hsl(213, 11%, ", + ["+", ["get", "symbolrank"], 25], + "%)" + ] + ], + "text-halo-width": 1, + "text-halo-blur": 1, + "text-halo-color": "hsl(0, 0%, 100%)", + "icon-opacity": 0.8 + } + }, + { + "id": "park_name", + "type": "symbol", + "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "source": "composite", + "source-layer": "poi_label", + "filter": [ + "all", + ["has", "name"], + ["match", ["get", "maki"], ["park", "cemetery"], true, false], + ["<=", ["get", "sizerank"], 10] + ], + "layout": { + "text-field": ["to-string", ["get", "name"]], + "text-font": ["Roboto Regular"], + "text-size": 14 + }, + "paint": { + "text-color": "#297925", + "text-halo-color": "hsl(0, 0%, 100%)", + "text-halo-width": 1, + "text-halo-blur": 1 + } + }, + { + "id": "road-number-shield", + "type": "symbol", + "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "source": "composite", + "source-layer": "road", + "filter": ["all", ["has", "ref"], ["<=", ["get", "reflen"], 6]], + "layout": { + "text-size": 9, + "icon-image": [ + "case", + [ + "match", + ["get", "shield"], + [ + "de-motorway", + "rectangle-green", + "rectangle-yellow", + "rectangle-white", + "rectangle-blue", + "rectangle-red", + "us-interstate" + ], + true, + false + ], + [ + "concat", + "shield_", + ["get", "shield"], + "_", + ["get", "reflen"] + ], + [ + "match", + ["get", "shield_text_color"], + ["white"], + true, + false + ], + ["concat", "shield_rectangle-blue_", ["get", "reflen"]], + ["concat", "shield_rectangle-white_", ["get", "reflen"]] + ], + "icon-rotation-alignment": "viewport", + "text-font": [ + "match", + ["get", "shield_text_color"], + ["white"], + ["literal", ["Roboto Bold"]], + ["black"], + ["literal", ["Roboto Medium"]], + ["literal", ["Roboto Bold"]] + ], + "symbol-placement": ["step", ["zoom"], "point", 11, "line"], + "text-offset": [0, 0.1], + "text-rotation-alignment": "viewport", + "icon-size": 0.75, + "text-field": ["get", "ref"], + "text-letter-spacing": 0.05 + }, + "paint": { + "text-color": [ + "case", + [ + "match", + ["get", "shield_text_color"], + ["white"], + true, + false + ], + "#ffffff", + [ + "match", + ["get", "shield_text_color"], + ["black"], + true, + false + ], + "hsl(0, 0%, 7%)", + [ + "match", + ["get", "shield_text_color"], + ["yellow"], + true, + false + ], + "hsl(50, 100%, 70%)", + [ + "match", + ["get", "shield_text_color"], + ["orange"], + true, + false + ], + "hsl(25, 100%, 75%)", + [ + "match", + ["get", "shield_text_color"], + ["blue"], + true, + false + ], + "hsl(230, 48%, 34%)", + "#ffffff" + ] + } + }, + { + "id": "country_name", + "type": "symbol", + "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "source": "composite", + "source-layer": "place_label", + "filter": ["match", ["get", "class"], ["country"], true, false], + "layout": { + "text-letter-spacing": [ + "interpolate", + ["linear"], + ["zoom"], + 1, + 0, + 3, + 0.15 + ], + "text-font": ["Roboto Medium"], + "text-size": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 1, + 12, + 7, + ["/", 100, ["get", "symbolrank"]] + ], + "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]] + }, + "paint": { + "text-color": "hsl(0, 0%, 10%)", + "text-halo-color": "hsl(0, 0%, 100%)", + "text-halo-width": 1, + "text-halo-blur": 1, + "text-opacity": [ + "interpolate", + ["linear"], + ["zoom"], + 6, + 1, + 7, + 0 + ] + } + }, + { + "id": "pedestrian_name", + "type": "symbol", + "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "all", + ["has", "name"], + ["match", ["get", "class"], ["pedestrian"], true, false], + ["match", ["get", "type"], ["platform"], false, true] + ], + "layout": { + "text-field": ["get", "name"], + "symbol-placement": "line", + "text-font": ["Roboto Regular"], + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 17, + 10, + 22, + 14 + ], + "text-padding": 5 + }, + "paint": { + "text-color": "#575757", + "text-halo-color": "#ffffff", + "text-halo-width": 1, + "text-halo-blur": 1 + } + }, + { + "id": "street_name", + "type": "symbol", + "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + ["has", "name"], + ["match", ["get", "class"], ["street"], true, false] + ], + "layout": { + "text-field": ["get", "name"], + "symbol-placement": "line", + "text-font": ["Roboto Regular"], + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 8, + 6, + 16, + 10 + ], + "text-padding": 5 + }, + "paint": { + "text-color": "#575757", + "text-halo-color": "#ffffff", + "text-halo-width": 1, + "text-halo-blur": 1 + } + }, + { + "id": "secondary_name", + "type": "symbol", + "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + ["has", "name"], + [ + "match", + ["get", "class"], + [ + "secondary", + "secondary_link", + "tertiary_link", + "tertiary", + "trunk_link", + "trunk" + ], + true, + false + ] + ], + "layout": { + "text-field": ["get", "name"], + "symbol-placement": "line", + "text-font": ["Roboto Regular"], + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 8, + 8, + 16, + 13 + ], + "symbol-spacing": 300, + "text-padding": 25 + }, + "paint": { + "text-color": "hsl(196, 0%, 34%)", + "text-halo-width": 1, + "text-halo-color": "#ffffff", + "text-halo-blur": 1 + } + }, + { + "id": "primary_name", + "type": "symbol", + "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + ["has", "name"], + [ + "match", + ["get", "class"], + ["primary", "primary_link"], + true, + false + ] + ], + "layout": { + "text-field": ["get", "name"], + "symbol-placement": "line", + "text-font": ["Roboto Regular"], + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 8, + 10, + 18, + 14 + ], + "symbol-spacing": 800, + "text-padding": 50 + }, + "paint": { + "text-color": "#6e481d", + "text-halo-width": 1, + "text-halo-color": "#ffffff", + "text-halo-blur": 1 + } + }, + { + "id": "poi_label_below", + "type": "symbol", + "metadata": {"mapbox:group": "124a9d7a8e5226775d947c592110dfad"}, + "source": "composite", + "source-layer": "poi_label", + "filter": [ + "all", + ["has", "name"], + ["<=", ["get", "filterrank"], ["/", ["zoom"], 3.5]], + [ + "!", + [ + "all", + [ + "match", + ["get", "maki"], + ["park", "cemetery"], + true, + false + ], + ["<=", ["get", "sizerank"], 10] + ] + ] + ], + "layout": { + "text-optional": true, + "text-line-height": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 1, + 15, + 1.2 + ], + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 13, + 15, + 14 + ], + "icon-offset": [0, -36], + "icon-image": [ + "match", + ["get", "maki"], + ["museum", "lodging", "theatre", "grocery", "restaurant"], + ["concat", "poi_", ["get", "maki"]], + [ + "fitness-centre", + "golf", + "campsite", + "bowling-alley", + "park", + "garden", + "farm", + "picnic-site", + "zoo", + "stadium", + "dog-park", + "pitch", + "cemetery" + ], + "poi_generic_green", + ["bank", "parking", "parking-garage"], + "poi_generic_purple", + ["bar", "cafe", "bakery"], + "poi_generic_orange", + [ + "alcohol-shop", + "shop", + "shoe", + "convenience", + "clothing-store", + "jewelry-store" + ], + "poi_generic_blue", + [ + "casino", + "castle", + "art-gallery", + "attraction", + "cinema", + "music", + "monument" + ], + "poi_generic_teal", + ["hospital", "doctor"], + "poi_generic_red", + [ + "restaurant-pizza", + "restaurant-seafood", + "restaurant-noodle", + "fast-food", + "ice-cream" + ], + "poi_restaurant", + "poi_generic" + ], + "text-font": ["Roboto Regular"], + "text-offset": [0, 0.5], + "icon-size": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 0.25, + 15, + 0.32 + ], + "text-anchor": "top", + "text-field": ["to-string", ["get", "name"]] + }, + "paint": { + "text-color": [ + "match", + ["get", "maki"], + [ + "museum", + "casino", + "castle", + "theatre", + "art-gallery", + "attraction", + "cinema", + "music", + "monument" + ], + "hsl(186, 78%, 44%)", + ["lodging"], + "#df7db1", + [ + "fitness-centre", + "golf", + "campsite", + "park", + "garden", + "farm", + "picnic-site", + "zoo", + "dog-park", + "stadium", + "bowling-alley", + "pitch", + "cemetery" + ], + "hsl(117, 53%, 31%)", + [ + "restaurant-pizza", + "restaurant-seafood", + "restaurant", + "restaurant-noodle", + "bar", + "cafe", + "fast-food", + "bakery", + "ice-cream" + ], + "#c77d57", + [ + "shop", + "shoe", + "alcohol-shop", + "convenience", + "grocery", + "clothing-store", + "jewelry-store" + ], + "hsl(213, 40%, 48%)", + ["bank", "parking", "parking-garage"], + "#737b9b", + ["hospital", "doctor"], + "#a47172", + "#67747b" + ], + "text-halo-color": "#ffffff", + "text-halo-width": 1, + "icon-translate": [0, 0], + "text-translate": [0, 0], + "text-halo-blur": 1 + } + }, + { + "id": "poi_label_above", + "type": "symbol", + "metadata": {"mapbox:group": "124a9d7a8e5226775d947c592110dfad"}, + "source": "composite", + "source-layer": "poi_label", + "filter": [ + "all", + ["has", "name"], + ["<=", ["get", "filterrank"], ["/", ["zoom"], 3.5]], + [ + "!", + [ + "all", + [ + "match", + ["get", "maki"], + ["park", "cemetery"], + true, + false + ], + ["<=", ["get", "sizerank"], 10] + ] + ] + ], + "layout": { + "text-optional": true, + "text-line-height": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 1, + 15, + 1.2 + ], + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 13, + 15, + 14 + ], + "icon-offset": [0, -36], + "icon-image": [ + "match", + ["get", "maki"], + ["museum", "lodging", "theatre", "grocery", "restaurant"], + ["concat", "poi_", ["get", "maki"]], + [ + "fitness-centre", + "golf", + "campsite", + "bowling-alley", + "park", + "garden", + "farm", + "picnic-site", + "zoo", + "stadium", + "dog-park", + "pitch", + "cemetery" + ], + "poi_generic_green", + ["bank", "parking", "parking-garage"], + "poi_generic_purple", + ["bar", "cafe", "bakery"], + "poi_generic_orange", + [ + "alcohol-shop", + "shop", + "shoe", + "convenience", + "clothing-store", + "jewelry-store" + ], + "poi_generic_blue", + [ + "casino", + "castle", + "art-gallery", + "attraction", + "cinema", + "music", + "monument" + ], + "poi_generic_teal", + ["hospital", "doctor"], + "poi_generic_red", + [ + "restaurant-pizza", + "restaurant-seafood", + "restaurant-noodle", + "fast-food", + "ice-cream" + ], + "poi_restaurant", + "poi_generic" + ], + "text-font": ["Roboto Regular"], + "text-offset": [0, -2], + "icon-size": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 0.25, + 15, + 0.32 + ], + "text-anchor": "bottom", + "text-field": ["to-string", ["get", "name"]] + }, + "paint": { + "text-color": [ + "match", + ["get", "maki"], + [ + "museum", + "casino", + "castle", + "theatre", + "art-gallery", + "attraction", + "cinema", + "music", + "monument" + ], + "hsl(186, 78%, 44%)", + ["lodging"], + "#df7db1", + [ + "fitness-centre", + "golf", + "campsite", + "park", + "garden", + "farm", + "picnic-site", + "zoo", + "dog-park", + "stadium", + "bowling-alley", + "pitch", + "cemetery" + ], + "hsl(117, 53%, 31%)", + [ + "restaurant-pizza", + "restaurant-seafood", + "restaurant", + "restaurant-noodle", + "bar", + "cafe", + "fast-food", + "bakery", + "ice-cream" + ], + "#c77d57", + [ + "shop", + "shoe", + "alcohol-shop", + "convenience", + "grocery", + "clothing-store", + "jewelry-store" + ], + "hsl(213, 40%, 48%)", + ["bank", "parking", "parking-garage"], + "#737b9b", + ["hospital", "doctor"], + "#a47172", + "#67747b" + ], + "text-halo-color": "#ffffff", + "text-halo-width": 1, + "icon-translate": [0, 0], + "text-translate": [0, 0], + "text-halo-blur": 1 + } + }, + { + "id": "poi_label_left", + "type": "symbol", + "metadata": {"mapbox:group": "124a9d7a8e5226775d947c592110dfad"}, + "source": "composite", + "source-layer": "poi_label", + "filter": [ + "all", + ["has", "name"], + ["<=", ["get", "filterrank"], ["/", ["zoom"], 3.5]], + [ + "!", + [ + "all", + [ + "match", + ["get", "maki"], + ["park", "cemetery"], + true, + false + ], + ["<=", ["get", "sizerank"], 10] + ] + ] + ], + "layout": { + "text-line-height": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 1, + 15, + 1.2 + ], + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 13, + 15, + 14 + ], + "icon-offset": [0, -36], + "icon-image": [ + "match", + ["get", "maki"], + ["museum", "lodging", "theatre", "grocery", "restaurant"], + ["concat", "poi_", ["get", "maki"]], + [ + "fitness-centre", + "golf", + "campsite", + "bowling-alley", + "park", + "garden", + "farm", + "picnic-site", + "zoo", + "stadium", + "dog-park", + "pitch", + "cemetery" + ], + "poi_generic_green", + ["bank", "parking", "parking-garage"], + "poi_generic_purple", + ["bar", "cafe", "bakery"], + "poi_generic_orange", + [ + "alcohol-shop", + "shop", + "shoe", + "convenience", + "clothing-store", + "jewelry-store" + ], + "poi_generic_blue", + [ + "casino", + "castle", + "art-gallery", + "attraction", + "cinema", + "music", + "monument" + ], + "poi_generic_teal", + ["hospital", "doctor"], + "poi_generic_red", + [ + "restaurant-pizza", + "restaurant-seafood", + "restaurant-noodle", + "fast-food", + "ice-cream" + ], + "poi_restaurant", + "poi_generic" + ], + "text-font": ["Roboto Regular"], + "text-justify": "right", + "text-offset": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + ["literal", [-1.1, -0.7]], + 15, + ["literal", [-1.1, -0.9]] + ], + "icon-size": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 0.25, + 15, + 0.32 + ], + "text-anchor": "right", + "text-field": ["to-string", ["get", "name"]] + }, + "paint": { + "text-color": [ + "match", + ["get", "maki"], + [ + "museum", + "casino", + "castle", + "theatre", + "art-gallery", + "attraction", + "cinema", + "music", + "monument" + ], + "hsl(186, 78%, 44%)", + ["lodging"], + "#df7db1", + [ + "fitness-centre", + "golf", + "campsite", + "park", + "garden", + "farm", + "picnic-site", + "zoo", + "dog-park", + "stadium", + "bowling-alley", + "pitch", + "cemetery" + ], + "hsl(117, 53%, 31%)", + [ + "restaurant-pizza", + "restaurant-seafood", + "restaurant", + "restaurant-noodle", + "bar", + "cafe", + "fast-food", + "bakery", + "ice-cream" + ], + "#c77d57", + [ + "shop", + "shoe", + "alcohol-shop", + "convenience", + "grocery", + "clothing-store", + "jewelry-store" + ], + "hsl(213, 40%, 48%)", + ["bank", "parking", "parking-garage"], + "#737b9b", + ["hospital", "doctor"], + "#a47172", + "#67747b" + ], + "text-halo-color": "#ffffff", + "text-halo-width": 1, + "icon-translate": [0, 0], + "text-translate": [0, 0], + "text-halo-blur": 1 + } + }, + { + "id": "poi_label_right", + "type": "symbol", + "metadata": {"mapbox:group": "124a9d7a8e5226775d947c592110dfad"}, + "source": "composite", + "source-layer": "poi_label", + "filter": [ + "all", + ["has", "name"], + ["<=", ["get", "filterrank"], ["/", ["zoom"], 3.5]], + [ + "!", + [ + "all", + [ + "match", + ["get", "maki"], + ["park", "cemetery"], + true, + false + ], + ["<=", ["get", "sizerank"], 10] + ] + ] + ], + "layout": { + "text-line-height": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 1, + 15, + 1.2 + ], + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 13, + 15, + 14 + ], + "icon-offset": [0, -36], + "icon-image": [ + "match", + ["get", "maki"], + ["museum", "lodging", "theatre", "grocery", "restaurant"], + ["concat", "poi_", ["get", "maki"]], + [ + "fitness-centre", + "golf", + "campsite", + "bowling-alley", + "park", + "garden", + "farm", + "picnic-site", + "zoo", + "stadium", + "dog-park", + "pitch", + "cemetery" + ], + "poi_generic_green", + ["bank", "parking", "parking-garage"], + "poi_generic_purple", + ["bar", "cafe", "bakery"], + "poi_generic_orange", + [ + "alcohol-shop", + "shop", + "shoe", + "convenience", + "clothing-store", + "jewelry-store" + ], + "poi_generic_blue", + [ + "casino", + "castle", + "art-gallery", + "attraction", + "cinema", + "music", + "monument" + ], + "poi_generic_teal", + ["hospital", "doctor"], + "poi_generic_red", + [ + "restaurant-pizza", + "restaurant-seafood", + "restaurant-noodle", + "fast-food", + "ice-cream" + ], + "poi_restaurant", + "poi_generic" + ], + "text-font": ["Roboto Regular"], + "text-justify": "left", + "text-offset": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + ["literal", [1.1, -0.7]], + 15, + ["literal", [1.1, -0.9]] + ], + "icon-size": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 0.25, + 15, + 0.32 + ], + "text-anchor": "left", + "text-field": ["to-string", ["get", "name"]] + }, + "paint": { + "text-color": [ + "match", + ["get", "maki"], + [ + "museum", + "casino", + "castle", + "theatre", + "art-gallery", + "attraction", + "cinema", + "music", + "monument" + ], + "hsl(186, 78%, 44%)", + ["lodging"], + "#df7db1", + [ + "fitness-centre", + "golf", + "campsite", + "park", + "garden", + "farm", + "picnic-site", + "zoo", + "dog-park", + "stadium", + "bowling-alley", + "pitch", + "cemetery" + ], + "hsl(117, 53%, 31%)", + [ + "restaurant-pizza", + "restaurant-seafood", + "restaurant", + "restaurant-noodle", + "bar", + "cafe", + "fast-food", + "bakery", + "ice-cream" + ], + "#c77d57", + [ + "shop", + "shoe", + "alcohol-shop", + "convenience", + "grocery", + "clothing-store", + "jewelry-store" + ], + "hsl(213, 40%, 48%)", + ["bank", "parking", "parking-garage"], + "#737b9b", + ["hospital", "doctor"], + "#a47172", + "#67747b" + ], + "text-halo-color": "#ffffff", + "text-halo-width": 1, + "icon-translate": [0, 0], + "text-translate": [0, 0], + "text-halo-blur": 1 + } + } + ], + "created": "2019-04-15T08:41:40.148Z", + "modified": "2020-09-05T19:42:03.856Z", + "id": "cjui4020201oo1fmca7yuwbor", + "owner": "microg", + "visibility": "public", + "protected": false, + "draft": false +} \ No newline at end of file diff --git a/play-services-maps-core-mapbox/src/main/assets/style-microg-satellite.json b/play-services-maps-core-mapbox/src/main/assets/style-microg-satellite.json new file mode 100644 index 000000000..b2a91277e --- /dev/null +++ b/play-services-maps-core-mapbox/src/main/assets/style-microg-satellite.json @@ -0,0 +1,2361 @@ +{ + "version": 8, + "name": "Mountain View Satellite", + "metadata": { + "mapbox:origin": "basic-template", + "mapbox:autocomposite": true, + "mapbox:type": "template", + "mapbox:sdk-support": { + "js": "0.50.0", + "android": "6.7.0", + "ios": "4.6.0" + }, + "mapbox:trackposition": false, + "mapbox:groups": { + "f51b507d2a17e572c70a5db74b0fec7e": { + "name": "Base", + "collapsed": true + }, + "3f48b8dc54ff2e6544b9ef9cedbf2990": { + "name": "Streets", + "collapsed": false + }, + "29bb589e8d1b9b402583363648b70302": { + "name": "Buildings", + "collapsed": true + }, + "3c26e9cbc75335c6f0ba8de5439cf1fa": { + "name": "Country borders", + "collapsed": true + }, + "7b44201d7f1682d99f7140188aff23ce": { + "name": "Labels", + "collapsed": true + }, + "24306bdccbff03e2ee08d5d1a4ca7312": { + "name": "Street name", + "collapsed": false + }, + "124a9d7a8e5226775d947c592110dfad": { + "name": "POI", + "collapsed": true + } + }, + "mapbox:uiParadigm": "layers" + }, + "center": [12.819420849458652, 50.03325860617235], + "zoom": 3.315829104862067, + "bearing": 0, + "pitch": 1.5, + "light": {"intensity": 0.5, "color": "hsl(0, 0%, 0%)"}, + "sources": { + "mapbox://mapbox.satellite": { + "url": "mapbox://mapbox.satellite", + "type": "raster", + "tileSize": 256 + }, + "composite": { + "url": "mapbox://mapbox.mapbox-streets-v8,mapbox.mapbox-terrain-v2", + "type": "vector" + } + }, + "sprite": "mapbox://sprites/microg/cjxgloted25ap1ct4uex7m6hi/8fkcj5fgn4mftlzuak3guz1f9", + "glyphs": "mapbox://fonts/microg/{fontstack}/{range}.pbf", + "layers": [ + { + "id": "background", + "type": "raster", + "source": "mapbox://mapbox.satellite", + "layout": {}, + "paint": {} + }, + { + "id": "forrest", + "type": "fill", + "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "source": "composite", + "source-layer": "landcover", + "filter": [ + "match", + ["get", "class"], + ["wood", "scrub"], + true, + false + ], + "layout": {"visibility": "none"}, + "paint": { + "fill-color": [ + "interpolate", + ["linear"], + ["zoom"], + 9, + "hsl(124, 42%, 86%)", + 11, + "hsl(107, 47%, 94%)", + 12.5, + "hsl(107, 47%, 94%)", + 13.5, + "hsl(45, 12%, 93%)" + ] + } + }, + { + "id": "national_park", + "type": "fill", + "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "source": "composite", + "source-layer": "landuse_overlay", + "filter": [ + "match", + ["get", "class"], + ["national_park"], + true, + false + ], + "layout": {"visibility": "none"}, + "paint": {"fill-color": "hsl(106, 58%, 85%)"} + }, + { + "id": "snow", + "type": "fill", + "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "source": "composite", + "source-layer": "landcover", + "filter": ["match", ["get", "class"], ["snow"], true, false], + "layout": {"visibility": "none"}, + "paint": {"fill-color": "#f9fafc"} + }, + { + "id": "hillshade", + "type": "fill", + "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "source": "composite", + "source-layer": "hillshade", + "layout": {"visibility": "none"}, + "paint": { + "fill-opacity": [ + "interpolate", + ["linear"], + ["zoom"], + 9, + 0.03, + 13, + 0 + ] + } + }, + { + "id": "park", + "type": "fill", + "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "source": "composite", + "source-layer": "landuse", + "filter": [ + "match", + ["get", "class"], + ["park", "scrub"], + true, + false + ], + "layout": {"visibility": "none"}, + "paint": {"fill-color": "#c1ecaf"} + }, + { + "id": "pitch", + "type": "fill", + "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "source": "composite", + "source-layer": "landuse", + "filter": ["match", ["get", "class"], ["pitch"], true, false], + "layout": {"visibility": "none"}, + "paint": {"fill-color": "#c8efbb"} + }, + { + "id": "landuse", + "type": "fill", + "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "source": "composite", + "source-layer": "landuse", + "filter": [ + "match", + ["get", "class"], + ["airport", "school", "hospital"], + true, + false + ], + "layout": {"visibility": "none"}, + "paint": {"fill-color": "hsl(202, 26%, 94%)"} + }, + { + "id": "river", + "type": "fill", + "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "source": "composite", + "source-layer": "water", + "layout": {"visibility": "none"}, + "paint": {"fill-color": "hsl(206, 100%, 83%)"} + }, + { + "id": "path", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + ["match", ["get", "class"], ["path"], true, false], + ["match", ["get", "type"], ["platform", "steps"], false, true] + ], + "layout": {}, + "paint": { + "line-color": "hsl(118, 34%, 66%)", + "line-dasharray": [4, 2], + "line-opacity": 0.3 + } + }, + { + "id": "steps", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + ["match", ["get", "class"], ["path"], true, false], + ["match", ["get", "type"], ["steps"], true, false] + ], + "layout": {}, + "paint": { + "line-color": "hsl(118, 5%, 66%)", + "line-dasharray": [1, 1], + "line-gap-width": 1, + "line-opacity": 0.3 + } + }, + { + "id": "platform", + "type": "fill", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": ["match", ["get", "type"], ["platform"], true, false], + "layout": {}, + "paint": { + "fill-color": [ + "interpolate", + ["linear"], + ["zoom"], + 15, + "hsl(2, 20%, 92%)", + 16, + "hsl(2, 95%, 92%)" + ], + "fill-outline-color": [ + "interpolate", + ["linear"], + ["zoom"], + 15, + "hsl(1, 10%, 76%)", + 16, + "hsl(1, 74%, 76%)" + ], + "fill-opacity": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 0, + 16, + 0.3 + ] + } + }, + { + "id": "primary_tunnel_border", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ + "match", + ["get", "class"], + ["primary_link", "primary", "motorway_link"], + true, + false + ], + ["match", ["get", "structure"], ["tunnel"], true, false] + ], + "layout": {"visibility": "none"}, + "paint": { + "line-gap-width": [ + "interpolate", + ["linear"], + ["zoom"], + 7, + 0, + 8, + 1, + 12, + 4, + 14, + 6, + 16, + 10, + 22, + 64 + ], + "line-color": "#cbcccd" + } + }, + { + "id": "primary_tunnel", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ + "match", + ["get", "class"], + ["primary_link", "primary", "motorway_link"], + true, + false + ], + ["match", ["get", "structure"], ["tunnel"], true, false] + ], + "layout": {}, + "paint": { + "line-width": [ + "interpolate", + ["linear"], + ["zoom"], + 8, + 1, + 12, + 4, + 14, + 6, + 16, + 10, + 22, + 64 + ], + "line-color": "hsl(0, 0%, 89%)", + "line-opacity": 0.3 + } + }, + { + "id": "aeroway", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "aeroway", + "layout": {}, + "paint": {"line-color": "hsla(0, 0%, 0%, 0.1)", "line-opacity": 0.3} + }, + { + "id": "service_road", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": ["match", ["get", "class"], ["service"], true, false], + "layout": {}, + "paint": {"line-color": "hsla(0, 0%, 0%, 0.1)", "line-opacity": 0.3} + }, + { + "id": "pedestrian_border", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + ["match", ["get", "class"], ["pedestrian"], true, false], + ["has", "name"] + ], + "layout": {"visibility": "none"}, + "paint": { + "line-gap-width": [ + "interpolate", + ["linear"], + ["zoom"], + 13, + 1, + 16, + 4, + 22, + 32 + ], + "line-color": "#e3e3e3", + "line-opacity": [ + "interpolate", + ["linear"], + ["zoom"], + 12.5, + 0, + 13.5, + 1 + ] + } + }, + { + "id": "street_border", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": ["match", ["get", "class"], ["street"], true, false], + "layout": {"visibility": "none"}, + "paint": { + "line-gap-width": [ + "interpolate", + ["linear"], + ["zoom"], + 12, + 1, + 16, + 6, + 22, + 40 + ], + "line-color": "#e3e3e3" + } + }, + { + "id": "secondary_border", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "match", + ["get", "class"], + [ + "secondary", + "secondary_link", + "tertiary_link", + "tertiary", + "trunk_link", + "trunk" + ], + true, + false + ], + "layout": {"visibility": "none"}, + "paint": { + "line-gap-width": [ + "interpolate", + ["linear"], + ["zoom"], + 10, + 1, + 17, + 10, + 22, + 48 + ], + "line-color": "#e3e3e3", + "line-width": [ + "interpolate", + ["linear"], + ["zoom"], + 16, + 1, + 20, + 2 + ] + } + }, + { + "id": "primary_border", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ + "match", + ["get", "class"], + ["primary_link", "primary", "motorway_link"], + true, + false + ], + ["match", ["get", "structure"], ["tunnel"], false, true] + ], + "layout": {"line-cap": "round", "visibility": "none"}, + "paint": { + "line-gap-width": [ + "interpolate", + ["linear"], + ["zoom"], + 9, + 1, + 16, + 8, + 22, + 64 + ], + "line-color": "#ecd283" + } + }, + { + "id": "motorway_border", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": ["match", ["get", "class"], ["motorway"], true, false], + "layout": {"visibility": "none"}, + "paint": { + "line-gap-width": [ + "interpolate", + ["linear"], + ["zoom"], + 8, + 1, + 15.5, + 8, + 22, + 78 + ], + "line-color": "#ecd283", + "line-width": ["interpolate", ["linear"], ["zoom"], 8, 1, 15, 2] + } + }, + { + "id": "railway", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "match", + ["get", "class"], + ["major_rail", "minor_rail", "service_rail"], + true, + false + ], + "layout": {}, + "paint": {"line-color": "hsl(220, 4%, 85%)", "line-opacity": 0.3} + }, + { + "id": "pedestrian", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + ["match", ["get", "class"], ["pedestrian"], true, false], + ["has", "name"], + ["match", ["get", "type"], ["platform"], false, true] + ], + "layout": {}, + "paint": { + "line-color": "hsl(0, 0%, 100%)", + "line-width": [ + "interpolate", + ["linear"], + ["zoom"], + 13, + 1, + 16, + 4, + 22, + 32 + ], + "line-opacity": [ + "interpolate", + ["linear"], + ["zoom"], + 12.5, + 0, + 13.5, + 0.3 + ] + } + }, + { + "id": "street", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": ["match", ["get", "class"], ["street"], true, false], + "layout": {}, + "paint": { + "line-color": "hsl(0, 0%, 100%)", + "line-width": [ + "interpolate", + ["linear"], + ["zoom"], + 12, + 1, + 16, + 6, + 22, + 40 + ], + "line-opacity": 0.3 + } + }, + { + "id": "secondary", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "match", + ["get", "class"], + [ + "secondary", + "secondary_link", + "trunk_link", + "tertiary", + "tertiary_link", + "trunk" + ], + true, + false + ], + "layout": {}, + "paint": { + "line-color": "hsl(0, 0%, 100%)", + "line-width": [ + "interpolate", + ["linear"], + ["zoom"], + 10, + 1, + 17, + 10, + 22, + 48 + ], + "line-opacity": 0.3 + } + }, + { + "id": "primary", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ + "match", + ["get", "class"], + ["primary_link", "primary", "motorway_link"], + true, + false + ], + ["match", ["get", "structure"], ["tunnel"], false, true] + ], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": [ + "step", + ["zoom"], + "hsl(50, 100%, 75%)", + 7, + "hsl(50, 100%, 85%)" + ], + "line-width": [ + "interpolate", + ["linear"], + ["zoom"], + 9, + 1, + 16, + 8, + 22, + 64 + ], + "line-opacity": 0.3 + } + }, + { + "id": "motorway", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": ["match", ["get", "class"], ["motorway"], true, false], + "layout": {}, + "paint": { + "line-color": "hsl(47, 100%, 82%)", + "line-width": [ + "interpolate", + ["linear"], + ["zoom"], + 8, + 1, + 15.5, + 8, + 22, + 78 + ], + "line-opacity": 0.3 + } + }, + { + "id": "primary_bridge_border", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ + "match", + ["get", "class"], + ["primary_link", "primary", "motorway_link"], + true, + false + ], + ["match", ["get", "structure"], ["bridge"], true, false] + ], + "layout": {"visibility": "none"}, + "paint": { + "line-gap-width": [ + "interpolate", + ["linear"], + ["zoom"], + 9, + 1, + 16, + 8, + 22, + 64 + ], + "line-color": "hsl(45, 73%, 72%)" + } + }, + { + "id": "primary_bridge", + "type": "line", + "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + [ + "match", + ["get", "class"], + ["primary_link", "primary", "motorway_link"], + true, + false + ], + ["match", ["get", "structure"], ["bridge"], true, false] + ], + "layout": {"visibility": "none"}, + "paint": { + "line-color": [ + "step", + ["zoom"], + "hsl(50, 100%, 75%)", + 7, + "hsl(50, 100%, 85%)" + ], + "line-width": [ + "interpolate", + ["linear"], + ["zoom"], + 9, + 1, + 16, + 8, + 22, + 64 + ] + } + }, + { + "id": "building", + "type": "fill", + "metadata": {"mapbox:group": "29bb589e8d1b9b402583363648b70302"}, + "source": "composite", + "source-layer": "building", + "filter": ["match", ["get", "type"], ["roof"], false, true], + "layout": {"visibility": "none"}, + "paint": { + "fill-color": [ + "match", + ["get", "type"], + [ + "store", + "retail", + "church", + "kiosk", + "civic", + "hotel", + "supermarket", + "pub", + "dormitory" + ], + "hsl(33, 100%, 96%)", + "#ededed" + ], + "fill-opacity": [ + "interpolate", + ["linear"], + ["zoom"], + 15, + 0, + 17, + 1 + ] + } + }, + { + "id": "building_border", + "type": "line", + "metadata": {"mapbox:group": "29bb589e8d1b9b402583363648b70302"}, + "source": "composite", + "source-layer": "building", + "filter": ["match", ["get", "type"], ["roof"], false, true], + "layout": {"visibility": "none"}, + "paint": { + "line-color": [ + "match", + ["get", "type"], + [ + "store", + "retail", + "church", + "kiosk", + "civic", + "commercial", + "hotel", + "supermarket", + "pub" + ], + "#f8e1c7", + "#dcdcdc" + ], + "line-opacity": [ + "interpolate", + ["linear"], + ["zoom"], + 15, + 0, + 17, + 1 + ] + } + }, + { + "id": "building_3d", + "type": "fill-extrusion", + "metadata": {"mapbox:group": "29bb589e8d1b9b402583363648b70302"}, + "source": "composite", + "source-layer": "building", + "filter": ["match", ["get", "extrude"], ["true"], true, false], + "layout": {"visibility": "none"}, + "paint": { + "fill-extrusion-height": [ + "interpolate", + ["linear"], + ["zoom"], + 15, + 0, + 16, + ["get", "height"] + ], + "fill-extrusion-color": "#ededed", + "fill-extrusion-opacity": 0.3 + } + }, + { + "id": "admin_0", + "type": "line", + "metadata": {"mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa"}, + "source": "composite", + "source-layer": "admin", + "filter": [ + "all", + ["match", ["get", "maritime"], ["false"], true, false], + ["match", ["get", "admin_level"], [0], true, false] + ], + "layout": {}, + "paint": { + "line-color": [ + "case", + ["==", ["get", "disputed"], true], + "hsl(0, 24%, 85%)", + "hsl(200, 1%, 85%)" + ] + } + }, + { + "id": "admin_1", + "type": "line", + "metadata": {"mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa"}, + "source": "composite", + "source-layer": "admin", + "filter": [ + "all", + ["match", ["get", "maritime"], ["false"], true, false], + ["match", ["get", "admin_level"], [1], true, false] + ], + "layout": {}, + "paint": { + "line-color": [ + "case", + ["==", ["get", "disputed"], true], + "hsl(0, 24%, 85%)", + "hsl(200, 1%, 85%)" + ], + "line-dasharray": [1, 1] + } + }, + { + "id": "river_name", + "type": "symbol", + "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "source": "composite", + "source-layer": "natural_label", + "filter": ["match", ["get", "class"], ["river"], true, false], + "layout": { + "text-field": ["to-string", ["get", "name"]], + "symbol-placement": "line", + "symbol-spacing": 500, + "text-font": ["Roboto Regular", "Arial Unicode MS Regular"] + }, + "paint": { + "text-color": "#5083c1", + "text-halo-color": "#5083c1", + "text-halo-blur": 1 + } + }, + { + "id": "city_label_right", + "type": "symbol", + "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "source": "composite", + "source-layer": "place_label", + "maxzoom": 8, + "filter": [ + "all", + ["<=", ["get", "filterrank"], ["/", ["zoom"], 4]], + [ + "match", + ["get", "class"], + ["settlement", "settlement_subdivision"], + true, + false + ] + ], + "layout": { + "text-optional": true, + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 0, + ["-", 14, ["max", 0, ["-", ["get", "symbolrank"], 8]]], + 22, + ["-", 20, ["/", ["get", "symbolrank"], 4]] + ], + "icon-image": [ + "match", + ["get", "capital"], + [0, 2], + "capital", + "city" + ], + "text-font": [ + "step", + ["get", "symbolrank"], + ["literal", ["Roboto Medium", "Arial Unicode MS Regular"]], + 10, + ["literal", ["Roboto Regular", "Arial Unicode MS Regular"]] + ], + "text-justify": "left", + "text-offset": [0.5, 0.1], + "icon-size": ["/", 5, ["get", "symbolrank"]], + "text-anchor": "left", + "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]] + }, + "paint": { + "text-color": [ + "interpolate", + ["linear"], + ["zoom"], + 0, + [ + "concat", + "hsl(213, 11%, ", + ["-", 100, ["*", ["get", "symbolrank"], 2]], + "%)" + ], + 22, + [ + "concat", + "hsl(213, 11%, ", + ["+", ["-", 100, ["get", "symbolrank"]], 5], + "%)" + ] + ], + "text-halo-width": 1, + "text-halo-blur": 1, + "icon-opacity": 0.8, + "text-halo-color": "hsl(0, 1%, 0%)" + } + }, + { + "id": "city_label_left", + "type": "symbol", + "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "source": "composite", + "source-layer": "place_label", + "maxzoom": 8, + "filter": [ + "all", + ["<=", ["get", "filterrank"], ["/", ["zoom"], 4]], + [ + "match", + ["get", "class"], + ["settlement", "settlement_subdivision"], + true, + false + ] + ], + "layout": { + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 0, + ["-", 14, ["max", 0, ["-", ["get", "symbolrank"], 8]]], + 22, + ["-", 20, ["/", ["get", "symbolrank"], 4]] + ], + "icon-image": [ + "match", + ["get", "capital"], + [0, 2], + "capital", + "city" + ], + "text-font": [ + "step", + ["get", "symbolrank"], + ["literal", ["Roboto Medium", "Arial Unicode MS Regular"]], + 10, + ["literal", ["Roboto Regular", "Arial Unicode MS Regular"]] + ], + "text-justify": "right", + "text-offset": [-0.5, 0.1], + "icon-size": ["/", 5, ["get", "symbolrank"]], + "text-anchor": "right", + "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]] + }, + "paint": { + "text-color": [ + "interpolate", + ["linear"], + ["zoom"], + 0, + [ + "concat", + "hsl(213, 11%, ", + ["-", 100, ["*", ["get", "symbolrank"], 2]], + "%)" + ], + 22, + [ + "concat", + "hsl(213, 11%, ", + ["+", ["-", 100, ["get", "symbolrank"]], 5], + "%)" + ] + ], + "text-halo-width": 1, + "text-halo-blur": 1, + "icon-opacity": 0.8, + "text-halo-color": "hsl(0, 1%, 0%)" + } + }, + { + "id": "city_label_below", + "type": "symbol", + "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "source": "composite", + "source-layer": "place_label", + "maxzoom": 8, + "filter": [ + "all", + ["<=", ["get", "filterrank"], ["/", ["zoom"], 4]], + [ + "match", + ["get", "class"], + ["settlement", "settlement_subdivision"], + true, + false + ] + ], + "layout": { + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 0, + ["-", 14, ["max", 0, ["-", ["get", "symbolrank"], 8]]], + 22, + ["-", 20, ["/", ["get", "symbolrank"], 4]] + ], + "icon-image": [ + "match", + ["get", "capital"], + [0, 2], + "capital", + "city" + ], + "text-font": [ + "step", + ["get", "symbolrank"], + ["literal", ["Roboto Medium", "Arial Unicode MS Regular"]], + 10, + ["literal", ["Roboto Regular", "Arial Unicode MS Regular"]] + ], + "text-offset": [0, 0.4], + "icon-size": ["/", 5, ["get", "symbolrank"]], + "text-anchor": "top", + "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]] + }, + "paint": { + "text-color": [ + "interpolate", + ["linear"], + ["zoom"], + 0, + [ + "concat", + "hsl(213, 11%, ", + ["-", 100, ["*", ["get", "symbolrank"], 2]], + "%)" + ], + 22, + [ + "concat", + "hsl(213, 11%, ", + ["+", ["-", 100, ["get", "symbolrank"]], 5], + "%)" + ] + ], + "text-halo-width": 1, + "text-halo-blur": 1, + "icon-opacity": 0.8, + "text-halo-color": "hsl(0, 1%, 0%)" + } + }, + { + "id": "city_name", + "type": "symbol", + "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "source": "composite", + "source-layer": "place_label", + "filter": [ + "all", + ["<=", ["get", "filterrank"], ["/", ["zoom"], 4]], + [ + "match", + ["get", "class"], + ["settlement", "settlement_subdivision"], + true, + false + ] + ], + "layout": { + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 0, + ["-", 14, ["max", 0, ["-", ["get", "symbolrank"], 8]]], + 22, + ["-", 20, ["/", ["get", "symbolrank"], 4]] + ], + "icon-image": [ + "step", + ["zoom"], + ["match", ["get", "capital"], [0, 2], "capital", "city"], + 8, + "" + ], + "text-transform": [ + "step", + ["get", "symbolrank"], + "none", + 15, + "uppercase" + ], + "text-font": [ + "step", + ["get", "symbolrank"], + ["literal", ["Roboto Medium", "Arial Unicode MS Regular"]], + 10, + ["literal", ["Roboto Regular", "Arial Unicode MS Regular"]] + ], + "text-offset": [ + "step", + ["zoom"], + ["literal", [0, -0.2]], + 8, + ["literal", [0, 0]] + ], + "icon-size": ["/", 5, ["get", "symbolrank"]], + "text-anchor": ["step", ["zoom"], "bottom", 8, "center"], + "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]], + "text-letter-spacing": [ + "interpolate", + ["linear"], + ["get", "symbolrank"], + 0, + 0, + 8, + 0, + 12, + 0.1, + 16, + 0.2 + ] + }, + "paint": { + "text-color": [ + "interpolate", + ["linear"], + ["zoom"], + 0, + [ + "concat", + "hsl(213, 11%, ", + ["-", 100, ["*", ["get", "symbolrank"], 2]], + "%)" + ], + 22, + [ + "concat", + "hsl(213, 11%, ", + ["+", ["-", 100, ["get", "symbolrank"]], 5], + "%)" + ] + ], + "text-halo-width": 1, + "text-halo-blur": 1, + "icon-opacity": 0.8, + "text-halo-color": "hsl(0, 1%, 0%)" + } + }, + { + "id": "park_name", + "type": "symbol", + "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "source": "composite", + "source-layer": "poi_label", + "filter": [ + "all", + ["has", "name"], + ["match", ["get", "maki"], ["park", "cemetery"], true, false], + ["<=", ["get", "sizerank"], 10] + ], + "layout": { + "text-field": ["to-string", ["get", "name"]], + "text-font": ["Roboto Regular", "Arial Unicode MS Regular"], + "text-size": 14 + }, + "paint": { + "text-color": "#297925", + "text-halo-color": "hsl(0, 0%, 100%)", + "text-halo-width": 1, + "text-halo-blur": 1 + } + }, + { + "id": "road-number-shield", + "type": "symbol", + "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "source": "composite", + "source-layer": "road", + "filter": ["all", ["has", "ref"], ["<=", ["get", "reflen"], 6]], + "layout": { + "text-size": 9, + "icon-image": [ + "case", + [ + "match", + ["get", "shield"], + [ + "de-motorway", + "rectangle-green", + "rectangle-yellow", + "rectangle-white", + "rectangle-blue", + "rectangle-red", + "us-interstate" + ], + true, + false + ], + [ + "concat", + "shield_", + ["get", "shield"], + "_", + ["get", "reflen"] + ], + [ + "match", + ["get", "shield_text_color"], + ["white"], + true, + false + ], + ["concat", "shield_rectangle-blue_", ["get", "reflen"]], + ["concat", "shield_rectangle-white_", ["get", "reflen"]] + ], + "icon-rotation-alignment": "viewport", + "text-font": [ + "match", + ["get", "shield_text_color"], + ["white"], + [ + "literal", + ["DIN Offc Pro Bold", "Arial Unicode MS Regular"] + ], + ["black"], + [ + "literal", + ["DIN Offc Pro Medium", "Arial Unicode MS Regular"] + ], + [ + "literal", + ["DIN Offc Pro Bold", "Arial Unicode MS Regular"] + ] + ], + "symbol-placement": ["step", ["zoom"], "point", 11, "line"], + "text-rotation-alignment": "viewport", + "icon-size": 0.75, + "text-field": ["get", "ref"], + "text-letter-spacing": 0.05 + }, + "paint": { + "text-color": [ + "case", + [ + "match", + ["get", "shield_text_color"], + ["white"], + true, + false + ], + "#ffffff", + [ + "match", + ["get", "shield_text_color"], + ["black"], + true, + false + ], + "hsl(0, 0%, 7%)", + [ + "match", + ["get", "shield_text_color"], + ["yellow"], + true, + false + ], + "hsl(50, 100%, 70%)", + [ + "match", + ["get", "shield_text_color"], + ["orange"], + true, + false + ], + "hsl(25, 100%, 75%)", + [ + "match", + ["get", "shield_text_color"], + ["blue"], + true, + false + ], + "hsl(230, 48%, 34%)", + "#ffffff" + ] + } + }, + { + "id": "country_name", + "type": "symbol", + "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "source": "composite", + "source-layer": "place_label", + "filter": ["match", ["get", "class"], ["country"], true, false], + "layout": { + "text-letter-spacing": [ + "interpolate", + ["linear"], + ["zoom"], + 1, + 0, + 3, + 0.15 + ], + "text-font": ["Roboto Medium", "Arial Unicode MS Regular"], + "text-size": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 1, + 12, + 7, + ["/", 100, ["get", "symbolrank"]] + ], + "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]] + }, + "paint": { + "text-opacity": [ + "interpolate", + ["linear"], + ["zoom"], + 6, + 1, + 7, + 0 + ], + "text-color": "hsl(0, 0%, 90%)", + "text-halo-width": 1, + "text-halo-blur": 1, + "text-halo-color": "hsl(0, 1%, 0%)" + } + }, + { + "id": "pedestrian_name", + "type": "symbol", + "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "all", + ["has", "name"], + ["match", ["get", "class"], ["pedestrian"], true, false], + ["match", ["get", "type"], ["platform"], false, true] + ], + "layout": { + "text-field": ["get", "name"], + "symbol-placement": "line", + "text-font": ["Roboto Regular", "Arial Unicode MS Regular"], + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 17, + 10, + 22, + 14 + ], + "text-padding": 5 + }, + "paint": { + "text-color": "hsl(0, 0%, 86%)", + "text-halo-color": "hsl(0, 1%, 0%)", + "text-halo-width": 1, + "text-halo-blur": 1 + } + }, + { + "id": "street_name", + "type": "symbol", + "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + ["has", "name"], + ["match", ["get", "class"], ["street"], true, false] + ], + "layout": { + "text-field": ["get", "name"], + "symbol-placement": "line", + "text-font": ["Roboto Regular", "Arial Unicode MS Regular"], + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 8, + 6, + 16, + 10 + ], + "text-padding": 5 + }, + "paint": { + "text-color": "hsl(0, 0%, 86%)", + "text-halo-color": "hsl(0, 1%, 0%)", + "text-halo-width": 1, + "text-halo-blur": 1 + } + }, + { + "id": "secondary_name", + "type": "symbol", + "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + ["has", "name"], + [ + "match", + ["get", "class"], + [ + "secondary", + "secondary_link", + "tertiary_link", + "tertiary", + "trunk_link", + "trunk" + ], + true, + false + ] + ], + "layout": { + "text-field": ["get", "name"], + "symbol-placement": "line", + "text-font": ["Roboto Regular", "Arial Unicode MS Regular"], + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 8, + 8, + 16, + 13 + ], + "symbol-spacing": 300, + "text-padding": 25 + }, + "paint": { + "text-color": "hsl(196, 0%, 86%)", + "text-halo-width": 1, + "text-halo-color": "hsl(0, 1%, 0%)", + "text-halo-blur": 1 + } + }, + { + "id": "primary_name", + "type": "symbol", + "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "source": "composite", + "source-layer": "road", + "filter": [ + "all", + ["has", "name"], + [ + "match", + ["get", "class"], + ["primary", "primary_link"], + true, + false + ] + ], + "layout": { + "text-field": ["get", "name"], + "symbol-placement": "line", + "text-font": ["Roboto Regular", "Arial Unicode MS Regular"], + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 8, + 10, + 18, + 14 + ], + "symbol-spacing": 800, + "text-padding": 50 + }, + "paint": { + "text-color": "hsl(32, 58%, 93%)", + "text-halo-width": 1, + "text-halo-color": "hsl(0, 1%, 0%)", + "text-halo-blur": 1 + } + }, + { + "id": "poi_label_below", + "type": "symbol", + "metadata": {"mapbox:group": "124a9d7a8e5226775d947c592110dfad"}, + "source": "composite", + "source-layer": "poi_label", + "filter": [ + "all", + ["has", "name"], + ["<=", ["get", "filterrank"], ["/", ["zoom"], 4]], + [ + "!", + [ + "all", + [ + "match", + ["get", "maki"], + ["park", "cemetery"], + true, + false + ], + ["<=", ["get", "sizerank"], 10] + ] + ] + ], + "layout": { + "text-optional": true, + "text-line-height": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 1, + 15, + 1.2 + ], + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 13, + 15, + 14 + ], + "icon-offset": [0, -36], + "icon-image": [ + "match", + ["get", "maki"], + ["museum", "lodging", "theatre", "grocery", "restaurant"], + ["concat", "poi_", ["get", "maki"]], + [ + "fitness-centre", + "golf", + "campsite", + "bowling-alley", + "park", + "garden", + "farm", + "picnic-site", + "zoo", + "stadium", + "dog-park", + "pitch", + "cemetery" + ], + "poi_generic_green", + ["bank", "parking", "parking-garage"], + "poi_generic_purple", + ["bar", "cafe", "bakery"], + "poi_generic_orange", + [ + "alcohol-shop", + "shop", + "shoe", + "convenience", + "clothing-store", + "jewelry-store" + ], + "poi_generic_blue", + [ + "casino", + "castle", + "art-gallery", + "attraction", + "cinema", + "music", + "monument" + ], + "poi_generic_teal", + ["hospital", "doctor"], + "poi_generic_red", + [ + "restaurant-pizza", + "restaurant-seafood", + "restaurant-noodle", + "fast-food", + "ice-cream" + ], + "poi_restaurant", + "poi_generic" + ], + "text-font": ["Roboto Regular", "Arial Unicode MS Regular"], + "text-offset": [0, 0.5], + "icon-size": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 0.25, + 15, + 0.32 + ], + "text-anchor": "top", + "text-field": ["to-string", ["get", "name"]] + }, + "paint": { + "text-color": [ + "match", + ["get", "maki"], + [ + "museum", + "casino", + "castle", + "theatre", + "art-gallery", + "attraction", + "cinema", + "music", + "monument" + ], + "hsl(186, 78%, 65%)", + ["lodging"], + "#df7db1", + [ + "fitness-centre", + "golf", + "campsite", + "park", + "garden", + "farm", + "picnic-site", + "zoo", + "dog-park", + "stadium", + "bowling-alley", + "pitch", + "cemetery" + ], + "hsl(117, 53%, 65%)", + [ + "restaurant-pizza", + "restaurant-seafood", + "restaurant", + "restaurant-noodle", + "bar", + "cafe", + "fast-food", + "bakery", + "ice-cream" + ], + "hsl(20, 50%, 65%)", + [ + "shop", + "shoe", + "alcohol-shop", + "convenience", + "grocery", + "clothing-store", + "jewelry-store" + ], + "hsl(213, 40%, 65%)", + ["bank", "parking", "parking-garage"], + "hsl(228, 17%, 65%)", + ["hospital", "doctor"], + "hsl(359, 22%, 65%)", + "hsl(201, 9%, 80%)" + ], + "text-halo-color": "hsl(0, 1%, 0%)", + "text-halo-width": 1, + "icon-translate": [0, 0], + "text-translate": [0, 0], + "text-halo-blur": 1 + } + }, + { + "id": "poi_label_above", + "type": "symbol", + "metadata": {"mapbox:group": "124a9d7a8e5226775d947c592110dfad"}, + "source": "composite", + "source-layer": "poi_label", + "filter": [ + "all", + ["has", "name"], + ["<=", ["get", "filterrank"], ["/", ["zoom"], 4]], + [ + "!", + [ + "all", + [ + "match", + ["get", "maki"], + ["park", "cemetery"], + true, + false + ], + ["<=", ["get", "sizerank"], 10] + ] + ] + ], + "layout": { + "text-optional": true, + "text-line-height": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 1, + 15, + 1.2 + ], + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 13, + 15, + 14 + ], + "icon-offset": [0, -36], + "icon-image": [ + "match", + ["get", "maki"], + ["museum", "lodging", "theatre", "grocery", "restaurant"], + ["concat", "poi_", ["get", "maki"]], + [ + "fitness-centre", + "golf", + "campsite", + "bowling-alley", + "park", + "garden", + "farm", + "picnic-site", + "zoo", + "stadium", + "dog-park", + "pitch", + "cemetery" + ], + "poi_generic_green", + ["bank", "parking", "parking-garage"], + "poi_generic_purple", + ["bar", "cafe", "bakery"], + "poi_generic_orange", + [ + "alcohol-shop", + "shop", + "shoe", + "convenience", + "clothing-store", + "jewelry-store" + ], + "poi_generic_blue", + [ + "casino", + "castle", + "art-gallery", + "attraction", + "cinema", + "music", + "monument" + ], + "poi_generic_teal", + ["hospital", "doctor"], + "poi_generic_red", + [ + "restaurant-pizza", + "restaurant-seafood", + "restaurant-noodle", + "fast-food", + "ice-cream" + ], + "poi_restaurant", + "poi_generic" + ], + "text-font": ["Roboto Regular", "Arial Unicode MS Regular"], + "text-offset": [0, -2], + "icon-size": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 0.25, + 15, + 0.32 + ], + "text-anchor": "bottom", + "text-field": ["to-string", ["get", "name"]] + }, + "paint": { + "text-color": [ + "match", + ["get", "maki"], + [ + "museum", + "casino", + "castle", + "theatre", + "art-gallery", + "attraction", + "cinema", + "music", + "monument" + ], + "hsl(186, 78%, 65%)", + ["lodging"], + "#df7db1", + [ + "fitness-centre", + "golf", + "campsite", + "park", + "garden", + "farm", + "picnic-site", + "zoo", + "dog-park", + "stadium", + "bowling-alley", + "pitch", + "cemetery" + ], + "hsl(117, 53%, 65%)", + [ + "restaurant-pizza", + "restaurant-seafood", + "restaurant", + "restaurant-noodle", + "bar", + "cafe", + "fast-food", + "bakery", + "ice-cream" + ], + "hsl(20, 50%, 65%)", + [ + "shop", + "shoe", + "alcohol-shop", + "convenience", + "grocery", + "clothing-store", + "jewelry-store" + ], + "hsl(213, 40%, 65%)", + ["bank", "parking", "parking-garage"], + "hsl(228, 17%, 65%)", + ["hospital", "doctor"], + "hsl(359, 22%, 65%)", + "hsl(201, 9%, 80%)" + ], + "text-halo-color": "hsl(0, 1%, 0%)", + "text-halo-width": 1, + "icon-translate": [0, 0], + "text-translate": [0, 0], + "text-halo-blur": 1 + } + }, + { + "id": "poi_label_left", + "type": "symbol", + "metadata": {"mapbox:group": "124a9d7a8e5226775d947c592110dfad"}, + "source": "composite", + "source-layer": "poi_label", + "filter": [ + "all", + ["has", "name"], + ["<=", ["get", "filterrank"], ["/", ["zoom"], 4]], + [ + "!", + [ + "all", + [ + "match", + ["get", "maki"], + ["park", "cemetery"], + true, + false + ], + ["<=", ["get", "sizerank"], 10] + ] + ] + ], + "layout": { + "text-line-height": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 1, + 15, + 1.2 + ], + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 13, + 15, + 14 + ], + "icon-offset": [0, -36], + "icon-image": [ + "match", + ["get", "maki"], + ["museum", "lodging", "theatre", "grocery", "restaurant"], + ["concat", "poi_", ["get", "maki"]], + [ + "fitness-centre", + "golf", + "campsite", + "bowling-alley", + "park", + "garden", + "farm", + "picnic-site", + "zoo", + "stadium", + "dog-park", + "pitch", + "cemetery" + ], + "poi_generic_green", + ["bank", "parking", "parking-garage"], + "poi_generic_purple", + ["bar", "cafe", "bakery"], + "poi_generic_orange", + [ + "alcohol-shop", + "shop", + "shoe", + "convenience", + "clothing-store", + "jewelry-store" + ], + "poi_generic_blue", + [ + "casino", + "castle", + "art-gallery", + "attraction", + "cinema", + "music", + "monument" + ], + "poi_generic_teal", + ["hospital", "doctor"], + "poi_generic_red", + [ + "restaurant-pizza", + "restaurant-seafood", + "restaurant-noodle", + "fast-food", + "ice-cream" + ], + "poi_restaurant", + "poi_generic" + ], + "text-font": ["Roboto Regular", "Arial Unicode MS Regular"], + "text-justify": "right", + "text-offset": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + ["literal", [-1.1, -0.7]], + 15, + ["literal", [-1.1, -0.9]] + ], + "icon-size": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 0.25, + 15, + 0.32 + ], + "text-anchor": "right", + "text-field": ["to-string", ["get", "name"]] + }, + "paint": { + "text-color": [ + "match", + ["get", "maki"], + [ + "museum", + "casino", + "castle", + "theatre", + "art-gallery", + "attraction", + "cinema", + "music", + "monument" + ], + "hsl(186, 78%, 65%)", + ["lodging"], + "#df7db1", + [ + "fitness-centre", + "golf", + "campsite", + "park", + "garden", + "farm", + "picnic-site", + "zoo", + "dog-park", + "stadium", + "bowling-alley", + "pitch", + "cemetery" + ], + "hsl(117, 53%, 65%)", + [ + "restaurant-pizza", + "restaurant-seafood", + "restaurant", + "restaurant-noodle", + "bar", + "cafe", + "fast-food", + "bakery", + "ice-cream" + ], + "hsl(20, 50%, 65%)", + [ + "shop", + "shoe", + "alcohol-shop", + "convenience", + "grocery", + "clothing-store", + "jewelry-store" + ], + "hsl(213, 40%, 65%)", + ["bank", "parking", "parking-garage"], + "hsl(228, 17%, 65%)", + ["hospital", "doctor"], + "hsl(359, 22%, 65%)", + "hsl(201, 9%, 80%)" + ], + "text-halo-color": "hsl(0, 1%, 0%)", + "text-halo-width": 1, + "icon-translate": [0, 0], + "text-translate": [0, 0], + "text-halo-blur": 1 + } + }, + { + "id": "poi_label_right", + "type": "symbol", + "metadata": {"mapbox:group": "124a9d7a8e5226775d947c592110dfad"}, + "source": "composite", + "source-layer": "poi_label", + "filter": [ + "all", + ["has", "name"], + ["<=", ["get", "filterrank"], ["/", ["zoom"], 4]], + [ + "!", + [ + "all", + [ + "match", + ["get", "maki"], + ["park", "cemetery"], + true, + false + ], + ["<=", ["get", "sizerank"], 10] + ] + ] + ], + "layout": { + "text-line-height": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 1, + 15, + 1.2 + ], + "text-size": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 13, + 15, + 14 + ], + "icon-offset": [0, -36], + "icon-image": [ + "match", + ["get", "maki"], + ["museum", "lodging", "theatre", "grocery", "restaurant"], + ["concat", "poi_", ["get", "maki"]], + [ + "fitness-centre", + "golf", + "campsite", + "bowling-alley", + "park", + "garden", + "farm", + "picnic-site", + "zoo", + "stadium", + "dog-park", + "pitch", + "cemetery" + ], + "poi_generic_green", + ["bank", "parking", "parking-garage"], + "poi_generic_purple", + ["bar", "cafe", "bakery"], + "poi_generic_orange", + [ + "alcohol-shop", + "shop", + "shoe", + "convenience", + "clothing-store", + "jewelry-store" + ], + "poi_generic_blue", + [ + "casino", + "castle", + "art-gallery", + "attraction", + "cinema", + "music", + "monument" + ], + "poi_generic_teal", + ["hospital", "doctor"], + "poi_generic_red", + [ + "restaurant-pizza", + "restaurant-seafood", + "restaurant-noodle", + "fast-food", + "ice-cream" + ], + "poi_restaurant", + "poi_generic" + ], + "text-font": ["Roboto Regular", "Arial Unicode MS Regular"], + "text-justify": "left", + "text-offset": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + ["literal", [1.1, -0.7]], + 15, + ["literal", [1.1, -0.9]] + ], + "icon-size": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + 0.25, + 15, + 0.32 + ], + "text-anchor": "left", + "text-field": ["to-string", ["get", "name"]] + }, + "paint": { + "text-color": [ + "match", + ["get", "maki"], + [ + "museum", + "casino", + "castle", + "theatre", + "art-gallery", + "attraction", + "cinema", + "music", + "monument" + ], + "hsl(186, 78%, 65%)", + ["lodging"], + "#df7db1", + [ + "fitness-centre", + "golf", + "campsite", + "park", + "garden", + "farm", + "picnic-site", + "zoo", + "dog-park", + "stadium", + "bowling-alley", + "pitch", + "cemetery" + ], + "hsl(117, 53%, 65%)", + [ + "restaurant-pizza", + "restaurant-seafood", + "restaurant", + "restaurant-noodle", + "bar", + "cafe", + "fast-food", + "bakery", + "ice-cream" + ], + "hsl(20, 50%, 65%)", + [ + "shop", + "shoe", + "alcohol-shop", + "convenience", + "grocery", + "clothing-store", + "jewelry-store" + ], + "hsl(213, 40%, 65%)", + ["bank", "parking", "parking-garage"], + "hsl(228, 17%, 65%)", + ["hospital", "doctor"], + "hsl(359, 22%, 65%)", + "hsl(201, 9%, 80%)" + ], + "text-halo-color": "hsl(0, 1%, 0%)", + "text-halo-width": 1, + "icon-translate": [0, 0], + "text-translate": [0, 0], + "text-halo-blur": 1 + } + } + ], + "created": "2019-06-28T21:20:23.628Z", + "modified": "2020-09-05T20:08:11.990Z", + "id": "cjxgloted25ap1ct4uex7m6hi", + "owner": "microg", + "visibility": "public", + "protected": false, + "draft": false +} \ No newline at end of file diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index 297dc873a..ded255746 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -130,6 +130,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) var tileId = 0L var storedMapType: Int = options.mapType + var mapStyle: MapStyleOptions? = null val waitingCameraUpdates = mutableListOf() var locationEnabled: Boolean = false @@ -247,6 +248,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) override fun setMapStyle(options: MapStyleOptions?): Boolean { Log.d(TAG, "setMapStyle options: " + options?.getJson()) + mapStyle = options return true } @@ -359,10 +361,10 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) override fun setMapType(type: Int) { storedMapType = type - applyMapType() + applyMapStyle() } - fun applyMapType() { + fun applyMapStyle() { val lines = lineManager?.annotations?.values() val fills = fillManager?.annotations?.values() val symbols = symbolManager?.annotations?.values() @@ -372,14 +374,10 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) symbols?.let { runCatching { symbolManager?.update(it) } } } - // TODO: Serve map styles locally - when (storedMapType) { - MAP_TYPE_SATELLITE -> map?.setStyle(Style.Builder().fromUri("mapbox://styles/microg/cjxgloted25ap1ct4uex7m6hi"), update) - MAP_TYPE_TERRAIN -> map?.setStyle(Style.Builder().fromUri("mapbox://styles/mapbox/outdoors-v12"), update) - MAP_TYPE_HYBRID -> map?.setStyle(Style.Builder().fromUri("mapbox://styles/microg/cjxgloted25ap1ct4uex7m6hi"), update) - //MAP_TYPE_NONE, MAP_TYPE_NORMAL, - else -> map?.setStyle(Style.Builder().fromUrl("mapbox://styles/microg/cjui4020201oo1fmca7yuwbor"), update) - } + map?.setStyle( + getStyle(MapContext(context), storedMapType, mapStyle), + update + ) map?.let { BitmapDescriptorFactoryImpl.registerMap(it) } @@ -681,7 +679,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) false } - applyMapType() + applyMapStyle() options.minZoomPreference?.let { if (it != 0f) map.setMinZoomPreference(it.toDouble()) } options.maxZoomPreference?.let { if (it != 0f) map.setMaxZoomPreference(it.toDouble()) } options.latLngBoundsForCameraTarget?.let { map.setLatLngBoundsForCameraTarget(it.toMapbox()) } diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt new file mode 100644 index 000000000..6942ef7ef --- /dev/null +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt @@ -0,0 +1,76 @@ +package org.microg.gms.maps.mapbox + +import androidx.annotation.FloatRange +import com.google.android.gms.maps.model.MapStyleOptions +import com.google.gson.Gson +import com.google.gson.JsonSyntaxException +import com.google.gson.annotations.SerializedName +import com.mapbox.mapboxsdk.maps.Style +import org.json.JSONObject +import org.microg.gms.maps.MapsConstants +import org.microg.gms.maps.mapbox.utils.MapContext + +const val TAG = "GmsMapStyles" + + +fun getStyle(context: MapContext, storedMapType: Int, styleOptions: MapStyleOptions?): Style.Builder { + + // TODO: Serve map style resources locally + val styleJson = JSONObject(context.assets.open( + when (storedMapType) { + MapsConstants.MAP_TYPE_SATELLITE, MapsConstants.MAP_TYPE_HYBRID -> "style-microg-satellite.json" + MapsConstants.MAP_TYPE_TERRAIN -> "style-mapbox-outdoors-v12.json" + //MAP_TYPE_NONE, MAP_TYPE_NORMAL, + else -> "style-microg-normal.json" + } + ).bufferedReader().readText()) + + styleOptions?.apply(styleJson) + + return Style.Builder().fromJson(styleJson.toString()) +} + +fun MapStyleOptions.apply(style: JSONObject) { + try { + Gson().fromJson(json, Array::class.java).let { styleOperations -> + + val layerArray = style.getJSONArray("layers") + for (i in 0 until layerArray.length()) { + val layer = layerArray.getJSONObject(i) + if (layer.has("metadata") && layer.getJSONObject("metadata") + .let { it.has("microg:gms-type-feature") && it.has("microg:gms-type-element") } + ) { + val featureType = layer.getJSONObject("metadata").getString("microg:gms-type-feature") + val elementType = layer.getJSONObject("metadata").getString("microg:gms-type-element") + + for (operation in styleOperations) { + if (operation.featureType?.startsWith(featureType) != false && // Todo: "all" here as well? + (operation.elementType?.startsWith(elementType) != false || operation.elementType == "all") + ) { + operation.stylers?.forEach { styler -> styler.apply(layer) } + } + } + } + } + } + + + } catch (e: JsonSyntaxException) { + e.printStackTrace() + } +} + +class StyleOperation(val featureType: String?, val elementType: String?, val stylers: Array?) + +class Styler( + val hue: String?, + @FloatRange(from = -100.0, to = 100.0) val saturation: Float?, + @FloatRange(from = -100.0, to = 100.0) val lightness: Float?, + @FloatRange(from = 0.01, to = 10.0) val gamma: Float?, + @SerializedName("invert_lightness") val invertLightness: Boolean?, + val visibility: String?, + val color: String?, + val weight: Int? +) + +fun Styler.apply(layer: JSONObject) { TODO() } \ No newline at end of file -- GitLab From 00323fd2d72253aa2f8a15caf767146ebbfab63b Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Mon, 6 Mar 2023 12:12:08 +0100 Subject: [PATCH 22/38] Uniform formatting in styles json `jq --indent 4` --- .../assets/style-mapbox-outdoors-v12.json | 26906 ++++++++-------- .../src/main/assets/style-microg-normal.json | 2842 +- .../main/assets/style-microg-satellite.json | 2886 +- 3 files changed, 18225 insertions(+), 14409 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/assets/style-mapbox-outdoors-v12.json b/play-services-maps-core-mapbox/src/main/assets/style-mapbox-outdoors-v12.json index 4924428b8..e022a2916 100644 --- a/play-services-maps-core-mapbox/src/main/assets/style-mapbox-outdoors-v12.json +++ b/play-services-maps-core-mapbox/src/main/assets/style-mapbox-outdoors-v12.json @@ -1,13549 +1,13549 @@ { - "name": "Mapbox Outdoors", - "sprite": "mapbox://sprites/mapbox/outdoors-v12", - "glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf", - "center": [ - 9.1, - 42.2 - ], - "zoom": 7.5, - "fog": { - "range": [ - 1, - 20 + "name": "Mapbox Outdoors", + "sprite": "mapbox://sprites/mapbox/outdoors-v12", + "glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf", + "center": [ + 9.1, + 42.2 ], - "color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 4, - "hsl(200, 100%, 100%)", - 6, - "hsl(200, 50%, 90%)" - ], - "high-color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 4, - "hsl(200, 100%, 60%)", - 6, - "hsl(310, 60%, 80%)" - ], - "space-color": [ - "interpolate", - [ - "exponential", - 1.2 - ], - [ - "zoom" - ], - 4, - "hsl(205, 10%, 10%)", - 6, - "hsl(205, 60%, 50%)" - ], - "horizon-blend": [ - "interpolate", - [ - "exponential", - 1.2 - ], - [ - "zoom" - ], - 4, - 0.01, - 6, - 0.1 - ], - "star-intensity": [ - "interpolate", - [ - "exponential", - 1.2 - ], - [ - "zoom" - ], - 4, - 0.1, - 6, - 0 - ] - }, - "projection": { - "name": "globe" - }, - "visibility": "public", - "version": 8, - "layers": [ - { - "id": "land", - "type": "background", - "layout": {}, - "minzoom": 0, - "paint": { - "background-color": "hsl(60, 20%, 85%)" - }, - "metadata": { - "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, land" - } - }, - { - "id": "landcover", - "type": "fill", - "source": "composite", - "source-layer": "landcover", - "minzoom": 0, - "maxzoom": 12, - "layout": {}, - "paint": { - "fill-color": [ - "match", - [ - "get", - "class" - ], - "wood", - "hsla(103, 50%, 60%, 0.8)", - "scrub", - "hsla(98, 47%, 68%, 0.6)", - "crop", - "hsla(68, 55%, 70%, 0.6)", - "grass", - "hsla(98, 50%, 74%, 0.6)", - "snow", - "hsl(205, 45%, 95%)", - "hsl(98, 48%, 67%)" - ], - "fill-opacity": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 8, - 0.8, - 12, - 0 - ], - "fill-antialias": false - }, - "metadata": { - "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, land" - } - }, - { - "id": "national-park", - "type": "fill", - "source": "composite", - "source-layer": "landuse_overlay", - "minzoom": 5, - "filter": [ - "==", - [ - "get", - "class" - ], - "national_park" - ], - "layout": {}, - "paint": { - "fill-color": "hsl(98, 38%, 68%)", - "fill-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 5, - 0, - 6, - 0.6, - 12, - 0.2 - ] - }, - "metadata": { - "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, land" - } - }, - { - "id": "national-park_tint-band", - "type": "line", - "source": "composite", - "source-layer": "landuse_overlay", - "minzoom": 9, - "filter": [ - "==", - [ - "get", - "class" - ], - "national_park" - ], - "layout": {}, - "paint": { - "line-color": "hsl(98, 38%, 68%)", - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 9, - 1, - 14, - 8 - ], - "line-blur": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 9, - 1, - 14, - 8 - ] - }, - "metadata": { - "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, land" - } - }, - { - "id": "landuse", - "type": "fill", - "source": "composite", - "source-layer": "landuse", - "minzoom": 5, - "filter": [ - "all", - [ - ">=", - [ - "to-number", - [ - "get", - "sizerank" - ] - ], - 0 - ], - [ - "match", - [ - "get", - "class" - ], - [ - "agriculture", - "wood", - "grass", - "scrub", - "glacier", - "pitch", - "sand" - ], - [ - "step", - [ - "zoom" - ], - false, - 11, - true - ], - "residential", - [ - "step", - [ - "zoom" - ], - true, - 10, - false - ], - [ - "park", - "airport" - ], - [ - "step", - [ - "zoom" - ], - false, - 8, - [ - "case", - [ - "==", - [ - "get", - "sizerank" - ], - 1 - ], - true, - false - ], - 10, - true - ], - [ - "facility", - "industrial" - ], - [ - "step", - [ - "zoom" - ], - false, - 12, - true - ], - "rock", - [ - "step", - [ - "zoom" - ], - false, - 11, - true - ], - "cemetery", - [ - "step", - [ - "zoom" - ], - false, - 11, - true - ], - "school", - [ - "step", - [ - "zoom" - ], - false, - 11, - true - ], - "hospital", - [ - "step", - [ - "zoom" - ], - false, - 11, - true - ], - "commercial_area", - [ - "step", - [ - "zoom" - ], - false, - 11, - true - ], - false + "zoom": 7.5, + "fog": { + "range": [ + 1, + 20 ], - [ - "<=", - [ - "-", + "color": [ + "interpolate", [ - "to-number", - [ - "get", - "sizerank" - ] + "linear" ], [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ "zoom" - ], - 12, - 0, - 18, - 14 - ] - ], - 14 - ] - ], - "layout": {}, - "paint": { - "fill-color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 15, - [ - "match", - [ - "get", - "class" - ], - "wood", - "hsla(103, 50%, 60%, 0.8)", - "scrub", - "hsla(98, 47%, 68%, 0.6)", - "agriculture", - "hsla(98, 50%, 74%, 0.6)", - "park", - [ - "match", - [ - "get", - "type" - ], - [ - "garden", - "playground", - "zoo" - ], - "hsl(98, 38%, 68%)", - "hsl(98, 55%, 70%)" - ], - "grass", - "hsla(98, 50%, 74%, 0.6)", - "airport", - "hsl(230, 40%, 82%)", - "cemetery", - "hsl(98, 45%, 75%)", - "glacier", - "hsl(205, 45%, 95%)", - "hospital", - "hsl(20, 45%, 82%)", - "pitch", - "hsl(88, 65%, 75%)", - "sand", - "hsl(69, 60%, 72%)", - "rock", - "hsl(60, 0%, 85%)", - "school", - "hsl(40, 45%, 78%)", - "commercial_area", - "hsl(55, 45%, 85%)", - "residential", - "hsl(60, 7%, 87%)", - [ - "facility", - "industrial" - ], - "hsl(230, 20%, 85%)", - "hsl(60, 22%, 72%)" - ], - 16, - [ - "match", - [ - "get", - "class" - ], - "wood", - "hsla(103, 50%, 60%, 0.8)", - "scrub", - "hsla(98, 47%, 68%, 0.6)", - "agriculture", - "hsla(98, 50%, 74%, 0.6)", - "park", - [ - "match", - [ - "get", - "type" - ], - [ - "garden", - "playground", - "zoo" - ], - "hsl(98, 38%, 68%)", - "hsl(98, 55%, 70%)" - ], - "grass", - "hsla(98, 50%, 74%, 0.6)", - "airport", - "hsl(230, 40%, 82%)", - "cemetery", - "hsl(98, 45%, 75%)", - "glacier", - "hsl(205, 45%, 95%)", - "hospital", - "hsl(20, 45%, 82%)", - "pitch", - "hsl(88, 65%, 75%)", - "sand", - "hsl(69, 60%, 72%)", - "rock", - "hsla(60, 0%, 85%, 0.5)", - "school", - "hsl(40, 45%, 78%)", - "commercial_area", - "hsla(55, 45%, 85%, 0.5)", - [ - "facility", - "industrial" - ], - "hsl(230, 20%, 85%)", - "hsl(60, 22%, 72%)" - ] - ], - "fill-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 8, - [ - "match", - [ - "get", - "class" - ], - "residential", - 0.8, - 0.2 - ], - 10, - [ - "match", - [ - "get", - "class" - ], - "residential", - 0, - 1 - ] - ], - "fill-antialias": false - }, - "metadata": { - "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, land" - } - }, - { - "id": "pitch-outline", - "type": "line", - "source": "composite", - "source-layer": "landuse", - "minzoom": 15, - "filter": [ - "==", - [ - "get", - "class" - ], - "pitch" - ], - "layout": {}, - "paint": { - "line-color": "hsl(88, 60%, 65%)" - }, - "metadata": { - "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, land" - } - }, - { - "id": "waterway-shadow", - "type": "line", - "source": "composite", - "source-layer": "waterway", - "minzoom": 10, - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 11, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 11, - "round" - ] - }, - "paint": { - "line-color": "hsl(224, 79%, 69%)", - "line-width": [ - "interpolate", - [ - "exponential", - 1.3 - ], - [ - "zoom" - ], - 9, - [ - "match", - [ - "get", - "class" - ], - [ - "canal", - "river" - ], - 0.1, - 0 - ], - 20, - [ - "match", - [ - "get", - "class" - ], - [ - "canal", - "river" - ], - 8, - 3 - ] - ], - "line-translate": [ - "interpolate", - [ - "exponential", - 1.2 - ], - [ - "zoom" - ], - 7, - [ - "literal", - [ - 0, - 0 - ] - ], - 16, - [ - "literal", - [ - -1, - -1 - ] - ] - ], - "line-translate-anchor": "viewport", - "line-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 8, - 0, - 8.5, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, water" - } - }, - { - "id": "water-shadow", - "type": "fill", - "source": "composite", - "source-layer": "water", - "minzoom": 10, - "layout": {}, - "paint": { - "fill-color": "hsl(224, 79%, 69%)", - "fill-translate": [ - "interpolate", - [ - "exponential", - 1.2 - ], - [ - "zoom" - ], - 7, - [ - "literal", - [ - 0, - 0 - ] - ], - 16, - [ - "literal", - [ - -1, - -1 - ] - ] - ], - "fill-translate-anchor": "viewport" - }, - "metadata": { - "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, water" - } - }, - { - "id": "waterway", - "type": "line", - "source": "composite", - "source-layer": "waterway", - "minzoom": 8, - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 11, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 11, - "round" - ] - }, - "paint": { - "line-color": "hsl(205, 75%, 70%)", - "line-width": [ - "interpolate", - [ - "exponential", - 1.3 - ], - [ - "zoom" - ], - 9, - [ - "match", - [ - "get", - "class" - ], - [ - "canal", - "river" - ], - 0.1, - 0 - ], - 20, - [ - "match", - [ - "get", - "class" - ], - [ - "canal", - "river" ], - 8, - 3 - ] + 4, + "hsl(200, 100%, 100%)", + 6, + "hsl(200, 50%, 90%)" ], - "line-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 8, - 0, - 8.5, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, water" - } - }, - { - "id": "water", - "type": "fill", - "source": "composite", - "source-layer": "water", - "minzoom": 0, - "layout": {}, - "paint": { - "fill-color": "hsl(205, 75%, 70%)" - }, - "metadata": { - "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, water" - } - }, - { - "id": "water-depth", - "type": "fill", - "source": "composite", - "source-layer": "depth", - "minzoom": 0, - "maxzoom": 8, - "layout": {}, - "paint": { - "fill-antialias": false, - "fill-color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 6, - [ + "high-color": [ "interpolate", [ - "linear" + "linear" ], [ - "get", - "min_depth" - ], - 0, - "hsla(205, 75%, 70%, 0.35)", - 200, - "hsla(205, 75%, 63%, 0.35)", - 7000, - "hsla(205, 75%, 56%, 0.35)" - ], - 8, - [ - "interpolate", - [ - "linear" + "zoom" ], - [ - "get", - "min_depth" - ], - 0, - "hsla(205, 75%, 70%, 0)", - 200, - "hsla(205, 75%, 63%, 0)", - 7000, - "hsla(205, 75%, 53%, 0)" - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, water" - } - }, - { - "id": "wetland", - "type": "fill", - "source": "composite", - "source-layer": "landuse_overlay", - "minzoom": 5, - "filter": [ - "match", - [ - "get", - "class" - ], - [ - "wetland", - "wetland_noveg" - ], - true, - false - ], - "paint": { - "fill-color": "hsl(194, 38%, 74%)", - "fill-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 10, - 0.25, - 10.5, - 0.15 - ] - }, - "metadata": { - "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, water" - } - }, - { - "id": "wetland-pattern", - "type": "fill", - "source": "composite", - "source-layer": "landuse_overlay", - "minzoom": 5, - "filter": [ - "match", - [ - "get", - "class" - ], - [ - "wetland", - "wetland_noveg" - ], - true, - false - ], - "paint": { - "fill-color": "hsl(194, 38%, 74%)", - "fill-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 10, - 0, - 10.5, - 1 + 4, + "hsl(200, 100%, 60%)", + 6, + "hsl(310, 60%, 80%)" ], - "fill-pattern": "wetland", - "fill-translate-anchor": "viewport" - }, - "metadata": { - "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, water" - } - }, - { - "id": "hillshade", - "type": "fill", - "source": "composite", - "source-layer": "hillshade", - "filter": [ - "all", - [ - "step", - [ - "zoom" - ], - [ - "==", + "space-color": [ + "interpolate", [ - "get", - "class" + "exponential", + 1.2 ], - "shadow" - ], - 11, - true - ], - [ - "match", - [ - "get", - "level" - ], - 89, - true, - 78, - [ - "step", - [ - "zoom" - ], - false, - 5, - true - ], - 67, - [ - "step", [ - "zoom" - ], - false, - 9, - true - ], - 56, - [ - "step", - [ - "zoom" + "zoom" ], - false, + 4, + "hsl(205, 10%, 10%)", 6, - true - ], - 94, - [ - "step", - [ - "zoom" - ], - false, - 11, - true - ], - 90, - [ - "step", - [ - "zoom" - ], - false, - 12, - true - ], - false - ] - ], - "minzoom": 0, - "maxzoom": 16, - "layout": {}, - "paint": { - "fill-color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 14, - [ - "match", - [ - "get", - "class" - ], - "shadow", - "hsla(66, 38%, 17%, 0.08)", - "hsla(60, 20%, 95%, 0.14)" - ], - 16, - [ - "match", - [ - "get", - "class" - ], - "shadow", - "hsla(66, 38%, 17%, 0)", - "hsla(60, 20%, 95%, 0)" - ] - ], - "fill-antialias": false - }, - "metadata": { - "mapbox:featureComponent": "terrain", - "mapbox:group": "Terrain, land" - } - }, - { - "id": "contour-line", - "type": "line", - "source": "composite", - "source-layer": "contour", - "minzoom": 11, - "filter": [ - "!=", - [ - "get", - "index" + "hsl(205, 60%, 50%)" ], - -1 - ], - "layout": {}, - "paint": { - "line-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 11, - [ - "match", - [ - "get", - "index" - ], - [ - 1, - 2 - ], - 0.15, - 0.3 - ], - 13, - [ - "match", + "horizon-blend": [ + "interpolate", [ - "get", - "index" + "exponential", + 1.2 ], [ - 1, - 2 + "zoom" ], - 0.3, - 0.5 - ] + 4, + 0.01, + 6, + 0.1 ], - "line-color": "hsl(60, 10%, 35%)", - "line-width": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 13, - [ - "match", - [ - "get", - "index" - ], - [ - 1, - 2 - ], - 0.5, - 0.6 - ], - 16, - [ - "match", + "star-intensity": [ + "interpolate", [ - "get", - "index" + "exponential", + 1.2 ], [ - 1, - 2 + "zoom" ], - 0.8, - 1.2 - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "terrain", - "mapbox:group": "Terrain, land" - } - }, - { - "id": "land-structure-polygon", - "type": "fill", - "source": "composite", - "source-layer": "structure", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "class" - ], - "land" - ], - [ - "==", - [ - "geometry-type" - ], - "Polygon" - ] - ], - "layout": {}, - "paint": { - "fill-color": "hsl(60, 20%, 85%)" - }, - "metadata": { - "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, built" - } - }, - { - "id": "land-structure-line", - "type": "line", - "source": "composite", - "source-layer": "structure", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "class" - ], - "land" - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": "square" - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.99 - ], - [ - "zoom" - ], - 14, - 0.75, - 20, - 40 - ], - "line-color": "hsl(60, 20%, 85%)" - }, - "metadata": { - "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, built" - } - }, - { - "id": "aeroway-polygon", - "type": "fill", - "source": "composite", - "source-layer": "aeroway", - "minzoom": 11, - "filter": [ - "all", - [ - "match", - [ - "get", - "type" - ], - [ - "runway", - "taxiway", - "helipad" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "Polygon" - ] - ], - "paint": { - "fill-color": "hsl(230, 36%, 74%)", - "fill-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 10, - 0, - 11, - 1 + 4, + 0.1, + 6, + 0 ] - }, - "metadata": { - "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, built" - } }, - { - "id": "aeroway-line", - "type": "line", - "source": "composite", - "source-layer": "aeroway", - "minzoom": 9, - "filter": [ - "==", - [ - "geometry-type" - ], - "LineString" - ], - "paint": { - "line-color": "hsl(230, 36%, 74%)", - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 9, - [ - "match", - [ - "get", - "type" + "projection": { + "name": "globe" + }, + "visibility": "public", + "version": 8, + "layers": [ + { + "id": "land", + "type": "background", + "layout": {}, + "minzoom": 0, + "paint": { + "background-color": "hsl(60, 20%, 85%)" + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, land" + } + }, + { + "id": "landcover", + "type": "fill", + "source": "composite", + "source-layer": "landcover", + "minzoom": 0, + "maxzoom": 12, + "layout": {}, + "paint": { + "fill-color": [ + "match", + [ + "get", + "class" + ], + "wood", + "hsla(103, 50%, 60%, 0.8)", + "scrub", + "hsla(98, 47%, 68%, 0.6)", + "crop", + "hsla(68, 55%, 70%, 0.6)", + "grass", + "hsla(98, 50%, 74%, 0.6)", + "snow", + "hsl(205, 45%, 95%)", + "hsl(98, 48%, 67%)" + ], + "fill-opacity": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 8, + 0.8, + 12, + 0 + ], + "fill-antialias": false + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, land" + } + }, + { + "id": "national-park", + "type": "fill", + "source": "composite", + "source-layer": "landuse_overlay", + "minzoom": 5, + "filter": [ + "==", + [ + "get", + "class" + ], + "national_park" ], - "runway", - 1, - 0.5 - ], - 18, - [ - "match", - [ - "get", - "type" + "layout": {}, + "paint": { + "fill-color": "hsl(98, 38%, 68%)", + "fill-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 5, + 0, + 6, + 0.6, + 12, + 0.2 + ] + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, land" + } + }, + { + "id": "national-park_tint-band", + "type": "line", + "source": "composite", + "source-layer": "landuse_overlay", + "minzoom": 9, + "filter": [ + "==", + [ + "get", + "class" + ], + "national_park" ], - "runway", - 80, - 20 - ] - ], - "line-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 10, - 0, - 11, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, built" - } - }, - { - "id": "building", - "type": "fill", - "source": "composite", - "source-layer": "building", - "minzoom": 15, - "filter": [ - "all", - [ - "!=", - [ - "get", - "type" - ], - "building:part" - ], - [ - "==", - [ - "get", - "underground" - ], - "false" - ] - ], - "layout": {}, - "paint": { - "fill-color": "hsl(50, 15%, 75%)", - "fill-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 15, - 0, - 16, - 1 - ], - "fill-outline-color": "hsl(60, 10%, 65%)" - }, - "metadata": { - "mapbox:featureComponent": "buildings", - "mapbox:group": "Buildings, built" - } - }, - { - "id": "building-underground", - "type": "fill", - "source": "composite", - "source-layer": "building", - "minzoom": 15, - "filter": [ - "all", - [ - "==", - [ - "get", - "underground" - ], - "true" - ], - [ - "==", - [ - "geometry-type" - ], - "Polygon" - ] - ], - "layout": {}, - "paint": { - "fill-color": "hsl(260, 60%, 85%)", - "fill-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 15, - 0, - 16, - 0.5 - ] - }, - "metadata": { - "mapbox:featureComponent": "buildings", - "mapbox:group": "Buildings, built" - } - }, - { - "id": "tunnel-minor-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "track" - ], - true, - "service", - [ - "step", - [ - "zoom" + "layout": {}, + "paint": { + "line-color": "hsl(98, 38%, 68%)", + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 9, + 1, + 14, + 8 + ], + "line-blur": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 9, + 1, + 14, + 8 + ] + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, land" + } + }, + { + "id": "landuse", + "type": "fill", + "source": "composite", + "source-layer": "landuse", + "minzoom": 5, + "filter": [ + "all", + [ + ">=", + [ + "to-number", + [ + "get", + "sizerank" + ] + ], + 0 + ], + [ + "match", + [ + "get", + "class" + ], + [ + "agriculture", + "wood", + "grass", + "scrub", + "glacier", + "pitch", + "sand" + ], + [ + "step", + [ + "zoom" + ], + false, + 11, + true + ], + "residential", + [ + "step", + [ + "zoom" + ], + true, + 10, + false + ], + [ + "park", + "airport" + ], + [ + "step", + [ + "zoom" + ], + false, + 8, + [ + "case", + [ + "==", + [ + "get", + "sizerank" + ], + 1 + ], + true, + false + ], + 10, + true + ], + [ + "facility", + "industrial" + ], + [ + "step", + [ + "zoom" + ], + false, + 12, + true + ], + "rock", + [ + "step", + [ + "zoom" + ], + false, + 11, + true + ], + "cemetery", + [ + "step", + [ + "zoom" + ], + false, + 11, + true + ], + "school", + [ + "step", + [ + "zoom" + ], + false, + 11, + true + ], + "hospital", + [ + "step", + [ + "zoom" + ], + false, + 11, + true + ], + "commercial_area", + [ + "step", + [ + "zoom" + ], + false, + 11, + true + ], + false + ], + [ + "<=", + [ + "-", + [ + "to-number", + [ + "get", + "sizerank" + ] + ], + [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0, + 18, + 14 + ] + ], + 14 + ] ], - false, - 14, - true - ], - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.8, - 22, - 2 - ], - "line-color": "hsl(60, 3%, 57%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 1, - 18, - 10, - 22, - 100 - ], - "line-dasharray": [ - 3, - 3 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels-case" - } - }, - { - "id": "tunnel-street-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "street", - "street_limited" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.8, - 22, - 2 - ], - "line-color": "hsl(60, 3%, 57%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.5, - 18, - 20, - 22, - 200 - ], - "line-opacity": [ - "step", - [ - "zoom" - ], - 0, - 14, - 1 - ], - "line-dasharray": [ - 3, - 3 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels-case" - } - }, - { - "id": "tunnel-minor-link-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "primary_link", - "secondary_link", - "tertiary_link" - ], - true, - false - ], - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.8, - 22, - 2 - ], - "line-color": "hsl(60, 10%, 70%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.4, - 18, - 18, - 22, - 180 - ], - "line-opacity": [ - "step", - [ - "zoom" - ], - 0, - 11, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels-case" - } - }, - { - "id": "tunnel-secondary-tertiary-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 11, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "secondary", - "tertiary" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 1, - 22, - 2 - ], - "line-color": "hsl(60, 3%, 57%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0, - 18, - 26, - 22, - 260 - ], - "line-dasharray": [ - 3, - 3 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels-case" - } - }, - { - "id": "tunnel-primary-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 10, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "==", - [ - "get", - "class" - ], - "primary" - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 1, - 22, - 2 - ], - "line-color": "hsl(60, 3%, 57%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0.8, - 18, - 28, - 22, - 280 - ], - "line-dasharray": [ - 3, - 3 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels-case" - } - }, - { - "id": "tunnel-major-link-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 12, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "motorway_link", - "trunk_link" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.8, - 22, - 2 - ], - "line-color": "hsl(0, 0%, 95%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.8, - 18, - 20, - 22, - 200 - ], - "line-dasharray": [ - 3, - 3 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels-case" - } - }, - { - "id": "tunnel-motorway-trunk-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "motorway", - "trunk" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 1, - 22, - 2 - ], - "line-color": "hsl(60, 10%, 82%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0.8, - 18, - 30, - 22, - 300 - ], - "line-dasharray": [ - 3, - 3 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels-case" - } - }, - { - "id": "tunnel-path-trail", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "==", - [ - "get", - "class" - ], - "path" - ], - [ - "match", - [ - "get", - "type" - ], - [ - "hiking", - "mountain_bike", - "trail" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": {}, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 15, - 1, - 18, - 4 - ], - "line-color": "hsl(60, 32%, 90%)", - "line-dasharray": [ - "step", - [ - "zoom" - ], - [ - "literal", - [ - 5, - 0.5 - ] - ], - 15, - [ - "literal", - [ - 4, - 0.5 - ] - ], - 16, - [ - "literal", - [ - 4, - 0.45 - ] - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., tunnels" - } - }, - { - "id": "tunnel-path-cycleway-piste", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 12, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "==", - [ - "get", - "class" - ], - "path" - ], - [ - "match", - [ - "get", - "type" - ], - [ - "cycleway", - "piste" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": {}, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 15, - 1, - 18, - 4 - ], - "line-color": "hsl(60, 32%, 90%)", - "line-dasharray": [ - 10, - 0 - ] - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., tunnels" - } - }, - { - "id": "tunnel-path", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "==", - [ - "get", - "class" - ], - "path" - ], - [ - "!=", - [ - "get", - "type" - ], - "steps" - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": {}, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 15, - 1, - 18, - 4 - ], - "line-color": "hsl(60, 32%, 90%)", - "line-dasharray": [ - "step", - [ - "zoom" - ], - [ - "literal", - [ - 1, - 0 - ] - ], - 15, - [ - "literal", - [ - 1.75, - 1 - ] - ], - 16, - [ - "literal", - [ - 1, - 0.75 - ] - ], - 17, - [ - "literal", - [ - 1, - 0.5 - ] - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., tunnels" - } - }, - { - "id": "tunnel-steps", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "==", - [ - "get", - "type" - ], - "steps" - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 15, - 1, - 16, - 1.6, - 18, - 6 - ], - "line-color": "hsl(60, 32%, 90%)", - "line-dasharray": [ - "step", - [ - "zoom" - ], - [ - "literal", - [ - 1, - 0 - ] - ], - 15, - [ - "literal", - [ - 1.75, - 1 - ] - ], - 16, - [ - "literal", - [ - 1, - 0.75 - ] - ], - 17, - [ - "literal", - [ - 0.3, - 0.3 - ] - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., tunnels" - } - }, - { - "id": "tunnel-pedestrian", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "==", - [ - "get", - "class" - ], - "pedestrian" - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.5, - 18, - 12 - ], - "line-color": "hsl(0, 0%, 95%)", - "line-dasharray": [ - "step", - [ - "zoom" - ], - [ - "literal", - [ - 1, - 0 - ] - ], - 15, - [ - "literal", - [ - 1.5, - 0.4 - ] - ], - 16, - [ - "literal", - [ - 1, - 0.2 - ] - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., tunnels" - } - }, - { - "id": "tunnel-construction", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "==", - [ - "get", - "class" - ], - "construction" - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 2, - 18, - 20, - 22, - 200 - ], - "line-color": "hsl(60, 10%, 70%)", - "line-dasharray": [ - "step", - [ - "zoom" - ], - [ - "literal", - [ - 0.4, - 0.8 - ] - ], - 15, - [ - "literal", - [ - 0.3, - 0.6 - ] - ], - 16, - [ - "literal", - [ - 0.2, - 0.3 - ] - ], - 17, - [ - "literal", - [ - 0.2, - 0.25 - ] - ], - 18, - [ - "literal", - [ - 0.15, - 0.15 - ] - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" - } - }, - { - "id": "tunnel-minor", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "track" - ], - true, - "service", - [ - "step", - [ - "zoom" + "layout": {}, + "paint": { + "fill-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + [ + "match", + [ + "get", + "class" + ], + "wood", + "hsla(103, 50%, 60%, 0.8)", + "scrub", + "hsla(98, 47%, 68%, 0.6)", + "agriculture", + "hsla(98, 50%, 74%, 0.6)", + "park", + [ + "match", + [ + "get", + "type" + ], + [ + "garden", + "playground", + "zoo" + ], + "hsl(98, 38%, 68%)", + "hsl(98, 55%, 70%)" + ], + "grass", + "hsla(98, 50%, 74%, 0.6)", + "airport", + "hsl(230, 40%, 82%)", + "cemetery", + "hsl(98, 45%, 75%)", + "glacier", + "hsl(205, 45%, 95%)", + "hospital", + "hsl(20, 45%, 82%)", + "pitch", + "hsl(88, 65%, 75%)", + "sand", + "hsl(69, 60%, 72%)", + "rock", + "hsl(60, 0%, 85%)", + "school", + "hsl(40, 45%, 78%)", + "commercial_area", + "hsl(55, 45%, 85%)", + "residential", + "hsl(60, 7%, 87%)", + [ + "facility", + "industrial" + ], + "hsl(230, 20%, 85%)", + "hsl(60, 22%, 72%)" + ], + 16, + [ + "match", + [ + "get", + "class" + ], + "wood", + "hsla(103, 50%, 60%, 0.8)", + "scrub", + "hsla(98, 47%, 68%, 0.6)", + "agriculture", + "hsla(98, 50%, 74%, 0.6)", + "park", + [ + "match", + [ + "get", + "type" + ], + [ + "garden", + "playground", + "zoo" + ], + "hsl(98, 38%, 68%)", + "hsl(98, 55%, 70%)" + ], + "grass", + "hsla(98, 50%, 74%, 0.6)", + "airport", + "hsl(230, 40%, 82%)", + "cemetery", + "hsl(98, 45%, 75%)", + "glacier", + "hsl(205, 45%, 95%)", + "hospital", + "hsl(20, 45%, 82%)", + "pitch", + "hsl(88, 65%, 75%)", + "sand", + "hsl(69, 60%, 72%)", + "rock", + "hsla(60, 0%, 85%, 0.5)", + "school", + "hsl(40, 45%, 78%)", + "commercial_area", + "hsla(55, 45%, 85%, 0.5)", + [ + "facility", + "industrial" + ], + "hsl(230, 20%, 85%)", + "hsl(60, 22%, 72%)" + ] + ], + "fill-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 8, + [ + "match", + [ + "get", + "class" + ], + "residential", + 0.8, + 0.2 + ], + 10, + [ + "match", + [ + "get", + "class" + ], + "residential", + 0, + 1 + ] + ], + "fill-antialias": false + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, land" + } + }, + { + "id": "pitch-outline", + "type": "line", + "source": "composite", + "source-layer": "landuse", + "minzoom": 15, + "filter": [ + "==", + [ + "get", + "class" + ], + "pitch" + ], + "layout": {}, + "paint": { + "line-color": "hsl(88, 60%, 65%)" + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, land" + } + }, + { + "id": "waterway-shadow", + "type": "line", + "source": "composite", + "source-layer": "waterway", + "minzoom": 10, + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 11, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 11, + "round" + ] + }, + "paint": { + "line-color": "hsl(224, 79%, 69%)", + "line-width": [ + "interpolate", + [ + "exponential", + 1.3 + ], + [ + "zoom" + ], + 9, + [ + "match", + [ + "get", + "class" + ], + [ + "canal", + "river" + ], + 0.1, + 0 + ], + 20, + [ + "match", + [ + "get", + "class" + ], + [ + "canal", + "river" + ], + 8, + 3 + ] + ], + "line-translate": [ + "interpolate", + [ + "exponential", + 1.2 + ], + [ + "zoom" + ], + 7, + [ + "literal", + [ + 0, + 0 + ] + ], + 16, + [ + "literal", + [ + -1, + -1 + ] + ] + ], + "line-translate-anchor": "viewport", + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 8, + 0, + 8.5, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, water" + } + }, + { + "id": "water-shadow", + "type": "fill", + "source": "composite", + "source-layer": "water", + "minzoom": 10, + "layout": {}, + "paint": { + "fill-color": "hsl(224, 79%, 69%)", + "fill-translate": [ + "interpolate", + [ + "exponential", + 1.2 + ], + [ + "zoom" + ], + 7, + [ + "literal", + [ + 0, + 0 + ] + ], + 16, + [ + "literal", + [ + -1, + -1 + ] + ] + ], + "fill-translate-anchor": "viewport" + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, water" + } + }, + { + "id": "waterway", + "type": "line", + "source": "composite", + "source-layer": "waterway", + "minzoom": 8, + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 11, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 11, + "round" + ] + }, + "paint": { + "line-color": "hsl(205, 75%, 70%)", + "line-width": [ + "interpolate", + [ + "exponential", + 1.3 + ], + [ + "zoom" + ], + 9, + [ + "match", + [ + "get", + "class" + ], + [ + "canal", + "river" + ], + 0.1, + 0 + ], + 20, + [ + "match", + [ + "get", + "class" + ], + [ + "canal", + "river" + ], + 8, + 3 + ] + ], + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 8, + 0, + 8.5, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, water" + } + }, + { + "id": "water", + "type": "fill", + "source": "composite", + "source-layer": "water", + "minzoom": 0, + "layout": {}, + "paint": { + "fill-color": "hsl(205, 75%, 70%)" + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, water" + } + }, + { + "id": "water-depth", + "type": "fill", + "source": "composite", + "source-layer": "depth", + "minzoom": 0, + "maxzoom": 8, + "layout": {}, + "paint": { + "fill-antialias": false, + "fill-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 6, + [ + "interpolate", + [ + "linear" + ], + [ + "get", + "min_depth" + ], + 0, + "hsla(205, 75%, 70%, 0.35)", + 200, + "hsla(205, 75%, 63%, 0.35)", + 7000, + "hsla(205, 75%, 56%, 0.35)" + ], + 8, + [ + "interpolate", + [ + "linear" + ], + [ + "get", + "min_depth" + ], + 0, + "hsla(205, 75%, 70%, 0)", + 200, + "hsla(205, 75%, 63%, 0)", + 7000, + "hsla(205, 75%, 53%, 0)" + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, water" + } + }, + { + "id": "wetland", + "type": "fill", + "source": "composite", + "source-layer": "landuse_overlay", + "minzoom": 5, + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "wetland", + "wetland_noveg" + ], + true, + false + ], + "paint": { + "fill-color": "hsl(194, 38%, 74%)", + "fill-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 0.25, + 10.5, + 0.15 + ] + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, water" + } + }, + { + "id": "wetland-pattern", + "type": "fill", + "source": "composite", + "source-layer": "landuse_overlay", + "minzoom": 5, + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "wetland", + "wetland_noveg" + ], + true, + false + ], + "paint": { + "fill-color": "hsl(194, 38%, 74%)", + "fill-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 0, + 10.5, + 1 + ], + "fill-pattern": "wetland", + "fill-translate-anchor": "viewport" + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, water" + } + }, + { + "id": "hillshade", + "type": "fill", + "source": "composite", + "source-layer": "hillshade", + "filter": [ + "all", + [ + "step", + [ + "zoom" + ], + [ + "==", + [ + "get", + "class" + ], + "shadow" + ], + 11, + true + ], + [ + "match", + [ + "get", + "level" + ], + 89, + true, + 78, + [ + "step", + [ + "zoom" + ], + false, + 5, + true + ], + 67, + [ + "step", + [ + "zoom" + ], + false, + 9, + true + ], + 56, + [ + "step", + [ + "zoom" + ], + false, + 6, + true + ], + 94, + [ + "step", + [ + "zoom" + ], + false, + 11, + true + ], + 90, + [ + "step", + [ + "zoom" + ], + false, + 12, + true + ], + false + ] + ], + "minzoom": 0, + "maxzoom": 16, + "layout": {}, + "paint": { + "fill-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 14, + [ + "match", + [ + "get", + "class" + ], + "shadow", + "hsla(66, 38%, 17%, 0.08)", + "hsla(60, 20%, 95%, 0.14)" + ], + 16, + [ + "match", + [ + "get", + "class" + ], + "shadow", + "hsla(66, 38%, 17%, 0)", + "hsla(60, 20%, 95%, 0)" + ] + ], + "fill-antialias": false + }, + "metadata": { + "mapbox:featureComponent": "terrain", + "mapbox:group": "Terrain, land" + } + }, + { + "id": "contour-line", + "type": "line", + "source": "composite", + "source-layer": "contour", + "minzoom": 11, + "filter": [ + "!=", + [ + "get", + "index" + ], + -1 + ], + "layout": {}, + "paint": { + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 11, + [ + "match", + [ + "get", + "index" + ], + [ + 1, + 2 + ], + 0.15, + 0.3 + ], + 13, + [ + "match", + [ + "get", + "index" + ], + [ + 1, + 2 + ], + 0.3, + 0.5 + ] + ], + "line-color": "hsl(60, 10%, 35%)", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 13, + [ + "match", + [ + "get", + "index" + ], + [ + 1, + 2 + ], + 0.5, + 0.6 + ], + 16, + [ + "match", + [ + "get", + "index" + ], + [ + 1, + 2 + ], + 0.8, + 1.2 + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "terrain", + "mapbox:group": "Terrain, land" + } + }, + { + "id": "land-structure-polygon", + "type": "fill", + "source": "composite", + "source-layer": "structure", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "land" + ], + [ + "==", + [ + "geometry-type" + ], + "Polygon" + ] + ], + "layout": {}, + "paint": { + "fill-color": "hsl(60, 20%, 85%)" + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, built" + } + }, + { + "id": "land-structure-line", + "type": "line", + "source": "composite", + "source-layer": "structure", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "land" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": "square" + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.99 + ], + [ + "zoom" + ], + 14, + 0.75, + 20, + 40 + ], + "line-color": "hsl(60, 20%, 85%)" + }, + "metadata": { + "mapbox:featureComponent": "land-and-water", + "mapbox:group": "Land & water, built" + } + }, + { + "id": "aeroway-polygon", + "type": "fill", + "source": "composite", + "source-layer": "aeroway", + "minzoom": 11, + "filter": [ + "all", + [ + "match", + [ + "get", + "type" + ], + [ + "runway", + "taxiway", + "helipad" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "Polygon" + ] + ], + "paint": { + "fill-color": "hsl(230, 36%, 74%)", + "fill-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 0, + 11, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, built" + } + }, + { + "id": "aeroway-line", + "type": "line", + "source": "composite", + "source-layer": "aeroway", + "minzoom": 9, + "filter": [ + "==", + [ + "geometry-type" + ], + "LineString" + ], + "paint": { + "line-color": "hsl(230, 36%, 74%)", + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 9, + [ + "match", + [ + "get", + "type" + ], + "runway", + 1, + 0.5 + ], + 18, + [ + "match", + [ + "get", + "type" + ], + "runway", + 80, + 20 + ] + ], + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 0, + 11, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, built" + } + }, + { + "id": "building", + "type": "fill", + "source": "composite", + "source-layer": "building", + "minzoom": 15, + "filter": [ + "all", + [ + "!=", + [ + "get", + "type" + ], + "building:part" + ], + [ + "==", + [ + "get", + "underground" + ], + "false" + ] + ], + "layout": {}, + "paint": { + "fill-color": "hsl(50, 15%, 75%)", + "fill-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + 0, + 16, + 1 + ], + "fill-outline-color": "hsl(60, 10%, 65%)" + }, + "metadata": { + "mapbox:featureComponent": "buildings", + "mapbox:group": "Buildings, built" + } + }, + { + "id": "building-underground", + "type": "fill", + "source": "composite", + "source-layer": "building", + "minzoom": 15, + "filter": [ + "all", + [ + "==", + [ + "get", + "underground" + ], + "true" + ], + [ + "==", + [ + "geometry-type" + ], + "Polygon" + ] + ], + "layout": {}, + "paint": { + "fill-color": "hsl(260, 60%, 85%)", + "fill-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + 0, + 16, + 0.5 + ] + }, + "metadata": { + "mapbox:featureComponent": "buildings", + "mapbox:group": "Buildings, built" + } + }, + { + "id": "tunnel-minor-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "track" + ], + true, + "service", + [ + "step", + [ + "zoom" + ], + false, + 14, + true + ], + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 3%, 57%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 18, + 10, + 22, + 100 + ], + "line-dasharray": [ + 3, + 3 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels-case" + } + }, + { + "id": "tunnel-street-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "street", + "street_limited" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 3%, 57%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.5, + 18, + 20, + 22, + 200 + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 14, + 1 + ], + "line-dasharray": [ + 3, + 3 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels-case" + } + }, + { + "id": "tunnel-minor-link-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "primary_link", + "secondary_link", + "tertiary_link" + ], + true, + false + ], + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.4, + 18, + 18, + 22, + 180 + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 11, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels-case" + } + }, + { + "id": "tunnel-secondary-tertiary-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 11, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "secondary", + "tertiary" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 22, + 2 + ], + "line-color": "hsl(60, 3%, 57%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0, + 18, + 26, + 22, + 260 + ], + "line-dasharray": [ + 3, + 3 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels-case" + } + }, + { + "id": "tunnel-primary-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 10, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "get", + "class" + ], + "primary" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 22, + 2 + ], + "line-color": "hsl(60, 3%, 57%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 28, + 22, + 280 + ], + "line-dasharray": [ + 3, + 3 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels-case" + } + }, + { + "id": "tunnel-major-link-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.8, + 18, + 20, + 22, + 200 + ], + "line-dasharray": [ + 3, + 3 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels-case" + } + }, + { + "id": "tunnel-motorway-trunk-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 82%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 30, + 22, + 300 + ], + "line-dasharray": [ + 3, + 3 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels-case" + } + }, + { + "id": "tunnel-path-trail", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "match", + [ + "get", + "type" + ], + [ + "hiking", + "mountain_bike", + "trail" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": {}, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 18, + 4 + ], + "line-color": "hsl(60, 32%, 90%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 5, + 0.5 + ] + ], + 15, + [ + "literal", + [ + 4, + 0.5 + ] + ], + 16, + [ + "literal", + [ + 4, + 0.45 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., tunnels" + } + }, + { + "id": "tunnel-path-cycleway-piste", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "match", + [ + "get", + "type" + ], + [ + "cycleway", + "piste" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": {}, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 18, + 4 + ], + "line-color": "hsl(60, 32%, 90%)", + "line-dasharray": [ + 10, + 0 + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., tunnels" + } + }, + { + "id": "tunnel-path", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "!=", + [ + "get", + "type" + ], + "steps" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": {}, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 18, + 4 + ], + "line-color": "hsl(60, 32%, 90%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 1, + 0 + ] + ], + 15, + [ + "literal", + [ + 1.75, + 1 + ] + ], + 16, + [ + "literal", + [ + 1, + 0.75 + ] + ], + 17, + [ + "literal", + [ + 1, + 0.5 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., tunnels" + } + }, + { + "id": "tunnel-steps", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "get", + "type" + ], + "steps" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 16, + 1.6, + 18, + 6 + ], + "line-color": "hsl(60, 32%, 90%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 1, + 0 + ] + ], + 15, + [ + "literal", + [ + 1.75, + 1 + ] + ], + 16, + [ + "literal", + [ + 1, + 0.75 + ] + ], + 17, + [ + "literal", + [ + 0.3, + 0.3 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., tunnels" + } + }, + { + "id": "tunnel-pedestrian", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "get", + "class" + ], + "pedestrian" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.5, + 18, + 12 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 1, + 0 + ] + ], + 15, + [ + "literal", + [ + 1.5, + 0.4 + ] + ], + 16, + [ + "literal", + [ + 1, + 0.2 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., tunnels" + } + }, + { + "id": "tunnel-construction", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "get", + "class" + ], + "construction" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 2, + 18, + 20, + 22, + 200 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 0.4, + 0.8 + ] + ], + 15, + [ + "literal", + [ + 0.3, + 0.6 + ] + ], + 16, + [ + "literal", + [ + 0.2, + 0.3 + ] + ], + 17, + [ + "literal", + [ + 0.2, + 0.25 + ] + ], + 18, + [ + "literal", + [ + 0.15, + 0.15 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-minor", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "track" + ], + true, + "service", + [ + "step", + [ + "zoom" + ], + false, + 14, + true + ], + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 18, + 10, + 22, + 100 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "street_limited", + "hsl(60, 22%, 80%)", + "hsl(0, 0%, 95%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-minor-link", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "primary_link", + "secondary_link", + "tertiary_link" + ], + true, + false + ], + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 13, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 13, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.4, + 18, + 18, + 22, + 180 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-major-link", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.8, + 18, + 20, + 22, + 200 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "motorway_link", + "hsl(15, 100%, 85%)", + "hsl(35, 78%, 85%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-street", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "street", + "street_limited" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.5, + 18, + 20, + 22, + 200 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "street_limited", + "hsl(60, 22%, 80%)", + "hsl(0, 0%, 95%)" + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 14, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-street-low", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "maxzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "street", + "street_limited" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.5, + 18, + 20, + 22, + 200 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-secondary-tertiary", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "secondary", + "tertiary" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0, + 18, + 26, + 22, + 260 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-primary", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "get", + "class" + ], + "primary" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 28, + 22, + 280 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-motorway-trunk", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 30, + 22, + 300 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "motorway", + "hsl(15, 100%, 85%)", + "hsl(35, 78%, 85%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-oneway-arrow-blue", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "==", + [ + "get", + "oneway" + ], + "true" + ], + [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "primary", + "secondary", + "street", + "street_limited", + "tertiary" + ], + true, + false + ], + 16, + [ + "match", + [ + "get", + "class" + ], + [ + "primary", + "secondary", + "tertiary", + "street", + "street_limited", + "primary_link", + "secondary_link", + "tertiary_link", + "service", + "track" + ], + true, + false + ] + ] + ], + "layout": { + "symbol-placement": "line", + "icon-image": [ + "step", + [ + "zoom" + ], + "oneway-small", + 18, + "oneway-large" + ], + "symbol-spacing": 200, + "icon-rotation-alignment": "map", + "icon-allow-overlap": true, + "icon-ignore-placement": true + }, + "paint": {}, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "tunnel-oneway-arrow-white", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "tunnel" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "motorway_link", + "trunk", + "trunk_link" + ], + true, + false + ], + [ + "==", + [ + "get", + "oneway" + ], + "true" + ] + ], + "layout": { + "symbol-placement": "line", + "icon-image": [ + "step", + [ + "zoom" + ], + "oneway-white-small", + 18, + "oneway-white-large" + ], + "symbol-spacing": 200, + "icon-rotation-alignment": "map", + "icon-allow-overlap": true, + "icon-ignore-placement": true + }, + "paint": {}, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, tunnels" + } + }, + { + "id": "cliff", + "type": "line", + "source": "composite", + "source-layer": "structure", + "minzoom": 15, + "filter": [ + "==", + [ + "get", + "class" + ], + "cliff" + ], + "layout": { + "line-cap": "round", + "line-join": "round" + }, + "paint": { + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + 0, + 15.25, + 1 + ], + "line-width": 10, + "line-pattern": "cliff" + }, + "metadata": { + "mapbox:featureComponent": "terrain", + "mapbox:group": "Terrain, surface" + } + }, + { + "id": "ferry", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 8, + "filter": [ + "==", + [ + "get", + "type" + ], + "ferry" + ], + "paint": { + "line-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + "hsl(214, 68%, 63%)", + 17, + "hsl(239, 68%, 63%)" + ], + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.5, + 20, + 1 + ], + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 1, + 0 + ] + ], + 13, + [ + "literal", + [ + 12, + 4 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, ferries" + } + }, + { + "id": "ferry-auto", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 8, + "filter": [ + "==", + [ + "get", + "type" + ], + "ferry_auto" + ], + "paint": { + "line-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + "hsl(214, 68%, 63%)", + 17, + "hsl(239, 68%, 63%)" + ], + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.5, + 20, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, ferries" + } + }, + { + "id": "road-pedestrian-polygon-fill", + "type": "fill", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "path", + "pedestrian" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "case", + [ + "has", + "layer" + ], + [ + ">=", + [ + "get", + "layer" + ], + 0 + ], + true + ], + [ + "==", + [ + "geometry-type" + ], + "Polygon" + ] + ], + "paint": { + "fill-color": "hsl(60, 20%, 85%)" + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-pedestrian-polygon-pattern", + "type": "fill", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "path", + "pedestrian" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "case", + [ + "has", + "layer" + ], + [ + ">=", + [ + "get", + "layer" + ], + 0 + ], + true + ], + [ + "==", + [ + "geometry-type" + ], + "Polygon" + ] + ], + "paint": { + "fill-pattern": "pedestrian-polygon", + "fill-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 16, + 0, + 17, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-path-bg", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "step", + [ + "zoom" + ], + [ + "!", + [ + "match", + [ + "get", + "type" + ], + [ + "steps", + "sidewalk", + "crossing" + ], + true, + false + ] + ], + 16, + [ + "!=", + [ + "get", + "type" + ], + "steps" + ] + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 2, + 18, + 7 + ], + "line-color": [ + "match", + [ + "get", + "type" + ], + "piste", + "hsl(215, 80%, 48%)", + [ + "mountain_bike", + "hiking", + "trail", + "cycleway", + "footway", + "path", + "bridleway" + ], + "hsl(35, 80%, 48%)", + "hsl(60, 1%, 64%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-steps-bg", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "type" + ], + "steps" + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-join": "round" + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 2, + 17, + 4.6, + 18, + 7 + ], + "line-color": "hsl(35, 80%, 48%)", + "line-opacity": 0.75 + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-pedestrian-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "pedestrian" + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "case", + [ + "has", + "layer" + ], + [ + ">=", + [ + "get", + "layer" + ], + 0 + ], + true + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 2, + 18, + 14.5 + ], + "line-color": "hsl(60, 10%, 70%)" + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-path-trail", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "match", + [ + "get", + "type" + ], + [ + "hiking", + "mountain_bike", + "trail" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 18, + 4 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 5, + 0.5 + ] + ], + 15, + [ + "literal", + [ + 4, + 0.5 + ] + ], + 16, + [ + "literal", + [ + 4, + 0.45 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-path-cycleway-piste", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "match", + [ + "get", + "type" + ], + [ + "cycleway", + "piste" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 18, + 4 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + 10, + 0 + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-path", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "step", + [ + "zoom" + ], + [ + "!", + [ + "match", + [ + "get", + "type" + ], + [ + "steps", + "sidewalk", + "crossing" + ], + true, + false + ] + ], + 16, + [ + "!=", + [ + "get", + "type" + ], + "steps" + ] + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 13, + 0.5, + 14, + 1, + 15, + 1, + 18, + 4 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 4, + 0.3 + ] + ], + 15, + [ + "literal", + [ + 1.75, + 0.3 + ] + ], + 16, + [ + "literal", + [ + 1, + 0.3 + ] + ], + 17, + [ + "literal", + [ + 1, + 0.25 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-steps", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "type" + ], + "steps" + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-join": "round" + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 16, + 1.6, + 18, + 6 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 1, + 0 + ] + ], + 15, + [ + "literal", + [ + 1.75, + 1 + ] + ], + 16, + [ + "literal", + [ + 1, + 0.75 + ] + ], + 17, + [ + "literal", + [ + 0.3, + 0.3 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-pedestrian", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "pedestrian" + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "case", + [ + "has", + "layer" + ], + [ + ">=", + [ + "get", + "layer" + ], + 0 + ], + true + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.5, + 18, + 12 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 1, + 0 + ] + ], + 15, + [ + "literal", + [ + 1.5, + 0.4 + ] + ], + 16, + [ + "literal", + [ + 1, + 0.2 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "golf-hole-line", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "==", + [ + "get", + "class" + ], + "golf" + ], + "paint": { + "line-color": "hsl(98, 26%, 56%)" + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., surface" + } + }, + { + "id": "road-polygon", + "type": "fill", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "primary", + "secondary", + "tertiary", + "primary_link", + "secondary_link", + "tertiary_link", + "trunk", + "trunk_link", + "street", + "street_limited", + "track", + "service" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "Polygon" + ] + ], + "paint": { + "fill-color": "hsl(0, 0%, 95%)", + "fill-outline-color": "hsl(60, 10%, 70%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "turning-feature-outline", + "type": "circle", + "source": "composite", + "source-layer": "road", + "minzoom": 15, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "turning_circle", + "turning_loop" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "Point" + ] + ], + "paint": { + "circle-radius": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 4.5, + 16, + 8, + 18, + 20, + 22, + 200 + ], + "circle-color": "hsl(0, 0%, 95%)", + "circle-stroke-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + 0.8, + 16, + 1.2, + 18, + 2 + ], + "circle-stroke-color": "hsl(60, 10%, 70%)", + "circle-pitch-alignment": "map" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-minor-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "track" + ], + true, + "service", + [ + "step", + [ + "zoom" + ], + false, + 14, + true + ], + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "track", + "hsl(35, 80%, 48%)", + "hsl(60, 10%, 70%)" + ], + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 18, + 10, + 22, + 100 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-street-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "street", + "street_limited" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.5, + 18, + 20, + 22, + 200 + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 14, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-minor-link-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "primary_link", + "secondary_link", + "tertiary_link" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.4, + 18, + 18, + 22, + 180 + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 11, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-secondary-tertiary-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 11, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "secondary", + "tertiary" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0, + 18, + 26, + 22, + 260 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-primary-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 10, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "primary" + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 28, + 22, + 280 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-major-link-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 82%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.8, + 18, + 20, + 22, + 200 + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 11, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-motorway-trunk-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 3, + "filter": [ + "all", + [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + 5, + [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ] + ] + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 82%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 30, + 22, + 300 + ], + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 0, + 3.5, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "turning-feature", + "type": "circle", + "source": "composite", + "source-layer": "road", + "minzoom": 15, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "turning_circle", + "turning_loop" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "Point" + ] + ], + "paint": { + "circle-radius": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 4.5, + 16, + 8, + 18, + 20, + 22, + 200 + ], + "circle-color": "hsl(0, 0%, 95%)", + "circle-pitch-alignment": "map" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-construction", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "construction" + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 2, + 18, + 20, + 22, + 200 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 0.4, + 0.8 + ] + ], + 15, + [ + "literal", + [ + 0.3, + 0.6 + ] + ], + 16, + [ + "literal", + [ + 0.2, + 0.3 + ] + ], + 17, + [ + "literal", + [ + 0.2, + 0.25 + ] + ], + 18, + [ + "literal", + [ + 0.15, + 0.15 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-minor", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "track" + ], + true, + "service", + [ + "step", + [ + "zoom" + ], + false, + 14, + true + ], + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 18, + 10, + 22, + 100 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-minor-link", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "primary_link", + "secondary_link", + "tertiary_link" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 13, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 13, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.4, + 18, + 18, + 22, + 180 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-major-link", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 13, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 13, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.8, + 18, + 20, + 22, + 200 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "motorway_link", + "hsl(15, 100%, 75%)", + "hsl(35, 89%, 75%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-street", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "street", + "street_limited" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.5, + 18, + 20, + 22, + 200 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "street_limited", + "hsl(60, 22%, 80%)", + "hsl(0, 0%, 95%)" + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 14, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-street-low", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 11, + "maxzoom": 14, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "street", + "street_limited" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.5, + 18, + 20, + 22, + 200 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-secondary-tertiary", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 9, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "secondary", + "tertiary" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0, + 18, + 26, + 22, + 260 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-primary", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 6, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "primary" + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 28, + 22, + 280 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-motorway-trunk", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 3, + "filter": [ + "all", + [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + 5, + [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ] + ] + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 13, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 13, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 30, + 22, + 300 + ], + "line-color": [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "class" + ], + "motorway", + "hsl(15, 88%, 69%)", + "trunk", + "hsl(35, 81%, 59%)", + "hsl(60, 18%, 85%)" + ], + 9, + [ + "match", + [ + "get", + "class" + ], + "motorway", + "hsl(15, 100%, 75%)", + "hsl(35, 89%, 75%)" + ] + ], + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 0, + 3.5, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface" + } + }, + { + "id": "road-rail", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "major_rail", + "minor_rail" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ] + ], + "paint": { + "line-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 13, + "hsl(75, 25%, 68%)", + 16, + "hsl(60, 0%, 56%)" + ], + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.5, + 20, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, surface" + } + }, + { + "id": "road-rail-tracks", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "major_rail", + "minor_rail" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ] + ], + "paint": { + "line-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 13, + "hsl(75, 25%, 68%)", + 16, + "hsl(60, 0%, 56%)" + ], + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 4, + 20, + 8 + ], + "line-dasharray": [ + 0.1, + 15 + ], + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 13.75, + 0, + 14, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, surface" + } + }, + { + "id": "level-crossing", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "==", + [ + "get", + "class" + ], + "level_crossing" + ], + "layout": { + "icon-image": "level-crossing", + "icon-rotation-alignment": "map", + "icon-allow-overlap": true, + "icon-ignore-placement": true + }, + "paint": {}, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface-icons" + } + }, + { + "id": "road-oneway-arrow-blue", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "all", + [ + "==", + [ + "get", + "oneway" + ], + "true" + ], + [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "primary", + "secondary", + "tertiary", + "street", + "street_limited" + ], + true, + false + ], + 16, + [ + "match", + [ + "get", + "class" + ], + [ + "primary", + "secondary", + "tertiary", + "street", + "street_limited", + "primary_link", + "secondary_link", + "tertiary_link", + "service", + "track" + ], + true, + false + ] + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ] + ], + "layout": { + "symbol-placement": "line", + "icon-image": [ + "step", + [ + "zoom" + ], + "oneway-small", + 18, + "oneway-large" + ], + "symbol-spacing": 200, + "icon-rotation-alignment": "map", + "icon-allow-overlap": true, + "icon-ignore-placement": true + }, + "paint": {}, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface-icons" + } + }, + { + "id": "road-oneway-arrow-white", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "all", + [ + "==", + [ + "get", + "oneway" + ], + "true" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk", + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "none", + "ford" + ], + true, + false + ] + ], + "layout": { + "symbol-placement": "line", + "icon-image": [ + "step", + [ + "zoom" + ], + "oneway-white-small", + 18, + "oneway-white-large" + ], + "symbol-spacing": 200, + "icon-rotation-alignment": "map", + "icon-allow-overlap": true, + "icon-ignore-placement": true + }, + "paint": {}, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface-icons" + } + }, + { + "id": "crosswalks", + "type": "symbol", + "source": "composite", + "source-layer": "structure", + "minzoom": 17, + "filter": [ + "all", + [ + "==", + [ + "get", + "type" + ], + "crosswalk" + ], + [ + "==", + [ + "geometry-type" + ], + "Point" + ] + ], + "layout": { + "icon-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 16, + 0.1, + 18, + 0.2, + 19, + 0.5, + 22, + 1.5 + ], + "icon-image": [ + "step", + [ + "zoom" + ], + "crosswalk-small", + 18, + "crosswalk-large" + ], + "icon-rotate": [ + "get", + "direction" + ], + "icon-rotation-alignment": "map", + "icon-allow-overlap": true, + "icon-ignore-placement": true + }, + "paint": {}, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, surface-icons" + } + }, + { + "id": "gate-fence-hedge", + "type": "line", + "source": "composite", + "source-layer": "structure", + "minzoom": 16, + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "gate", + "fence", + "hedge" + ], + true, + false + ], + "layout": {}, + "paint": { + "line-color": [ + "match", + [ + "get", + "class" + ], + "hedge", + "hsl(98, 32%, 56%)", + "hsl(60, 25%, 63%)" + ], + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 16, + 1, + 20, + 3 + ], + "line-opacity": [ + "match", + [ + "get", + "class" + ], + "gate", + 0.5, + 1 + ], + "line-dasharray": [ + 1, + 2, + 5, + 2, + 1, + 2 + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "bridge-path-bg", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "step", + [ + "zoom" + ], + [ + "!", + [ + "match", + [ + "get", + "type" + ], + [ + "steps", + "sidewalk", + "crossing" + ], + true, + false + ] + ], + 16, + [ + "!=", + [ + "get", + "type" + ], + "steps" + ] + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 2, + 18, + 7 + ], + "line-color": [ + "match", + [ + "get", + "type" + ], + "piste", + "hsl(215, 80%, 48%)", + [ + "mountain_bike", + "hiking", + "trail", + "cycleway", + "footway", + "path", + "bridleway" + ], + "hsl(35, 80%, 48%)", + "hsl(60, 1%, 64%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "bridge-steps-bg", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "type" + ], + "steps" + ], + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 2, + 17, + 4.6, + 18, + 7 + ], + "line-color": "hsl(35, 80%, 48%)", + "line-opacity": 0.75 + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "bridge-pedestrian-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "class" + ], + "pedestrian" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 2, + 18, + 14.5 + ], + "line-color": "hsl(60, 10%, 70%)" + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "bridge-path-trail", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "match", + [ + "get", + "type" + ], + [ + "hiking", + "mountain_bike", + "trail" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": {}, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 18, + 4 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 5, + 0.5 + ] + ], + 15, + [ + "literal", + [ + 4, + 0.5 + ] + ], + 16, + [ + "literal", + [ + 4, + 0.45 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "bridge-path-cycleway-piste", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "match", + [ + "get", + "type" + ], + [ + "cycleway", + "piste" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": {}, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 18, + 4 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + 10, + 0 + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "bridge-path", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "class" + ], + "path" + ], + [ + "!=", + [ + "get", + "type" + ], + "steps" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": {}, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 18, + 4 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 4, + 0.3 + ] + ], + 15, + [ + "literal", + [ + 1.75, + 0.3 + ] + ], + 16, + [ + "literal", + [ + 1, + 0.3 + ] + ], + 17, + [ + "literal", + [ + 1, + 0.25 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "bridge-steps", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "type" + ], + "steps" + ], + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 15, + 1, + 16, + 1.6, + 18, + 6 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 1, + 0 + ] + ], + 15, + [ + "literal", + [ + 1.75, + 1 + ] + ], + 16, + [ + "literal", + [ + 1, + 0.75 + ] + ], + 17, + [ + "literal", + [ + 0.3, + 0.3 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "bridge-pedestrian", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "class" + ], + "pedestrian" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.5, + 18, + 12 + ], + "line-color": "hsl(0, 0%, 95%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 1, + 0 + ] + ], + 15, + [ + "literal", + [ + 1.5, + 0.4 + ] + ], + 16, + [ + "literal", + [ + 1, + 0.2 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "gate-label", + "type": "symbol", + "source": "composite", + "source-layer": "structure", + "minzoom": 16, + "filter": [ + "==", + [ + "get", + "class" + ], + "gate" + ], + "layout": { + "icon-image": [ + "match", + [ + "get", + "type" + ], + "gate", + "gate", + "lift_gate", + "lift-gate", + "" + ] + }, + "paint": {}, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., barriers-bridges" + } + }, + { + "id": "bridge-minor-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "track" + ], + true, + "service", + [ + "step", + [ + "zoom" + ], + false, + 14, + true + ], + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "track", + "hsl(35, 80%, 48%)", + "hsl(60, 10%, 70%)" + ], + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 18, + 10, + 22, + 100 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-street-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "street", + "street_limited" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "track", + "hsl(35, 80%, 48%)", + "hsl(60, 10%, 70%)" + ], + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.5, + 18, + 20, + 22, + 200 + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 14, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-minor-link-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "primary_link", + "secondary_link", + "tertiary_link" + ], + true, + false + ], + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.4, + 18, + 18, + 22, + 180 + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 11, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-secondary-tertiary-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 11, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "secondary", + "tertiary" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0, + 18, + 26, + 22, + 260 + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 10, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-primary-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 10, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "class" + ], + "primary" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 28, + 22, + 280 + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 10, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-major-link-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "<=", + [ + "get", + "layer" + ], + 1 + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 82%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.8, + 18, + 20, + 22, + 200 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-motorway-trunk-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + [ + "<=", + [ + "get", + "layer" + ], + 1 + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 82%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 30, + 22, + 300 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-construction", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "class" + ], + "construction" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 2, + 18, + 20, + 22, + 200 + ], + "line-color": "hsl(60, 10%, 70%)", + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 0.4, + 0.8 + ] + ], + 15, + [ + "literal", + [ + 0.3, + 0.6 + ] + ], + 16, + [ + "literal", + [ + 0.2, + 0.3 + ] + ], + 17, + [ + "literal", + [ + 0.2, + 0.25 + ] + ], + 18, + [ + "literal", + [ + 0.15, + 0.15 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-minor", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "track" + ], + true, + "service", + [ + "step", + [ + "zoom" + ], + false, + 14, + true + ], + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 18, + 10, + 22, + 100 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-minor-link", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "primary_link", + "secondary_link", + "tertiary_link" + ], + true, + false + ], + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] ], - false, - 14, - true - ], - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 1, - 18, - 10, - 22, - 100 - ], - "line-color": [ - "match", - [ - "get", - "class" - ], - "street_limited", - "hsl(60, 22%, 80%)", - "hsl(0, 0%, 95%)" - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" - } - }, - { - "id": "tunnel-minor-link", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "primary_link", - "secondary_link", - "tertiary_link" - ], - true, - false - ], - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 13, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 13, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.4, - 18, - 18, - 22, - 180 - ], - "line-color": "hsl(0, 0%, 95%)" - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" - } - }, - { - "id": "tunnel-major-link", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 12, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "motorway_link", - "trunk_link" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.8, - 18, - 20, - 22, - 200 - ], - "line-color": [ - "match", - [ - "get", - "class" - ], - "motorway_link", - "hsl(15, 100%, 85%)", - "hsl(35, 78%, 85%)" - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" - } - }, - { - "id": "tunnel-street", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "street", - "street_limited" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.5, - 18, - 20, - 22, - 200 - ], - "line-color": [ - "match", - [ - "get", - "class" - ], - "street_limited", - "hsl(60, 22%, 80%)", - "hsl(0, 0%, 95%)" - ], - "line-opacity": [ - "step", - [ - "zoom" - ], - 0, - 14, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" - } - }, - { - "id": "tunnel-street-low", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "maxzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "street", - "street_limited" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.5, - 18, - 20, - 22, - 200 - ], - "line-color": "hsl(0, 0%, 95%)" - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" - } - }, - { - "id": "tunnel-secondary-tertiary", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "secondary", - "tertiary" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0, - 18, - 26, - 22, - 260 - ], - "line-color": "hsl(0, 0%, 95%)" - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" - } - }, - { - "id": "tunnel-primary", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "==", - [ - "get", - "class" - ], - "primary" - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0.8, - 18, - 28, - 22, - 280 - ], - "line-color": "hsl(0, 0%, 95%)" - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" - } - }, - { - "id": "tunnel-motorway-trunk", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "motorway", - "trunk" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0.8, - 18, - 30, - 22, - 300 - ], - "line-color": [ - "match", - [ - "get", - "class" - ], - "motorway", - "hsl(15, 100%, 85%)", - "hsl(35, 78%, 85%)" - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" - } - }, - { - "id": "tunnel-oneway-arrow-blue", - "type": "symbol", - "source": "composite", - "source-layer": "road", - "minzoom": 16, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "==", - [ - "get", - "oneway" - ], - "true" - ], - [ - "step", - [ - "zoom" - ], - [ - "match", - [ - "get", - "class" + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.4, + 18, + 18, + 22, + 180 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-major-link", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "<=", + [ + "get", + "layer" + ], + 1 + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] ], - [ - "primary", - "secondary", - "street", - "street_limited", - "tertiary" - ], - true, - false - ], - 16, - [ - "match", - [ - "get", - "class" + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 13, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.8, + 18, + 20, + 22, + 200 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "motorway_link", + "hsl(15, 100%, 75%)", + "hsl(35, 89%, 75%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-street", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "street", + "street_limited" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] ], - [ - "primary", - "secondary", - "tertiary", - "street", - "street_limited", - "primary_link", - "secondary_link", - "tertiary_link", - "service", - "track" - ], - true, - false - ] - ] - ], - "layout": { - "symbol-placement": "line", - "icon-image": [ - "step", - [ - "zoom" - ], - "oneway-small", - 18, - "oneway-large" - ], - "symbol-spacing": 200, - "icon-rotation-alignment": "map", - "icon-allow-overlap": true, - "icon-ignore-placement": true - }, - "paint": {}, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" - } - }, - { - "id": "tunnel-oneway-arrow-white", - "type": "symbol", - "source": "composite", - "source-layer": "road", - "minzoom": 16, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "tunnel" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "motorway", - "motorway_link", - "trunk", - "trunk_link" - ], - true, - false - ], - [ - "==", - [ - "get", - "oneway" - ], - "true" - ] - ], - "layout": { - "symbol-placement": "line", - "icon-image": [ - "step", - [ - "zoom" - ], - "oneway-white-small", - 18, - "oneway-white-large" - ], - "symbol-spacing": 200, - "icon-rotation-alignment": "map", - "icon-allow-overlap": true, - "icon-ignore-placement": true - }, - "paint": {}, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" - } - }, - { - "id": "cliff", - "type": "line", - "source": "composite", - "source-layer": "structure", - "minzoom": 15, - "filter": [ - "==", - [ - "get", - "class" - ], - "cliff" - ], - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "paint": { - "line-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 15, - 0, - 15.25, - 1 - ], - "line-width": 10, - "line-pattern": "cliff" - }, - "metadata": { - "mapbox:featureComponent": "terrain", - "mapbox:group": "Terrain, surface" - } - }, - { - "id": "ferry", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 8, - "filter": [ - "==", - [ - "get", - "type" - ], - "ferry" - ], - "paint": { - "line-color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 15, - "hsl(214, 68%, 63%)", - 17, - "hsl(239, 68%, 63%)" - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.5, - 20, - 1 - ], - "line-dasharray": [ - "step", - [ - "zoom" - ], - [ - "literal", - [ - 1, - 0 - ] - ], - 13, - [ - "literal", - [ - 12, - 4 - ] - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, ferries" - } - }, - { - "id": "ferry-auto", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 8, - "filter": [ - "==", - [ - "get", - "type" - ], - "ferry_auto" - ], - "paint": { - "line-color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 15, - "hsl(214, 68%, 63%)", - 17, - "hsl(239, 68%, 63%)" - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.5, - 20, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, ferries" - } - }, - { - "id": "road-pedestrian-polygon-fill", - "type": "fill", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "path", - "pedestrian" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "case", - [ - "has", - "layer" - ], - [ - ">=", - [ - "get", - "layer" + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.5, + 18, + 20, + 22, + 200 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "street_limited", + "hsl(60, 22%, 80%)", + "hsl(0, 0%, 95%)" + ], + "line-opacity": [ + "step", + [ + "zoom" + ], + 0, + 14, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-street-low", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "maxzoom": 14, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "street", + "street_limited" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] ], - 0 - ], - true - ], - [ - "==", - [ - "geometry-type" - ], - "Polygon" - ] - ], - "paint": { - "fill-color": "hsl(60, 20%, 85%)" - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" - } - }, - { - "id": "road-pedestrian-polygon-pattern", - "type": "fill", - "source": "composite", - "source-layer": "road", - "minzoom": 16, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "path", - "pedestrian" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "case", - [ - "has", - "layer" - ], - [ - ">=", - [ - "get", - "layer" + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ], + "line-join": [ + "step", + [ + "zoom" + ], + "miter", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.5, + 18, + 20, + 22, + 200 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-secondary-tertiary", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "secondary", + "tertiary" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0, + 18, + 26, + 22, + 260 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-primary", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "class" + ], + "primary" + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] + ], + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 28, + 22, + 280 + ], + "line-color": "hsl(0, 0%, 95%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-motorway-trunk", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + [ + "<=", + [ + "get", + "layer" + ], + 1 + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] ], - 0 - ], - true - ], - [ - "==", - [ - "geometry-type" - ], - "Polygon" - ] - ], - "paint": { - "fill-pattern": "pedestrian-polygon", - "fill-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 16, - 0, - 17, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" - } - }, - { - "id": "road-path-bg", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 12, - "filter": [ - "all", - [ - "==", - [ - "get", - "class" - ], - "path" - ], - [ - "step", - [ - "zoom" - ], - [ - "!", - [ - "match", - [ - "get", - "type" - ], - [ - "steps", - "sidewalk", - "crossing" - ], - true, - false - ] - ], - 16, - [ - "!=", - [ - "get", - "type" + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 30, + 22, + 300 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "motorway", + "hsl(15, 100%, 75%)", + "hsl(35, 89%, 75%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-major-link-2-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + ">=", + [ + "get", + "layer" + ], + 2 + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] ], - "steps" - ] - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 15, - 2, - 18, - 7 - ], - "line-color": [ - "match", - [ - "get", - "type" - ], - "piste", - "hsl(215, 80%, 48%)", - [ - "mountain_bike", - "hiking", - "trail", - "cycleway", - "footway", - "path", - "bridleway" - ], - "hsl(35, 80%, 48%)", - "hsl(60, 1%, 64%)" - ] - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" - } - }, - { - "id": "road-steps-bg", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "type" - ], - "steps" - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-join": "round" - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 15, - 2, - 17, - 4.6, - 18, - 7 - ], - "line-color": "hsl(35, 80%, 48%)", - "line-opacity": 0.75 - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" - } - }, - { - "id": "road-pedestrian-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "class" - ], - "pedestrian" - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "case", - [ - "has", - "layer" - ], - [ - ">=", - [ - "get", - "layer" + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.8, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 82%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.8, + 18, + 20, + 22, + 200 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-motorway-trunk-2-case", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + ">=", + [ + "get", + "layer" + ], + 2 + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] ], - 0 - ], - true - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 2, - 18, - 14.5 - ], - "line-color": "hsl(60, 10%, 70%)" - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" - } - }, - { - "id": "road-path-trail", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 12, - "filter": [ - "all", - [ - "==", - [ - "get", - "class" - ], - "path" - ], - [ - "match", - [ - "get", - "type" - ], - [ - "hiking", - "mountain_bike", - "trail" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 15, - 1, - 18, - 4 - ], - "line-color": "hsl(0, 0%, 95%)", - "line-dasharray": [ - "step", - [ - "zoom" - ], - [ - "literal", - [ - 5, - 0.5 - ] - ], - 15, - [ - "literal", - [ - 4, - 0.5 - ] - ], - 16, - [ - "literal", - [ - 4, - 0.45 - ] - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" - } - }, - { - "id": "road-path-cycleway-piste", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 12, - "filter": [ - "all", - [ - "==", - [ - "get", - "class" - ], - "path" - ], - [ - "match", - [ - "get", - "type" - ], - [ - "cycleway", - "piste" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 15, - 1, - 18, - 4 - ], - "line-color": "hsl(0, 0%, 95%)", - "line-dasharray": [ - 10, - 0 - ] - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" - } - }, - { - "id": "road-path", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 12, - "filter": [ - "all", - [ - "==", - [ - "get", - "class" - ], - "path" - ], - [ - "step", - [ - "zoom" - ], - [ - "!", - [ - "match", - [ - "get", - "type" - ], - [ - "steps", - "sidewalk", - "crossing" - ], - true, - false - ] - ], - 16, - [ - "!=", - [ - "get", - "type" + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 22, + 2 + ], + "line-color": "hsl(60, 10%, 82%)", + "line-gap-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 30, + 22, + 300 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-major-link-2", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + ">=", + [ + "get", + "layer" + ], + 2 + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] ], - "steps" - ] - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 13, - 0.5, - 14, - 1, - 15, - 1, - 18, - 4 - ], - "line-color": "hsl(0, 0%, 95%)", - "line-dasharray": [ - "step", - [ - "zoom" - ], - [ - "literal", - [ - 4, - 0.3 - ] - ], - 15, - [ - "literal", - [ - 1.75, - 0.3 - ] - ], - 16, - [ - "literal", - [ - 1, - 0.3 - ] - ], - 17, - [ - "literal", - [ - 1, - 0.25 - ] - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" - } - }, - { - "id": "road-steps", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "type" - ], - "steps" - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-join": "round" - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 15, - 1, - 16, - 1.6, - 18, - 6 - ], - "line-color": "hsl(0, 0%, 95%)", - "line-dasharray": [ - "step", - [ - "zoom" - ], - [ - "literal", - [ - 1, - 0 - ] - ], - 15, - [ - "literal", - [ - 1.75, - 1 - ] - ], - 16, - [ - "literal", - [ - 1, - 0.75 - ] - ], - 17, - [ - "literal", - [ - 0.3, - 0.3 - ] - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" - } - }, - { - "id": "road-pedestrian", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 12, - "filter": [ - "all", - [ - "==", - [ - "get", - "class" - ], - "pedestrian" - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "case", - [ - "has", - "layer" - ], - [ - ">=", - [ - "get", - "layer" + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 13, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 12, + 0.8, + 18, + 20, + 22, + 200 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "motorway_link", + "hsl(15, 100%, 75%)", + "hsl(35, 89%, 75%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-motorway-trunk-2", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + ">=", + [ + "get", + "layer" + ], + 2 + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + true, + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] ], - 0 - ], - true - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.5, - 18, - 12 - ], - "line-color": "hsl(0, 0%, 95%)", - "line-dasharray": [ - "step", - [ - "zoom" - ], - [ - "literal", - [ - 1, - 0 - ] - ], - 15, - [ - "literal", - [ - 1.5, - 0.4 - ] - ], - 16, - [ - "literal", - [ - 1, - 0.2 - ] - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" - } - }, - { - "id": "golf-hole-line", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 16, - "filter": [ - "==", - [ - "get", - "class" - ], - "golf" - ], - "paint": { - "line-color": "hsl(98, 26%, 56%)" - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" - } - }, - { - "id": "road-polygon", - "type": "fill", - "source": "composite", - "source-layer": "road", - "minzoom": 12, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "primary", - "secondary", - "tertiary", - "primary_link", - "secondary_link", - "tertiary_link", - "trunk", - "trunk_link", - "street", - "street_limited", - "track", - "service" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "Polygon" - ] - ], - "paint": { - "fill-color": "hsl(0, 0%, 95%)", - "fill-outline-color": "hsl(60, 10%, 70%)" - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" - } - }, - { - "id": "turning-feature-outline", - "type": "circle", - "source": "composite", - "source-layer": "road", - "minzoom": 15, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "turning_circle", - "turning_loop" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "Point" - ] - ], - "paint": { - "circle-radius": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 15, - 4.5, - 16, - 8, - 18, - 20, - 22, - 200 - ], - "circle-color": "hsl(0, 0%, 95%)", - "circle-stroke-width": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 15, - 0.8, - 16, - 1.2, - 18, - 2 - ], - "circle-stroke-color": "hsl(60, 10%, 70%)", - "circle-pitch-alignment": "map" - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" - } - }, - { - "id": "road-minor-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "track" - ], - true, - "service", - [ - "step", - [ - "zoom" + "layout": { + "line-cap": [ + "step", + [ + "zoom" + ], + "butt", + 14, + "round" + ] + }, + "paint": { + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 3, + 0.8, + 18, + 30, + 22, + 300 + ], + "line-color": [ + "match", + [ + "get", + "class" + ], + "motorway", + "hsl(15, 100%, 75%)", + "hsl(35, 89%, 75%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-oneway-arrow-blue", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "==", + [ + "get", + "oneway" + ], + "true" + ], + [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "primary", + "secondary", + "tertiary", + "street", + "street_limited" + ], + true, + false + ], + 16, + [ + "match", + [ + "get", + "class" + ], + [ + "primary", + "secondary", + "tertiary", + "street", + "street_limited", + "primary_link", + "secondary_link", + "tertiary_link", + "service", + "track" + ], + true, + false + ] + ] ], - false, - 14, - true - ], - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.8, - 22, - 2 - ], - "line-color": [ - "match", - [ - "get", - "class" - ], - "track", - "hsl(35, 80%, 48%)", - "hsl(60, 10%, 70%)" - ], - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 1, - 18, - 10, - 22, - 100 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" - } - }, - { - "id": "road-street-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "street", - "street_limited" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.8, - 22, - 2 - ], - "line-color": "hsl(60, 10%, 70%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.5, - 18, - 20, - 22, - 200 - ], - "line-opacity": [ - "step", - [ - "zoom" - ], - 0, - 14, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" - } - }, - { - "id": "road-minor-link-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "primary_link", - "secondary_link", - "tertiary_link" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.8, - 22, - 2 - ], - "line-color": "hsl(60, 10%, 70%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.4, - 18, - 18, - 22, - 180 - ], - "line-opacity": [ - "step", - [ - "zoom" - ], - 0, - 11, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" - } - }, - { - "id": "road-secondary-tertiary-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 11, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "secondary", - "tertiary" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.8, - 22, - 2 - ], - "line-color": "hsl(60, 10%, 70%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0, - 18, - 26, - 22, - 260 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" - } - }, - { - "id": "road-primary-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 10, - "filter": [ - "all", - [ - "==", - [ - "get", - "class" - ], - "primary" - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 1, - 22, - 2 - ], - "line-color": "hsl(60, 10%, 70%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0.8, - 18, - 28, - 22, - 280 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" - } - }, - { - "id": "road-major-link-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 12, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "motorway_link", - "trunk_link" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.8, - 22, - 2 - ], - "line-color": "hsl(60, 10%, 82%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.8, - 18, - 20, - 22, - 200 - ], - "line-opacity": [ - "step", - [ - "zoom" - ], - 0, - 11, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" - } - }, - { - "id": "road-motorway-trunk-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 3, - "filter": [ - "all", - [ - "step", - [ - "zoom" - ], - [ - "match", - [ - "get", - "class" + "layout": { + "symbol-placement": "line", + "icon-image": [ + "step", + [ + "zoom" + ], + "oneway-small", + 18, + "oneway-large" + ], + "symbol-spacing": 200, + "icon-rotation-alignment": "map", + "icon-allow-overlap": true, + "icon-ignore-placement": true + }, + "paint": {}, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-oneway-arrow-white", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk", + "motorway_link", + "trunk_link" + ], + true, + false + ], + [ + "==", + [ + "get", + "oneway" + ], + "true" + ] ], - [ - "motorway", - "trunk" - ], - true, - false - ], - 5, - [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "motorway", - "trunk" - ], - true, - false + "layout": { + "symbol-placement": "line", + "icon-image": "oneway-white-small", + "symbol-spacing": 200, + "icon-rotation-alignment": "map", + "icon-allow-overlap": true, + "icon-ignore-placement": true + }, + "paint": {}, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, bridges" + } + }, + { + "id": "bridge-rail", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "major_rail", + "minor_rail" + ], + true, + false + ] ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ] - ] - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 1, - 22, - 2 - ], - "line-color": "hsl(60, 10%, 82%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0.8, - 18, - 30, - 22, - 300 - ], - "line-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 3, - 0, - 3.5, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" - } - }, - { - "id": "turning-feature", - "type": "circle", - "source": "composite", - "source-layer": "road", - "minzoom": 15, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "turning_circle", - "turning_loop" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "Point" - ] - ], - "paint": { - "circle-radius": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 15, - 4.5, - 16, - 8, - 18, - 20, - 22, - 200 - ], - "circle-color": "hsl(0, 0%, 95%)", - "circle-pitch-alignment": "map" - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" - } - }, - { - "id": "road-construction", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "class" - ], - "construction" - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 2, - 18, - 20, - 22, - 200 - ], - "line-color": "hsl(0, 0%, 95%)", - "line-dasharray": [ - "step", - [ - "zoom" - ], - [ - "literal", - [ - 0.4, - 0.8 - ] - ], - 15, - [ - "literal", - [ - 0.3, - 0.6 - ] - ], - 16, - [ - "literal", - [ - 0.2, - 0.3 - ] - ], - 17, - [ - "literal", - [ - 0.2, - 0.25 - ] - ], - 18, - [ - "literal", - [ - 0.15, - 0.15 - ] - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" - } - }, - { - "id": "road-minor", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "track" - ], - true, - "service", - [ - "step", - [ - "zoom" + "paint": { + "line-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 13, + "hsl(75, 25%, 68%)", + 16, + "hsl(60, 0%, 56%)" + ], + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 0.5, + 20, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, bridges" + } + }, + { + "id": "bridge-rail-tracks", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 13, + "filter": [ + "all", + [ + "==", + [ + "get", + "structure" + ], + "bridge" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "major_rail", + "minor_rail" + ], + true, + false + ] ], - false, - 14, - true - ], - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 1, - 18, - 10, - 22, - 100 - ], - "line-color": "hsl(0, 0%, 95%)" - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" - } - }, - { - "id": "road-minor-link", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 12, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "primary_link", - "secondary_link", - "tertiary_link" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 13, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 13, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.4, - 18, - 18, - 22, - 180 - ], - "line-color": "hsl(0, 0%, 95%)" - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" - } - }, - { - "id": "road-major-link", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 12, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "motorway_link", - "trunk_link" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 13, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 13, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.8, - 18, - 20, - 22, - 200 - ], - "line-color": [ - "match", - [ - "get", - "class" - ], - "motorway_link", - "hsl(15, 100%, 75%)", - "hsl(35, 89%, 75%)" - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" - } - }, - { - "id": "road-street", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "street", - "street_limited" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.5, - 18, - 20, - 22, - 200 - ], - "line-color": [ - "match", - [ - "get", - "class" - ], - "street_limited", - "hsl(60, 22%, 80%)", - "hsl(0, 0%, 95%)" - ], - "line-opacity": [ - "step", - [ - "zoom" - ], - 0, - 14, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" - } - }, - { - "id": "road-street-low", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 11, - "maxzoom": 14, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "street", - "street_limited" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.5, - 18, - 20, - 22, - 200 - ], - "line-color": "hsl(0, 0%, 95%)" - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" - } - }, - { - "id": "road-secondary-tertiary", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 9, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "secondary", - "tertiary" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0, - 18, - 26, - 22, - 260 - ], - "line-color": "hsl(0, 0%, 95%)" - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" - } - }, - { - "id": "road-primary", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 6, - "filter": [ - "all", - [ - "==", - [ - "get", - "class" - ], - "primary" - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0.8, - 18, - 28, - 22, - 280 - ], - "line-color": "hsl(0, 0%, 95%)" - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" - } - }, - { - "id": "road-motorway-trunk", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 3, - "filter": [ - "all", - [ - "step", - [ - "zoom" - ], - [ - "match", - [ - "get", - "class" + "paint": { + "line-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 13, + "hsl(75, 25%, 68%)", + 16, + "hsl(60, 0%, 56%)" + ], + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 4, + 20, + 8 + ], + "line-dasharray": [ + 0.1, + 15 + ], + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 13.75, + 0, + 14, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, bridges" + } + }, + { + "id": "aerialway", + "type": "line", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "==", + [ + "get", + "class" + ], + "aerialway" ], - [ - "motorway", - "trunk" - ], - true, - false - ], - 5, - [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "motorway", - "trunk" - ], - true, - false + "paint": { + "line-color": "hsl(230, 50%, 60%)", + "line-width": [ + "interpolate", + [ + "exponential", + 1.5 + ], + [ + "zoom" + ], + 14, + 1, + 20, + 2 + ], + "line-dasharray": [ + 4, + 1 + ] + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, elevated" + } + }, + { + "id": "admin-1-boundary-bg", + "type": "line", + "source": "composite", + "source-layer": "admin", + "minzoom": 7, + "filter": [ + "all", + [ + "==", + [ + "get", + "admin_level" + ], + 1 + ], + [ + "==", + [ + "get", + "maritime" + ], + "false" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ] ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ] - ] - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 13, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 13, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0.8, - 18, - 30, - 22, - 300 - ], - "line-color": [ - "step", - [ - "zoom" - ], - [ - "match", - [ - "get", - "class" - ], - "motorway", - "hsl(15, 88%, 69%)", - "trunk", - "hsl(35, 81%, 59%)", - "hsl(60, 18%, 85%)" - ], - 9, - [ - "match", - [ - "get", - "class" + "paint": { + "line-color": "hsl(350, 90%, 88%)", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 3, + 12, + 6 + ], + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 7, + 0, + 8, + 0.5 + ], + "line-dasharray": [ + 1, + 0 + ], + "line-blur": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 0, + 12, + 3 + ] + }, + "metadata": { + "mapbox:featureComponent": "admin-boundaries", + "mapbox:group": "Administrative boundaries, admin" + } + }, + { + "id": "admin-0-boundary-bg", + "type": "line", + "source": "composite", + "source-layer": "admin", + "minzoom": 1, + "filter": [ + "all", + [ + "==", + [ + "get", + "admin_level" + ], + 0 + ], + [ + "==", + [ + "get", + "maritime" + ], + "false" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ] ], - "motorway", - "hsl(15, 100%, 75%)", - "hsl(35, 89%, 75%)" - ] - ], - "line-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 3, - 0, - 3.5, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" - } - }, - { - "id": "road-rail", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "major_rail", - "minor_rail" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ] - ], - "paint": { - "line-color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 13, - "hsl(75, 25%, 68%)", - 16, - "hsl(60, 0%, 56%)" - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.5, - 20, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, surface" - } - }, - { - "id": "road-rail-tracks", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "major_rail", - "minor_rail" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ] - ], - "paint": { - "line-color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 13, - "hsl(75, 25%, 68%)", - 16, - "hsl(60, 0%, 56%)" - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 4, - 20, - 8 - ], - "line-dasharray": [ - 0.1, - 15 - ], - "line-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 13.75, - 0, - 14, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, surface" - } - }, - { - "id": "level-crossing", - "type": "symbol", - "source": "composite", - "source-layer": "road", - "minzoom": 16, - "filter": [ - "==", - [ - "get", - "class" - ], - "level_crossing" - ], - "layout": { - "icon-image": "level-crossing", - "icon-rotation-alignment": "map", - "icon-allow-overlap": true, - "icon-ignore-placement": true - }, - "paint": {}, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface-icons" - } - }, - { - "id": "road-oneway-arrow-blue", - "type": "symbol", - "source": "composite", - "source-layer": "road", - "minzoom": 16, - "filter": [ - "all", - [ - "==", - [ - "get", - "oneway" - ], - "true" - ], - [ - "step", - [ - "zoom" - ], - [ - "match", - [ - "get", - "class" + "paint": { + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 4, + 12, + 8 + ], + "line-color": "hsl(350, 90%, 88%)", + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 0, + 4, + 0.5 + ], + "line-blur": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 0, + 12, + 2 + ] + }, + "metadata": { + "mapbox:featureComponent": "admin-boundaries", + "mapbox:group": "Administrative boundaries, admin" + } + }, + { + "id": "admin-1-boundary", + "type": "line", + "source": "composite", + "source-layer": "admin", + "minzoom": 2, + "filter": [ + "all", + [ + "==", + [ + "get", + "admin_level" + ], + 1 + ], + [ + "==", + [ + "get", + "maritime" + ], + "false" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ] ], - [ - "primary", - "secondary", - "tertiary", - "street", - "street_limited" - ], - true, - false - ], - 16, - [ - "match", - [ - "get", - "class" + "layout": {}, + "paint": { + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 2, + 0 + ] + ], + 7, + [ + "literal", + [ + 2, + 2, + 6, + 2 + ] + ] + ], + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 0.3, + 12, + 1.5 + ], + "line-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 2, + 0, + 3, + 1 + ], + "line-color": "hsl(350, 30%, 55%)" + }, + "metadata": { + "mapbox:featureComponent": "admin-boundaries", + "mapbox:group": "Administrative boundaries, admin" + } + }, + { + "id": "admin-0-boundary", + "type": "line", + "source": "composite", + "source-layer": "admin", + "minzoom": 1, + "filter": [ + "all", + [ + "==", + [ + "get", + "admin_level" + ], + 0 + ], + [ + "==", + [ + "get", + "disputed" + ], + "false" + ], + [ + "==", + [ + "get", + "maritime" + ], + "false" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ] ], - [ - "primary", - "secondary", - "tertiary", - "street", - "street_limited", - "primary_link", - "secondary_link", - "tertiary_link", - "service", - "track" - ], - true, - false - ] - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ] - ], - "layout": { - "symbol-placement": "line", - "icon-image": [ - "step", - [ - "zoom" - ], - "oneway-small", - 18, - "oneway-large" - ], - "symbol-spacing": 200, - "icon-rotation-alignment": "map", - "icon-allow-overlap": true, - "icon-ignore-placement": true - }, - "paint": {}, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface-icons" - } - }, - { - "id": "road-oneway-arrow-white", - "type": "symbol", - "source": "composite", - "source-layer": "road", - "minzoom": 16, - "filter": [ - "all", - [ - "==", - [ - "get", - "oneway" - ], - "true" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "motorway", - "trunk", - "motorway_link", - "trunk_link" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "none", - "ford" - ], - true, - false - ] - ], - "layout": { - "symbol-placement": "line", - "icon-image": [ - "step", - [ - "zoom" - ], - "oneway-white-small", - 18, - "oneway-white-large" - ], - "symbol-spacing": 200, - "icon-rotation-alignment": "map", - "icon-allow-overlap": true, - "icon-ignore-placement": true - }, - "paint": {}, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface-icons" - } - }, - { - "id": "crosswalks", - "type": "symbol", - "source": "composite", - "source-layer": "structure", - "minzoom": 17, - "filter": [ - "all", - [ - "==", - [ - "get", - "type" - ], - "crosswalk" - ], - [ - "==", - [ - "geometry-type" - ], - "Point" - ] - ], - "layout": { - "icon-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 16, - 0.1, - 18, - 0.2, - 19, - 0.5, - 22, - 1.5 - ], - "icon-image": [ - "step", - [ - "zoom" - ], - "crosswalk-small", - 18, - "crosswalk-large" - ], - "icon-rotate": [ - "get", - "direction" - ], - "icon-rotation-alignment": "map", - "icon-allow-overlap": true, - "icon-ignore-placement": true - }, - "paint": {}, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface-icons" - } - }, - { - "id": "gate-fence-hedge", - "type": "line", - "source": "composite", - "source-layer": "structure", - "minzoom": 16, - "filter": [ - "match", - [ - "get", - "class" - ], - [ - "gate", - "fence", - "hedge" - ], - true, - false - ], - "layout": {}, - "paint": { - "line-color": [ - "match", - [ - "get", - "class" - ], - "hedge", - "hsl(98, 32%, 56%)", - "hsl(60, 25%, 63%)" - ], - "line-width": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 16, - 1, - 20, - 3 - ], - "line-opacity": [ - "match", - [ - "get", - "class" - ], - "gate", - 0.5, - 1 - ], - "line-dasharray": [ - 1, - 2, - 5, - 2, - 1, - 2 - ] - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" - } - }, - { - "id": "bridge-path-bg", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "==", - [ - "get", - "class" - ], - "path" - ], - [ - "step", - [ - "zoom" - ], - [ - "!", - [ - "match", - [ - "get", - "type" - ], - [ - "steps", - "sidewalk", - "crossing" - ], - true, - false - ] - ], - 16, - [ - "!=", - [ - "get", - "type" + "layout": {}, + "paint": { + "line-color": "hsl(350, 30%, 50%)", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 0.5, + 12, + 2 + ], + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 2, + 0 + ] + ], + 7, + [ + "literal", + [ + 2, + 2, + 6, + 2 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "admin-boundaries", + "mapbox:group": "Administrative boundaries, admin" + } + }, + { + "id": "admin-0-boundary-disputed", + "type": "line", + "source": "composite", + "source-layer": "admin", + "minzoom": 1, + "filter": [ + "all", + [ + "==", + [ + "get", + "disputed" + ], + "true" + ], + [ + "==", + [ + "get", + "admin_level" + ], + 0 + ], + [ + "==", + [ + "get", + "maritime" + ], + "false" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ] ], - "steps" - ] - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 15, - 2, - 18, - 7 - ], - "line-color": [ - "match", - [ - "get", - "type" - ], - "piste", - "hsl(215, 80%, 48%)", - [ - "mountain_bike", - "hiking", - "trail", - "cycleway", - "footway", - "path", - "bridleway" - ], - "hsl(35, 80%, 48%)", - "hsl(60, 1%, 64%)" - ] - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" - } - }, - { - "id": "bridge-steps-bg", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "type" - ], - "steps" - ], - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 15, - 2, - 17, - 4.6, - 18, - 7 - ], - "line-color": "hsl(35, 80%, 48%)", - "line-opacity": 0.75 - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" - } - }, - { - "id": "bridge-pedestrian-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "==", - [ - "get", - "class" - ], - "pedestrian" - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 2, - 18, - 14.5 - ], - "line-color": "hsl(60, 10%, 70%)" - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" - } - }, - { - "id": "bridge-path-trail", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "==", - [ - "get", - "class" - ], - "path" - ], - [ - "match", - [ - "get", - "type" - ], - [ - "hiking", - "mountain_bike", - "trail" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": {}, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 15, - 1, - 18, - 4 - ], - "line-color": "hsl(0, 0%, 95%)", - "line-dasharray": [ - "step", - [ - "zoom" - ], - [ - "literal", - [ - 5, - 0.5 - ] - ], - 15, - [ - "literal", - [ - 4, - 0.5 - ] - ], - 16, - [ - "literal", - [ - 4, - 0.45 - ] - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" - } - }, - { - "id": "bridge-path-cycleway-piste", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "==", - [ - "get", - "class" - ], - "path" - ], - [ - "match", - [ - "get", - "type" - ], - [ - "cycleway", - "piste" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": {}, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 15, - 1, - 18, - 4 - ], - "line-color": "hsl(0, 0%, 95%)", - "line-dasharray": [ - 10, - 0 - ] - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" - } - }, - { - "id": "bridge-path", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "==", - [ - "get", - "class" - ], - "path" - ], - [ - "!=", - [ - "get", - "type" - ], - "steps" - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": {}, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 15, - 1, - 18, - 4 - ], - "line-color": "hsl(0, 0%, 95%)", - "line-dasharray": [ - "step", - [ - "zoom" - ], - [ - "literal", - [ - 4, - 0.3 - ] - ], - 15, - [ - "literal", - [ - 1.75, - 0.3 - ] - ], - 16, - [ - "literal", - [ - 1, - 0.3 - ] - ], - 17, - [ - "literal", - [ - 1, - 0.25 - ] - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" - } - }, - { - "id": "bridge-steps", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "type" - ], - "steps" - ], - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 15, - 1, - 16, - 1.6, - 18, - 6 - ], - "line-color": "hsl(0, 0%, 95%)", - "line-dasharray": [ - "step", - [ - "zoom" - ], - [ - "literal", - [ - 1, - 0 - ] - ], - 15, - [ - "literal", - [ - 1.75, - 1 - ] - ], - 16, - [ - "literal", - [ - 1, - 0.75 - ] - ], - 17, - [ - "literal", - [ - 0.3, - 0.3 - ] - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" - } - }, - { - "id": "bridge-pedestrian", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "==", - [ - "get", - "class" - ], - "pedestrian" - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.5, - 18, - 12 - ], - "line-color": "hsl(0, 0%, 95%)", - "line-dasharray": [ - "step", - [ - "zoom" - ], - [ - "literal", - [ - 1, - 0 - ] - ], - 15, - [ - "literal", - [ - 1.5, - 0.4 - ] - ], - 16, - [ - "literal", - [ - 1, - 0.2 - ] - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" - } - }, - { - "id": "gate-label", - "type": "symbol", - "source": "composite", - "source-layer": "structure", - "minzoom": 16, - "filter": [ - "==", - [ - "get", - "class" - ], - "gate" - ], - "layout": { - "icon-image": [ - "match", - [ - "get", - "type" - ], - "gate", - "gate", - "lift_gate", - "lift-gate", - "" - ] - }, - "paint": {}, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" - } - }, - { - "id": "bridge-minor-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "track" - ], - true, - "service", - [ - "step", - [ - "zoom" + "paint": { + "line-color": "hsl(350, 30%, 50%)", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 3, + 0.5, + 12, + 2 + ], + "line-dasharray": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 3, + 2, + 5 + ] + ], + 7, + [ + "literal", + [ + 2, + 1.5 + ] + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "admin-boundaries", + "mapbox:group": "Administrative boundaries, admin" + } + }, + { + "id": "contour-label", + "type": "symbol", + "source": "composite", + "source-layer": "contour", + "minzoom": 11, + "filter": [ + "any", + [ + "==", + [ + "get", + "index" + ], + 10 + ], + [ + "==", + [ + "get", + "index" + ], + 5 + ] ], - false, - 14, - true - ], - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.8, - 22, - 2 - ], - "line-color": [ - "match", - [ - "get", - "class" - ], - "track", - "hsl(35, 80%, 48%)", - "hsl(60, 10%, 70%)" - ], - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 1, - 18, - 10, - 22, - 100 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-street-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "street", - "street_limited" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.8, - 22, - 2 - ], - "line-color": [ - "match", - [ - "get", - "class" - ], - "track", - "hsl(35, 80%, 48%)", - "hsl(60, 10%, 70%)" - ], - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.5, - 18, - 20, - 22, - 200 - ], - "line-opacity": [ - "step", - [ - "zoom" - ], - 0, - 14, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-minor-link-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "primary_link", - "secondary_link", - "tertiary_link" - ], - true, - false - ], - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.8, - 22, - 2 - ], - "line-color": "hsl(60, 10%, 70%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.4, - 18, - 18, - 22, - 180 - ], - "line-opacity": [ - "step", - [ - "zoom" - ], - 0, - 11, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-secondary-tertiary-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 11, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "secondary", - "tertiary" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 1, - 22, - 2 - ], - "line-color": "hsl(60, 10%, 70%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0, - 18, - 26, - 22, - 260 - ], - "line-opacity": [ - "step", - [ - "zoom" - ], - 0, - 10, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-primary-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 10, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "==", - [ - "get", - "class" - ], - "primary" - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 1, - 22, - 2 - ], - "line-color": "hsl(60, 10%, 70%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0.8, - 18, - 28, - 22, - 280 - ], - "line-opacity": [ - "step", - [ - "zoom" - ], - 0, - 10, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-major-link-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 12, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "motorway_link", - "trunk_link" - ], - true, - false - ], - [ - "<=", - [ - "get", - "layer" - ], - 1 - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.8, - 22, - 2 - ], - "line-color": "hsl(60, 10%, 82%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.8, - 18, - 20, - 22, - 200 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-motorway-trunk-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "motorway", - "trunk" - ], - true, - false - ], - [ - "<=", - [ - "get", - "layer" - ], - 1 - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 1, - 22, - 2 - ], - "line-color": "hsl(60, 10%, 82%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0.8, - 18, - 30, - 22, - 300 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-construction", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "==", - [ - "get", - "class" - ], - "construction" - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 2, - 18, - 20, - 22, - 200 - ], - "line-color": "hsl(60, 10%, 70%)", - "line-dasharray": [ - "step", - [ - "zoom" - ], - [ - "literal", - [ - 0.4, - 0.8 - ] - ], - 15, - [ - "literal", - [ - 0.3, - 0.6 - ] - ], - 16, - [ - "literal", - [ - 0.2, - 0.3 - ] - ], - 17, - [ - "literal", - [ - 0.2, - 0.25 - ] - ], - 18, - [ - "literal", - [ - 0.15, - 0.15 - ] - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-minor", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "track" - ], - true, - "service", - [ - "step", - [ - "zoom" + "layout": { + "text-field": [ + "concat", + [ + "get", + "ele" + ], + " m" + ], + "symbol-placement": "line", + "text-pitch-alignment": "viewport", + "text-max-angle": 25, + "text-padding": 5, + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + 9.5, + 20, + 12 + ] + }, + "paint": { + "text-color": "hsl(60, 10%, 35%)", + "text-halo-width": 1, + "text-halo-color": "hsl(60, 10%, 85%)" + }, + "metadata": { + "mapbox:featureComponent": "terrain", + "mapbox:group": "Terrain, terrain-labels" + } + }, + { + "id": "building-entrance", + "type": "symbol", + "source": "composite", + "source-layer": "structure", + "minzoom": 18, + "filter": [ + "==", + [ + "get", + "class" + ], + "entrance" ], - false, - 14, - true - ], - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 1, - 18, - 10, - 22, - 100 - ], - "line-color": "hsl(0, 0%, 95%)" - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-minor-link", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "primary_link", - "secondary_link", - "tertiary_link" - ], - true, - false - ], - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.4, - 18, - 18, - 22, - 180 - ], - "line-color": "hsl(0, 0%, 95%)" - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-major-link", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 12, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "motorway_link", - "trunk_link" - ], - true, - false - ], - [ - "<=", - [ - "get", - "layer" - ], - 1 - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 13, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.8, - 18, - 20, - 22, - 200 - ], - "line-color": [ - "match", - [ - "get", - "class" - ], - "motorway_link", - "hsl(15, 100%, 75%)", - "hsl(35, 89%, 75%)" - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-street", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "street", - "street_limited" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.5, - 18, - 20, - 22, - 200 - ], - "line-color": [ - "match", - [ - "get", - "class" - ], - "street_limited", - "hsl(60, 22%, 80%)", - "hsl(0, 0%, 95%)" - ], - "line-opacity": [ - "step", - [ - "zoom" - ], - 0, - 14, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-street-low", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "maxzoom": 14, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "street", - "street_limited" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ], - "line-join": [ - "step", - [ - "zoom" - ], - "miter", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.5, - 18, - 20, - 22, - 200 - ], - "line-color": "hsl(0, 0%, 95%)" - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-secondary-tertiary", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "secondary", - "tertiary" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0, - 18, - 26, - 22, - 260 - ], - "line-color": "hsl(0, 0%, 95%)" - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-primary", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "==", - [ - "get", - "class" - ], - "primary" - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0.8, - 18, - 28, - 22, - 280 - ], - "line-color": "hsl(0, 0%, 95%)" - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-motorway-trunk", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "motorway", - "trunk" - ], - true, - false - ], - [ - "<=", - [ - "get", - "layer" - ], - 1 - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0.8, - 18, - 30, - 22, - 300 - ], - "line-color": [ - "match", - [ - "get", - "class" - ], - "motorway", - "hsl(15, 100%, 75%)", - "hsl(35, 89%, 75%)" - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-major-link-2-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 12, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - ">=", - [ - "get", - "layer" - ], - 2 - ], - [ - "match", - [ - "get", - "class" - ], - [ - "motorway_link", - "trunk_link" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.8, - 22, - 2 - ], - "line-color": "hsl(60, 10%, 82%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.8, - 18, - 20, - 22, - 200 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-motorway-trunk-2-case", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - ">=", - [ - "get", - "layer" - ], - 2 - ], - [ - "match", - [ - "get", - "class" - ], - [ - "motorway", - "trunk" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 1, - 22, - 2 - ], - "line-color": "hsl(60, 10%, 82%)", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0.8, - 18, - 30, - 22, - 300 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-major-link-2", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 12, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - ">=", - [ - "get", - "layer" - ], - 2 - ], - [ - "match", - [ - "get", - "class" - ], - [ - "motorway_link", - "trunk_link" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 13, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 12, - 0.8, - 18, - 20, - 22, - 200 - ], - "line-color": [ - "match", - [ - "get", - "class" - ], - "motorway_link", - "hsl(15, 100%, 75%)", - "hsl(35, 89%, 75%)" - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-motorway-trunk-2", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - ">=", - [ - "get", - "layer" - ], - 2 - ], - [ - "match", - [ - "get", - "class" - ], - [ - "motorway", - "trunk" - ], - true, - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "line-cap": [ - "step", - [ - "zoom" - ], - "butt", - 14, - "round" - ] - }, - "paint": { - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 3, - 0.8, - 18, - 30, - 22, - 300 - ], - "line-color": [ - "match", - [ - "get", - "class" - ], - "motorway", - "hsl(15, 100%, 75%)", - "hsl(35, 89%, 75%)" - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-oneway-arrow-blue", - "type": "symbol", - "source": "composite", - "source-layer": "road", - "minzoom": 16, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "==", - [ - "get", - "oneway" - ], - "true" - ], - [ - "step", - [ - "zoom" - ], - [ - "match", - [ - "get", - "class" + "layout": { + "icon-image": "marker", + "text-field": [ + "get", + "ref" + ], + "text-size": 10, + "text-offset": [ + 0, + -0.5 + ], + "text-font": [ + "DIN Pro Italic", + "Arial Unicode MS Regular" + ] + }, + "paint": { + "text-color": "hsl(60, 8%, 38%)", + "text-halo-color": "hsl(60, 13%, 77%)", + "text-halo-width": 1, + "icon-opacity": 0.4 + }, + "metadata": { + "mapbox:featureComponent": "buildings", + "mapbox:group": "Buildings, building-labels" + } + }, + { + "id": "building-number-label", + "type": "symbol", + "source": "composite", + "source-layer": "housenum_label", + "minzoom": 17, + "layout": { + "text-field": [ + "get", + "house_num" + ], + "text-font": [ + "DIN Pro Italic", + "Arial Unicode MS Regular" + ], + "text-padding": 4, + "text-max-width": 7, + "text-size": 10 + }, + "paint": { + "text-color": "hsl(60, 8%, 38%)", + "text-halo-color": "hsl(60, 13%, 77%)", + "text-halo-width": 1 + }, + "metadata": { + "mapbox:featureComponent": "buildings", + "mapbox:group": "Buildings, building-labels" + } + }, + { + "id": "block-number-label", + "type": "symbol", + "source": "composite", + "source-layer": "place_label", + "minzoom": 16, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "settlement_subdivision" + ], + [ + "==", + [ + "get", + "type" + ], + "block" + ] ], - [ - "primary", - "secondary", - "tertiary", - "street", - "street_limited" - ], - true, - false - ], - 16, - [ - "match", - [ - "get", - "class" + "layout": { + "text-field": [ + "get", + "name" + ], + "text-font": [ + "DIN Pro Italic", + "Arial Unicode MS Regular" + ], + "text-max-width": 7, + "text-size": 11 + }, + "paint": { + "text-color": "hsl(60, 18%, 44%)", + "text-halo-color": "hsl(60, 17%, 84%)", + "text-halo-width": 0.5, + "text-halo-blur": 0.5 + }, + "metadata": { + "mapbox:featureComponent": "buildings", + "mapbox:group": "Buildings, building-labels" + } + }, + { + "id": "road-label", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 10, + "filter": [ + "all", + [ + "has", + "name" + ], + [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk", + "primary", + "secondary", + "tertiary" + ], + true, + false + ], + 12, + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk", + "primary", + "secondary", + "tertiary", + "street", + "street_limited", + "track" + ], + true, + false + ], + 15, + [ + "match", + [ + "get", + "class" + ], + [ + "path", + "pedestrian", + "golf", + "ferry", + "aerialway" + ], + false, + true + ] + ] + ], + "layout": { + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk", + "primary", + "secondary", + "tertiary" + ], + 10, + [ + "motorway_link", + "trunk_link", + "primary_link", + "secondary_link", + "tertiary_link", + "street", + "street_limited", + "track" + ], + 9, + 6.5 + ], + 18, + [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk", + "primary", + "secondary", + "tertiary" + ], + 16, + [ + "motorway_link", + "trunk_link", + "primary_link", + "secondary_link", + "tertiary_link", + "street", + "street_limited", + "track" + ], + 14, + 13 + ] + ], + "text-max-angle": 30, + "text-font": [ + "DIN Pro Regular", + "Arial Unicode MS Regular" + ], + "symbol-placement": "line", + "text-padding": 1, + "text-rotation-alignment": "map", + "text-pitch-alignment": "viewport", + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-letter-spacing": 0.01 + }, + "paint": { + "text-color": "hsl(0,0%, 0%)", + "text-halo-color": [ + "match", + [ + "get", + "class" + ], + [ + "motorway", + "trunk" + ], + "hsla(60, 25%, 100%, 0.75)", + "hsl(60, 25%, 100%)" + ], + "text-halo-width": 1, + "text-halo-blur": 1 + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, road-labels" + } + }, + { + "id": "road-intersection", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 15, + "filter": [ + "all", + [ + "==", + [ + "get", + "class" + ], + "intersection" + ], + [ + "has", + "name" + ] + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "icon-image": "intersection", + "icon-text-fit": "both", + "icon-text-fit-padding": [ + 1, + 2, + 1, + 2 + ], + "text-size": [ + "interpolate", + [ + "exponential", + 1.2 + ], + [ + "zoom" + ], + 15, + 9, + 18, + 12 + ], + "text-font": [ + "DIN Pro Bold", + "Arial Unicode MS Bold" + ] + }, + "paint": { + "text-color": "hsl(230, 36%, 64%)" + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, road-labels" + } + }, + { + "id": "road-number-shield", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 6, + "filter": [ + "all", + [ + "has", + "reflen" + ], + [ + "<=", + [ + "get", + "reflen" + ], + 6 + ], + [ + "match", + [ + "get", + "class" + ], + [ + "pedestrian", + "service" + ], + false, + true + ], + [ + "step", + [ + "zoom" + ], + [ + "==", + [ + "geometry-type" + ], + "Point" + ], + 11, + [ + ">", + [ + "get", + "len" + ], + 5000 + ], + 12, + [ + ">", + [ + "get", + "len" + ], + 2500 + ], + 13, + [ + ">", + [ + "get", + "len" + ], + 1000 + ], + 14, + true + ] ], - [ - "primary", - "secondary", - "tertiary", - "street", - "street_limited", - "primary_link", - "secondary_link", - "tertiary_link", - "service", - "track" - ], - true, - false - ] - ] - ], - "layout": { - "symbol-placement": "line", - "icon-image": [ - "step", - [ - "zoom" - ], - "oneway-small", - 18, - "oneway-large" - ], - "symbol-spacing": 200, - "icon-rotation-alignment": "map", - "icon-allow-overlap": true, - "icon-ignore-placement": true - }, - "paint": {}, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-oneway-arrow-white", - "type": "symbol", - "source": "composite", - "source-layer": "road", - "minzoom": 16, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "motorway", - "trunk", - "motorway_link", - "trunk_link" - ], - true, - false - ], - [ - "==", - [ - "get", - "oneway" - ], - "true" - ] - ], - "layout": { - "symbol-placement": "line", - "icon-image": "oneway-white-small", - "symbol-spacing": 200, - "icon-rotation-alignment": "map", - "icon-allow-overlap": true, - "icon-ignore-placement": true - }, - "paint": {}, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" - } - }, - { - "id": "bridge-rail", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "major_rail", - "minor_rail" - ], - true, - false - ] - ], - "paint": { - "line-color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 13, - "hsl(75, 25%, 68%)", - 16, - "hsl(60, 0%, 56%)" - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 0.5, - 20, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, bridges" - } - }, - { - "id": "bridge-rail-tracks", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - [ - "get", - "structure" - ], - "bridge" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "major_rail", - "minor_rail" - ], - true, - false - ] - ], - "paint": { - "line-color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 13, - "hsl(75, 25%, 68%)", - 16, - "hsl(60, 0%, 56%)" - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 4, - 20, - 8 - ], - "line-dasharray": [ - 0.1, - 15 - ], - "line-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 13.75, - 0, - 14, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, bridges" - } - }, - { - "id": "aerialway", - "type": "line", - "source": "composite", - "source-layer": "road", - "minzoom": 12, - "filter": [ - "==", - [ - "get", - "class" - ], - "aerialway" - ], - "paint": { - "line-color": "hsl(230, 50%, 60%)", - "line-width": [ - "interpolate", - [ - "exponential", - 1.5 - ], - [ - "zoom" - ], - 14, - 1, - 20, - 2 - ], - "line-dasharray": [ - 4, - 1 - ] - }, - "metadata": { - "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, elevated" - } - }, - { - "id": "admin-1-boundary-bg", - "type": "line", - "source": "composite", - "source-layer": "admin", - "minzoom": 7, - "filter": [ - "all", - [ - "==", - [ - "get", - "admin_level" - ], - 1 - ], - [ - "==", - [ - "get", - "maritime" - ], - "false" - ], - [ - "match", - [ - "get", - "worldview" - ], - [ - "all", - "US" - ], - true, - false - ] - ], - "paint": { - "line-color": "hsl(350, 90%, 88%)", - "line-width": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 3, - 3, - 12, - 6 - ], - "line-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 7, - 0, - 8, - 0.5 - ], - "line-dasharray": [ - 1, - 0 - ], - "line-blur": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 3, - 0, - 12, - 3 - ] - }, - "metadata": { - "mapbox:featureComponent": "admin-boundaries", - "mapbox:group": "Administrative boundaries, admin" - } - }, - { - "id": "admin-0-boundary-bg", - "type": "line", - "source": "composite", - "source-layer": "admin", - "minzoom": 1, - "filter": [ - "all", - [ - "==", - [ - "get", - "admin_level" - ], - 0 - ], - [ - "==", - [ - "get", - "maritime" - ], - "false" - ], - [ - "match", - [ - "get", - "worldview" - ], - [ - "all", - "US" - ], - true, - false - ] - ], - "paint": { - "line-width": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 3, - 4, - 12, - 8 - ], - "line-color": "hsl(350, 90%, 88%)", - "line-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 3, - 0, - 4, - 0.5 - ], - "line-blur": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 3, - 0, - 12, - 2 - ] - }, - "metadata": { - "mapbox:featureComponent": "admin-boundaries", - "mapbox:group": "Administrative boundaries, admin" - } - }, - { - "id": "admin-1-boundary", - "type": "line", - "source": "composite", - "source-layer": "admin", - "minzoom": 2, - "filter": [ - "all", - [ - "==", - [ - "get", - "admin_level" - ], - 1 - ], - [ - "==", - [ - "get", - "maritime" - ], - "false" - ], - [ - "match", - [ - "get", - "worldview" - ], - [ - "all", - "US" - ], - true, - false - ] - ], - "layout": {}, - "paint": { - "line-dasharray": [ - "step", - [ - "zoom" - ], - [ - "literal", - [ - 2, - 0 - ] - ], - 7, - [ - "literal", - [ - 2, - 2, - 6, - 2 - ] - ] - ], - "line-width": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 3, - 0.3, - 12, - 1.5 - ], - "line-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 2, - 0, - 3, - 1 - ], - "line-color": "hsl(350, 30%, 55%)" - }, - "metadata": { - "mapbox:featureComponent": "admin-boundaries", - "mapbox:group": "Administrative boundaries, admin" - } - }, - { - "id": "admin-0-boundary", - "type": "line", - "source": "composite", - "source-layer": "admin", - "minzoom": 1, - "filter": [ - "all", - [ - "==", - [ - "get", - "admin_level" - ], - 0 - ], - [ - "==", - [ - "get", - "disputed" - ], - "false" - ], - [ - "==", - [ - "get", - "maritime" - ], - "false" - ], - [ - "match", - [ - "get", - "worldview" - ], - [ - "all", - "US" - ], - true, - false - ] - ], - "layout": {}, - "paint": { - "line-color": "hsl(350, 30%, 50%)", - "line-width": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 3, - 0.5, - 12, - 2 - ], - "line-dasharray": [ - "step", - [ - "zoom" - ], - [ - "literal", - [ - 2, - 0 - ] - ], - 7, - [ - "literal", - [ - 2, - 2, - 6, - 2 - ] - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "admin-boundaries", - "mapbox:group": "Administrative boundaries, admin" - } - }, - { - "id": "admin-0-boundary-disputed", - "type": "line", - "source": "composite", - "source-layer": "admin", - "minzoom": 1, - "filter": [ - "all", - [ - "==", - [ - "get", - "disputed" - ], - "true" - ], - [ - "==", - [ - "get", - "admin_level" - ], - 0 - ], - [ - "==", - [ - "get", - "maritime" - ], - "false" - ], - [ - "match", - [ - "get", - "worldview" - ], - [ - "all", - "US" - ], - true, - false - ] - ], - "paint": { - "line-color": "hsl(350, 30%, 50%)", - "line-width": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 3, - 0.5, - 12, - 2 - ], - "line-dasharray": [ - "step", - [ - "zoom" - ], - [ - "literal", - [ - 3, - 2, - 5 - ] - ], - 7, - [ - "literal", - [ - 2, - 1.5 - ] - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "admin-boundaries", - "mapbox:group": "Administrative boundaries, admin" - } - }, - { - "id": "contour-label", - "type": "symbol", - "source": "composite", - "source-layer": "contour", - "minzoom": 11, - "filter": [ - "any", - [ - "==", - [ - "get", - "index" - ], - 10 - ], - [ - "==", - [ - "get", - "index" - ], - 5 - ] - ], - "layout": { - "text-field": [ - "concat", - [ - "get", - "ele" - ], - " m" - ], - "symbol-placement": "line", - "text-pitch-alignment": "viewport", - "text-max-angle": 25, - "text-padding": 5, - "text-font": [ - "DIN Pro Medium", - "Arial Unicode MS Regular" - ], - "text-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 15, - 9.5, - 20, - 12 - ] - }, - "paint": { - "text-color": "hsl(60, 10%, 35%)", - "text-halo-width": 1, - "text-halo-color": "hsl(60, 10%, 85%)" - }, - "metadata": { - "mapbox:featureComponent": "terrain", - "mapbox:group": "Terrain, terrain-labels" - } - }, - { - "id": "building-entrance", - "type": "symbol", - "source": "composite", - "source-layer": "structure", - "minzoom": 18, - "filter": [ - "==", - [ - "get", - "class" - ], - "entrance" - ], - "layout": { - "icon-image": "marker", - "text-field": [ - "get", - "ref" - ], - "text-size": 10, - "text-offset": [ - 0, - -0.5 - ], - "text-font": [ - "DIN Pro Italic", - "Arial Unicode MS Regular" - ] - }, - "paint": { - "text-color": "hsl(60, 8%, 38%)", - "text-halo-color": "hsl(60, 13%, 77%)", - "text-halo-width": 1, - "icon-opacity": 0.4 - }, - "metadata": { - "mapbox:featureComponent": "buildings", - "mapbox:group": "Buildings, building-labels" - } - }, - { - "id": "building-number-label", - "type": "symbol", - "source": "composite", - "source-layer": "housenum_label", - "minzoom": 17, - "layout": { - "text-field": [ - "get", - "house_num" - ], - "text-font": [ - "DIN Pro Italic", - "Arial Unicode MS Regular" - ], - "text-padding": 4, - "text-max-width": 7, - "text-size": 10 - }, - "paint": { - "text-color": "hsl(60, 8%, 38%)", - "text-halo-color": "hsl(60, 13%, 77%)", - "text-halo-width": 1 - }, - "metadata": { - "mapbox:featureComponent": "buildings", - "mapbox:group": "Buildings, building-labels" - } - }, - { - "id": "block-number-label", - "type": "symbol", - "source": "composite", - "source-layer": "place_label", - "minzoom": 16, - "filter": [ - "all", - [ - "==", - [ - "get", - "class" - ], - "settlement_subdivision" - ], - [ - "==", - [ - "get", - "type" - ], - "block" - ] - ], - "layout": { - "text-field": [ - "get", - "name" - ], - "text-font": [ - "DIN Pro Italic", - "Arial Unicode MS Regular" - ], - "text-max-width": 7, - "text-size": 11 - }, - "paint": { - "text-color": "hsl(60, 18%, 44%)", - "text-halo-color": "hsl(60, 17%, 84%)", - "text-halo-width": 0.5, - "text-halo-blur": 0.5 - }, - "metadata": { - "mapbox:featureComponent": "buildings", - "mapbox:group": "Buildings, building-labels" - } - }, - { - "id": "road-label", - "type": "symbol", - "source": "composite", - "source-layer": "road", - "minzoom": 10, - "filter": [ - "all", - [ - "has", - "name" - ], - [ - "step", - [ - "zoom" - ], - [ - "match", - [ - "get", - "class" + "layout": { + "text-size": 9, + "icon-image": [ + "case", + [ + "has", + "shield_beta" + ], + [ + "coalesce", + [ + "image", + [ + "concat", + [ + "get", + "shield_beta" + ], + "-", + [ + "to-string", + [ + "get", + "reflen" + ] + ] + ] + ], + [ + "image", + [ + "concat", + "default-", + [ + "to-string", + [ + "get", + "reflen" + ] + ] + ] + ] + ], + [ + "concat", + [ + "get", + "shield" + ], + "-", + [ + "to-string", + [ + "get", + "reflen" + ] + ] + ] + ], + "icon-rotation-alignment": "viewport", + "text-max-angle": 38, + "symbol-spacing": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 11, + 400, + 14, + 600 + ], + "text-font": [ + "DIN Pro Bold", + "Arial Unicode MS Bold" + ], + "symbol-placement": [ + "step", + [ + "zoom" + ], + "point", + 11, + "line" + ], + "text-rotation-alignment": "viewport", + "text-field": [ + "get", + "ref" + ], + "text-letter-spacing": 0.05 + }, + "paint": { + "text-color": [ + "case", + [ + "all", + [ + "has", + "shield_text_color_beta" + ], + [ + "to-boolean", + [ + "coalesce", + [ + "image", + [ + "concat", + [ + "get", + "shield_beta" + ], + "-", + [ + "to-string", + [ + "get", + "reflen" + ] + ] + ] + ], + "" + ] + ] + ], + [ + "match", + [ + "get", + "shield_text_color_beta" + ], + "white", + "hsl(0, 0%, 100%)", + "yellow", + "hsl(50, 63%, 70%)", + "orange", + "hsl(25, 63%, 75%)", + "blue", + "hsl(230, 36%, 44%)", + "red", + "hsl(0, 54%, 59%)", + "green", + "hsl(140, 46%, 37%)", + "hsl(230, 11%, 13%)" + ], + [ + "match", + [ + "get", + "shield_text_color" + ], + "white", + "hsl(0, 0%, 100%)", + "yellow", + "hsl(50, 63%, 70%)", + "orange", + "hsl(25, 63%, 75%)", + "blue", + "hsl(230, 36%, 44%)", + "red", + "hsl(0, 54%, 59%)", + "green", + "hsl(140, 46%, 37%)", + "hsl(230, 11%, 13%)" + ] + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, road-labels" + } + }, + { + "id": "road-exit-shield", + "type": "symbol", + "source": "composite", + "source-layer": "motorway_junction", + "minzoom": 14, + "filter": [ + "all", + [ + "has", + "reflen" + ], + [ + "<=", + [ + "get", + "reflen" + ], + 9 + ] ], - [ - "motorway", - "trunk", - "primary", - "secondary", - "tertiary" - ], - true, - false - ], - 12, - [ - "match", - [ - "get", - "class" + "layout": { + "text-field": [ + "get", + "ref" + ], + "text-size": 9, + "icon-image": [ + "concat", + "motorway-exit-", + [ + "to-string", + [ + "get", + "reflen" + ] + ] + ], + "text-font": [ + "DIN Pro Bold", + "Arial Unicode MS Bold" + ] + }, + "paint": { + "text-color": "hsl(0, 0%, 100%)", + "text-translate": [ + 0, + 0 + ] + }, + "metadata": { + "mapbox:featureComponent": "road-network", + "mapbox:group": "Road network, road-labels" + } + }, + { + "id": "path-pedestrian-label", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 12, + "filter": [ + "all", + [ + "case", + [ + "has", + "layer" + ], + [ + ">=", + [ + "get", + "layer" + ], + 0 + ], + true + ], + [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "pedestrian" + ], + true, + false + ], + 15, + [ + "match", + [ + "get", + "class" + ], + [ + "path", + "pedestrian" + ], + true, + false + ] + ] ], - [ - "motorway", - "trunk", - "primary", - "secondary", - "tertiary", - "street", - "street_limited", - "track" - ], - true, - false - ], - 15, - [ - "match", - [ - "get", - "class" + "layout": { + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + [ + "match", + [ + "get", + "class" + ], + "pedestrian", + 9, + 6.5 + ], + 18, + [ + "match", + [ + "get", + "class" + ], + "pedestrian", + 14, + 13 + ] + ], + "text-max-angle": 30, + "text-font": [ + "DIN Pro Regular", + "Arial Unicode MS Regular" + ], + "symbol-placement": "line", + "text-padding": 1, + "text-rotation-alignment": "map", + "text-pitch-alignment": "viewport", + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-letter-spacing": 0.01 + }, + "paint": { + "text-color": "hsl(0,0%, 0%)", + "text-halo-color": "hsl(60, 25%, 100%)", + "text-halo-width": 1, + "text-halo-blur": 1 + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., walking-cycling-labels" + } + }, + { + "id": "golf-hole-label", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 16, + "filter": [ + "==", + [ + "get", + "class" + ], + "golf" ], - [ - "path", - "pedestrian", - "golf", - "ferry", - "aerialway" - ], - false, - true - ] - ] - ], - "layout": { - "text-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 10, - [ - "match", - [ - "get", - "class" + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "text-size": 12 + }, + "paint": { + "text-halo-color": "hsl(98, 60%, 55%)", + "text-halo-width": 0.5, + "text-halo-blur": 0.5, + "text-color": "hsl(100, 80%, 18%)" + }, + "metadata": { + "mapbox:featureComponent": "walking-cycling", + "mapbox:group": "Walking, cycling, etc., walking-cycling-labels" + } + }, + { + "id": "ferry-aerialway-label", + "type": "symbol", + "source": "composite", + "source-layer": "road", + "minzoom": 15, + "filter": [ + "match", + [ + "get", + "class" + ], + "aerialway", + true, + "ferry", + true, + false + ], + "layout": { + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 6.5, + 18, + 13 + ], + "text-max-angle": 30, + "text-font": [ + "DIN Pro Regular", + "Arial Unicode MS Regular" + ], + "symbol-placement": "line", + "text-padding": 1, + "text-rotation-alignment": "map", + "text-pitch-alignment": "viewport", + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-letter-spacing": 0.01 + }, + "paint": { + "text-color": [ + "match", + [ + "get", + "class" + ], + "ferry", + "hsl(205, 43%, 100%)", + "hsl(230, 50%, 60%)" + ], + "text-halo-color": [ + "match", + [ + "get", + "class" + ], + "ferry", + "hsl(205, 75%, 70%)", + "hsl(60, 20%, 100%)" + ], + "text-halo-width": 1, + "text-halo-blur": 1 + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, ferry-aerialway-labels" + } + }, + { + "id": "waterway-label", + "type": "symbol", + "source": "composite", + "source-layer": "natural_label", + "minzoom": 13, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "canal", + "river", + "stream", + "disputed_canal", + "disputed_river", + "disputed_stream" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] ], - [ - "motorway", - "trunk", - "primary", - "secondary", - "tertiary" + "layout": { + "text-font": [ + "DIN Pro Italic", + "Arial Unicode MS Regular" + ], + "text-max-angle": 30, + "symbol-spacing": [ + "interpolate", + [ + "linear", + 1 + ], + [ + "zoom" + ], + 15, + 250, + 17, + 400 + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 13, + 12, + 18, + 18 + ], + "symbol-placement": "line", + "text-pitch-alignment": "viewport", + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] + }, + "paint": { + "text-color": "hsl(205, 43%, 90%)", + "text-halo-color": "hsla(60, 17%, 84%, 0.5)" + }, + "metadata": { + "mapbox:featureComponent": "natural-features", + "mapbox:group": "Natural features, natural-labels" + } + }, + { + "id": "natural-line-label", + "type": "symbol", + "metadata": { + "mapbox:featureComponent": "natural-features", + "mapbox:group": "Natural features, natural-labels" + }, + "source": "composite", + "source-layer": "natural_label", + "minzoom": 4, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "glacier", + "landform", + "disputed_glacier", + "disputed_landform" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false + ], + [ + "<=", + [ + "get", + "filterrank" + ], + 4 + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] ], - 10, - [ - "motorway_link", - "trunk_link", - "primary_link", - "secondary_link", - "tertiary_link", - "street", - "street_limited", - "track" - ], - 9, - 6.5 - ], - 18, - [ - "match", - [ - "get", - "class" + "layout": { + "text-size": [ + "step", + [ + "zoom" + ], + [ + "step", + [ + "get", + "sizerank" + ], + 18, + 5, + 12 + ], + 17, + [ + "step", + [ + "get", + "sizerank" + ], + 18, + 13, + 12 + ] + ], + "text-max-angle": 30, + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "symbol-placement": "line-center", + "text-pitch-alignment": "viewport" + }, + "paint": { + "text-halo-width": 0.5, + "text-halo-color": "hsl(60, 17%, 84%)", + "text-halo-blur": 0.5, + "text-color": "hsl(340, 10%, 38%)" + } + }, + { + "id": "natural-point-label", + "type": "symbol", + "source": "composite", + "source-layer": "natural_label", + "minzoom": 4, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "dock", + "glacier", + "landform", + "water_feature", + "wetland", + "disputed_dock", + "disputed_glacier", + "disputed_landform", + "disputed_water_feature", + "disputed_wetland" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false + ], + [ + "<=", + [ + "get", + "filterrank" + ], + 4 + ], + [ + "==", + [ + "geometry-type" + ], + "Point" + ] ], - [ - "motorway", - "trunk", - "primary", - "secondary", - "tertiary" + "layout": { + "text-size": [ + "step", + [ + "zoom" + ], + [ + "step", + [ + "get", + "sizerank" + ], + 18, + 5, + 12 + ], + 17, + [ + "step", + [ + "get", + "sizerank" + ], + 18, + 13, + 12 + ] + ], + "icon-image": [ + "get", + "maki" + ], + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "text-offset": [ + "step", + [ + "zoom" + ], + [ + "step", + [ + "get", + "sizerank" + ], + [ + "literal", + [ + 0, + 0 + ] + ], + 5, + [ + "literal", + [ + 0, + 0.8 + ] + ] + ], + 17, + [ + "step", + [ + "get", + "sizerank" + ], + [ + "literal", + [ + 0, + 0 + ] + ], + 13, + [ + "literal", + [ + 0, + 0.8 + ] + ] + ] + ], + "text-anchor": [ + "step", + [ + "zoom" + ], + [ + "step", + [ + "get", + "sizerank" + ], + "center", + 5, + "top" + ], + 17, + [ + "step", + [ + "get", + "sizerank" + ], + "center", + 13, + "top" + ] + ], + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] + }, + "paint": { + "icon-opacity": [ + "step", + [ + "zoom" + ], + [ + "step", + [ + "get", + "sizerank" + ], + 0, + 5, + 1 + ], + 17, + [ + "step", + [ + "get", + "sizerank" + ], + 0, + 13, + 1 + ] + ], + "text-halo-color": "hsl(60, 20%, 100%)", + "text-halo-width": 0.5, + "text-halo-blur": 0.5, + "text-color": "hsl(340, 10%, 38%)" + }, + "metadata": { + "mapbox:featureComponent": "natural-features", + "mapbox:group": "Natural features, natural-labels" + } + }, + { + "id": "water-line-label", + "type": "symbol", + "metadata": { + "mapbox:featureComponent": "natural-features", + "mapbox:group": "Natural features, natural-labels" + }, + "source": "composite", + "source-layer": "natural_label", + "minzoom": 1, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "bay", + "ocean", + "reservoir", + "sea", + "water", + "disputed_bay", + "disputed_ocean", + "disputed_reservoir", + "disputed_sea", + "disputed_water" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false + ], + [ + "==", + [ + "geometry-type" + ], + "LineString" + ] ], - 16, - [ - "motorway_link", - "trunk_link", - "primary_link", - "secondary_link", - "tertiary_link", - "street", - "street_limited", - "track" - ], - 14, - 13 - ] - ], - "text-max-angle": 30, - "text-font": [ - "DIN Pro Regular", - "Arial Unicode MS Regular" - ], - "symbol-placement": "line", - "text-padding": 1, - "text-rotation-alignment": "map", - "text-pitch-alignment": "viewport", - "text-field": [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ], - "text-letter-spacing": 0.01 - }, - "paint": { - "text-color": "hsl(0,0%, 0%)", - "text-halo-color": [ - "match", - [ - "get", - "class" - ], - [ - "motorway", - "trunk" - ], - "hsla(60, 25%, 100%, 0.75)", - "hsl(60, 25%, 100%)" - ], - "text-halo-width": 1, - "text-halo-blur": 1 - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, road-labels" - } - }, - { - "id": "road-intersection", - "type": "symbol", - "source": "composite", - "source-layer": "road", - "minzoom": 15, - "filter": [ - "all", - [ - "==", - [ - "get", - "class" - ], - "intersection" - ], - [ - "has", - "name" - ] - ], - "layout": { - "text-field": [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ], - "icon-image": "intersection", - "icon-text-fit": "both", - "icon-text-fit-padding": [ - 1, - 2, - 1, - 2 - ], - "text-size": [ - "interpolate", - [ - "exponential", - 1.2 - ], - [ - "zoom" - ], - 15, - 9, - 18, - 12 - ], - "text-font": [ - "DIN Pro Bold", - "Arial Unicode MS Bold" - ] - }, - "paint": { - "text-color": "hsl(230, 36%, 64%)" - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, road-labels" - } - }, - { - "id": "road-number-shield", - "type": "symbol", - "source": "composite", - "source-layer": "road", - "minzoom": 6, - "filter": [ - "all", - [ - "has", - "reflen" - ], - [ - "<=", - [ - "get", - "reflen" - ], - 6 - ], - [ - "match", - [ - "get", - "class" - ], - [ - "pedestrian", - "service" - ], - false, - true - ], - [ - "step", - [ - "zoom" - ], - [ - "==", - [ - "geometry-type" + "layout": { + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 0, + [ + "*", + [ + "-", + 16, + [ + "sqrt", + [ + "get", + "sizerank" + ] + ] + ], + 1 + ], + 22, + [ + "*", + [ + "-", + 22, + [ + "sqrt", + [ + "get", + "sizerank" + ] + ] + ], + 1 + ] + ], + "text-max-angle": 30, + "text-letter-spacing": [ + "match", + [ + "get", + "class" + ], + "ocean", + 0.25, + [ + "sea", + "bay" + ], + 0.15, + 0 + ], + "text-font": [ + "DIN Pro Italic", + "Arial Unicode MS Regular" + ], + "symbol-placement": "line-center", + "text-pitch-alignment": "viewport", + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] + }, + "paint": { + "text-color": [ + "match", + [ + "get", + "class" + ], + [ + "bay", + "ocean", + "sea" + ], + "hsl(205, 71%, 90%)", + "hsl(205, 43%, 90%)" + ], + "text-halo-color": "hsla(60, 17%, 84%, 0.5)" + } + }, + { + "id": "water-point-label", + "type": "symbol", + "source": "composite", + "source-layer": "natural_label", + "minzoom": 1, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "bay", + "ocean", + "reservoir", + "sea", + "water", + "disputed_bay", + "disputed_ocean", + "disputed_reservoir", + "disputed_sea", + "disputed_water" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false + ], + [ + "==", + [ + "geometry-type" + ], + "Point" + ] ], - "Point" - ], - 11, - [ - ">", - [ - "get", - "len" - ], - 5000 - ], - 12, - [ - ">", - [ - "get", - "len" - ], - 2500 - ], - 13, - [ - ">", - [ - "get", - "len" + "layout": { + "text-line-height": 1.3, + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 0, + [ + "*", + [ + "-", + 16, + [ + "sqrt", + [ + "get", + "sizerank" + ] + ] + ], + 1 + ], + 22, + [ + "*", + [ + "-", + 22, + [ + "sqrt", + [ + "get", + "sizerank" + ] + ] + ], + 1 + ] + ], + "text-font": [ + "DIN Pro Italic", + "Arial Unicode MS Regular" + ], + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-letter-spacing": [ + "match", + [ + "get", + "class" + ], + "ocean", + 0.25, + [ + "bay", + "sea" + ], + 0.15, + 0.01 + ], + "text-max-width": [ + "match", + [ + "get", + "class" + ], + "ocean", + 4, + "sea", + 5, + [ + "bay", + "water" + ], + 7, + 10 + ] + }, + "paint": { + "text-color": [ + "match", + [ + "get", + "class" + ], + [ + "bay", + "ocean", + "sea" + ], + "hsl(205, 71%, 90%)", + "hsl(205, 43%, 90%)" + ], + "text-halo-color": "hsla(60, 17%, 84%, 0.5)" + }, + "metadata": { + "mapbox:featureComponent": "natural-features", + "mapbox:group": "Natural features, natural-labels" + } + }, + { + "id": "poi-label", + "type": "symbol", + "source": "composite", + "source-layer": "poi_label", + "minzoom": 6, + "filter": [ + "<=", + [ + "get", + "filterrank" + ], + [ + "+", + [ + "step", + [ + "zoom" + ], + 0, + 16, + 1, + 17, + 2 + ], + [ + "match", + [ + "get", + "class" + ], + "food_and_drink_stores", + 3, + "historic", + 3, + "landmark", + 3, + "medical", + 3, + "motorist", + 3, + "park_like", + 4, + "sport_and_leisure", + 4, + "visitor_amenities", + 4, + 2 + ] + ] ], - 1000 - ], - 14, - true - ] - ], - "layout": { - "text-size": 9, - "icon-image": [ - "case", - [ - "has", - "shield_beta" - ], - [ - "coalesce", - [ - "image", - [ - "concat", + "layout": { + "text-size": [ + "step", + [ + "zoom" + ], + [ + "step", + [ + "get", + "sizerank" + ], + 18, + 5, + 12 + ], + 17, + [ + "step", + [ + "get", + "sizerank" + ], + 18, + 13, + 12 + ] + ], + "icon-image": [ + "case", + [ + "has", + "maki_beta" + ], + [ + "coalesce", + [ + "image", + [ + "get", + "maki_beta" + ] + ], + [ + "image", + [ + "get", + "maki" + ] + ] + ], + [ + "image", + [ + "get", + "maki" + ] + ] + ], + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "text-offset": [ + "step", + [ + "zoom" + ], + [ + "step", + [ + "get", + "sizerank" + ], + [ + "literal", + [ + 0, + 0 + ] + ], + 5, + [ + "literal", + [ + 0, + 0.8 + ] + ] + ], + 17, + [ + "step", + [ + "get", + "sizerank" + ], + [ + "literal", + [ + 0, + 0 + ] + ], + 13, + [ + "literal", + [ + 0, + 0.8 + ] + ] + ] + ], + "text-anchor": [ + "step", + [ + "zoom" + ], + [ + "step", + [ + "get", + "sizerank" + ], + "center", + 5, + "top" + ], + 17, + [ + "step", + [ + "get", + "sizerank" + ], + "center", + 13, + "top" + ] + ], + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] + }, + "paint": { + "icon-opacity": [ + "step", + [ + "zoom" + ], + [ + "step", + [ + "get", + "sizerank" + ], + 0, + 5, + 1 + ], + 17, + [ + "step", + [ + "get", + "sizerank" + ], + 0, + 13, + 1 + ] + ], + "text-halo-color": "hsl(60, 20%, 100%)", + "text-halo-width": 0.5, + "text-halo-blur": 0.5, + "text-color": [ + "match", + [ + "get", + "class" + ], + "food_and_drink", + "hsl(35, 80%, 38%)", + "park_like", + "hsl(100, 80%, 18%)", + "education", + "hsl(30, 60%, 28%)", + "medical", + "hsl(10, 60%, 43%)", + "sport_and_leisure", + "hsl(210, 60%, 38%)", + "hsl(340, 10%, 38%)" + ] + }, + "metadata": { + "mapbox:featureComponent": "point-of-interest-labels", + "mapbox:group": "Point of interest labels, poi-labels" + } + }, + { + "id": "transit-label", + "type": "symbol", + "source": "composite", + "source-layer": "transit_stop_label", + "minzoom": 12, + "filter": [ + "step", + [ + "zoom" + ], + [ + "all", + [ + "<=", + [ + "get", + "filterrank" + ], + 4 + ], + [ + "match", + [ + "get", + "mode" + ], + "rail", + true, + "metro_rail", + true, + false + ], + [ + "!=", + [ + "get", + "stop_type" + ], + "entrance" + ] + ], + 14, + [ + "all", + [ + "match", + [ + "get", + "mode" + ], + "rail", + true, + "metro_rail", + true, + false + ], + [ + "!=", + [ + "get", + "stop_type" + ], + "entrance" + ] + ], + 15, + [ + "all", + [ + "match", + [ + "get", + "mode" + ], + "rail", + true, + "metro_rail", + true, + "ferry", + true, + "light_rail", + true, + false + ], + [ + "!=", + [ + "get", + "stop_type" + ], + "entrance" + ] + ], + 16, [ - "get", - "shield_beta" + "all", + [ + "match", + [ + "get", + "mode" + ], + "bus", + false, + true + ], + [ + "!=", + [ + "get", + "stop_type" + ], + "entrance" + ] ], - "-", + 17, [ - "to-string", - [ + "!=", + [ + "get", + "stop_type" + ], + "entrance" + ], + 19, + true + ], + "layout": { + "text-size": 12, + "icon-image": [ "get", - "reflen" - ] + "network" + ], + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "text-justify": [ + "match", + [ + "get", + "stop_type" + ], + "entrance", + "left", + "center" + ], + "text-offset": [ + "match", + [ + "get", + "stop_type" + ], + "entrance", + [ + "literal", + [ + 1, + 0 + ] + ], + [ + "literal", + [ + 0, + 0.8 + ] + ] + ], + "text-anchor": [ + "match", + [ + "get", + "stop_type" + ], + "entrance", + "left", + "top" + ], + "text-field": [ + "step", + [ + "zoom" + ], + "", + 13, + [ + "match", + [ + "get", + "mode" + ], + [ + "rail", + "metro_rail" + ], + [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "" + ], + 14, + [ + "match", + [ + "get", + "mode" + ], + [ + "bus", + "bicycle" + ], + "", + [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] + ], + 18, + [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] + ], + "text-letter-spacing": 0.01, + "text-max-width": [ + "match", + [ + "get", + "stop_type" + ], + "entrance", + 15, + 9 ] - ] - ], - [ - "image", - [ - "concat", - "default-", + }, + "paint": { + "text-halo-color": "hsl(60, 20%, 100%)", + "text-color": [ + "match", + [ + "get", + "network" + ], + "tokyo-metro", + "hsl(180, 30%, 30%)", + "mexico-city-metro", + "hsl(25, 63%, 63%)", + [ + "barcelona-metro", + "delhi-metro", + "hong-kong-mtr", + "milan-metro", + "osaka-subway" + ], + "hsl(0, 57%, 47%)", + [ + "boston-t", + "washington-metro" + ], + "hsl(230, 11%, 20%)", + [ + "chongqing-rail-transit", + "kiev-metro", + "singapore-mrt", + "taipei-metro" + ], + "hsl(140, 56%, 25%)", + "hsl(230, 50%, 60%)" + ], + "text-halo-blur": 0.5, + "text-halo-width": 0.5 + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, transit-labels" + } + }, + { + "id": "airport-label", + "type": "symbol", + "source": "composite", + "source-layer": "airport_label", + "minzoom": 8, + "filter": [ + "match", [ - "to-string", - [ "get", - "reflen" - ] - ] - ] - ] - ], - [ - "concat", - [ - "get", - "shield" - ], - "-", - [ - "to-string", - [ - "get", - "reflen" - ] - ] - ] - ], - "icon-rotation-alignment": "viewport", - "text-max-angle": 38, - "symbol-spacing": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 11, - 400, - 14, - 600 - ], - "text-font": [ - "DIN Pro Bold", - "Arial Unicode MS Bold" - ], - "symbol-placement": [ - "step", - [ - "zoom" - ], - "point", - 11, - "line" - ], - "text-rotation-alignment": "viewport", - "text-field": [ - "get", - "ref" - ], - "text-letter-spacing": 0.05 - }, - "paint": { - "text-color": [ - "case", - [ - "all", - [ - "has", - "shield_text_color_beta" - ], - [ - "to-boolean", - [ - "coalesce", + "class" + ], [ - "image", - [ - "concat", + "military", + "civil", + "disputed_military", + "disputed_civil" + ], + [ + "match", + [ + "get", + "worldview" + ], [ - "get", - "shield_beta" + "all", + "US" ], - "-", + true, + false + ], + false + ], + "layout": { + "text-line-height": 1.1, + "text-size": [ + "step", [ - "to-string", - [ "get", - "reflen" - ] + "sizerank" + ], + 18, + 9, + 12 + ], + "icon-image": [ + "get", + "maki" + ], + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "text-offset": [ + 0, + 0.8 + ], + "text-rotation-alignment": "viewport", + "text-anchor": "top", + "text-field": [ + "step", + [ + "get", + "sizerank" + ], + [ + "case", + [ + "has", + "ref" + ], + [ + "concat", + [ + "get", + "ref" + ], + " -\n", + [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] + ], + [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] + ], + 15, + [ + "get", + "ref" ] - ] - ], - "" - ] - ] - ], - [ - "match", - [ - "get", - "shield_text_color_beta" - ], - "white", - "hsl(0, 0%, 100%)", - "yellow", - "hsl(50, 63%, 70%)", - "orange", - "hsl(25, 63%, 75%)", - "blue", - "hsl(230, 36%, 44%)", - "red", - "hsl(0, 54%, 59%)", - "green", - "hsl(140, 46%, 37%)", - "hsl(230, 11%, 13%)" - ], - [ - "match", - [ - "get", - "shield_text_color" - ], - "white", - "hsl(0, 0%, 100%)", - "yellow", - "hsl(50, 63%, 70%)", - "orange", - "hsl(25, 63%, 75%)", - "blue", - "hsl(230, 36%, 44%)", - "red", - "hsl(0, 54%, 59%)", - "green", - "hsl(140, 46%, 37%)", - "hsl(230, 11%, 13%)" - ] - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, road-labels" - } - }, - { - "id": "road-exit-shield", - "type": "symbol", - "source": "composite", - "source-layer": "motorway_junction", - "minzoom": 14, - "filter": [ - "all", - [ - "has", - "reflen" - ], - [ - "<=", - [ - "get", - "reflen" - ], - 9 - ] - ], - "layout": { - "text-field": [ - "get", - "ref" - ], - "text-size": 9, - "icon-image": [ - "concat", - "motorway-exit-", - [ - "to-string", - [ - "get", - "reflen" - ] - ] - ], - "text-font": [ - "DIN Pro Bold", - "Arial Unicode MS Bold" - ] - }, - "paint": { - "text-color": "hsl(0, 0%, 100%)", - "text-translate": [ - 0, - 0 - ] - }, - "metadata": { - "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, road-labels" - } - }, - { - "id": "path-pedestrian-label", - "type": "symbol", - "source": "composite", - "source-layer": "road", - "minzoom": 12, - "filter": [ - "all", - [ - "case", - [ - "has", - "layer" - ], - [ - ">=", - [ - "get", - "layer" - ], - 0 - ], - true - ], - [ - "step", - [ - "zoom" - ], - [ - "match", - [ - "get", - "class" - ], - [ - "pedestrian" - ], - true, - false - ], - 15, - [ - "match", - [ - "get", - "class" - ], - [ - "path", - "pedestrian" - ], - true, - false - ] - ] - ], - "layout": { - "text-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 10, - [ - "match", - [ - "get", - "class" - ], - "pedestrian", - 9, - 6.5 - ], - 18, - [ - "match", - [ - "get", - "class" - ], - "pedestrian", - 14, - 13 - ] - ], - "text-max-angle": 30, - "text-font": [ - "DIN Pro Regular", - "Arial Unicode MS Regular" - ], - "symbol-placement": "line", - "text-padding": 1, - "text-rotation-alignment": "map", - "text-pitch-alignment": "viewport", - "text-field": [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ], - "text-letter-spacing": 0.01 - }, - "paint": { - "text-color": "hsl(0,0%, 0%)", - "text-halo-color": "hsl(60, 25%, 100%)", - "text-halo-width": 1, - "text-halo-blur": 1 - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., walking-cycling-labels" - } - }, - { - "id": "golf-hole-label", - "type": "symbol", - "source": "composite", - "source-layer": "road", - "minzoom": 16, - "filter": [ - "==", - [ - "get", - "class" - ], - "golf" - ], - "layout": { - "text-field": [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ], - "text-font": [ - "DIN Pro Medium", - "Arial Unicode MS Regular" - ], - "text-size": 12 - }, - "paint": { - "text-halo-color": "hsl(98, 60%, 55%)", - "text-halo-width": 0.5, - "text-halo-blur": 0.5, - "text-color": "hsl(100, 80%, 18%)" - }, - "metadata": { - "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., walking-cycling-labels" - } - }, - { - "id": "ferry-aerialway-label", - "type": "symbol", - "source": "composite", - "source-layer": "road", - "minzoom": 15, - "filter": [ - "match", - [ - "get", - "class" - ], - "aerialway", - true, - "ferry", - true, - false - ], - "layout": { - "text-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 10, - 6.5, - 18, - 13 - ], - "text-max-angle": 30, - "text-font": [ - "DIN Pro Regular", - "Arial Unicode MS Regular" - ], - "symbol-placement": "line", - "text-padding": 1, - "text-rotation-alignment": "map", - "text-pitch-alignment": "viewport", - "text-field": [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ], - "text-letter-spacing": 0.01 - }, - "paint": { - "text-color": [ - "match", - [ - "get", - "class" - ], - "ferry", - "hsl(205, 43%, 100%)", - "hsl(230, 50%, 60%)" - ], - "text-halo-color": [ - "match", - [ - "get", - "class" - ], - "ferry", - "hsl(205, 75%, 70%)", - "hsl(60, 20%, 100%)" - ], - "text-halo-width": 1, - "text-halo-blur": 1 - }, - "metadata": { - "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, ferry-aerialway-labels" - } - }, - { - "id": "waterway-label", - "type": "symbol", - "source": "composite", - "source-layer": "natural_label", - "minzoom": 13, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "canal", - "river", - "stream", - "disputed_canal", - "disputed_river", - "disputed_stream" - ], - [ - "match", - [ - "get", - "worldview" - ], - [ - "all", - "US" - ], - true, - false - ], - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "text-font": [ - "DIN Pro Italic", - "Arial Unicode MS Regular" - ], - "text-max-angle": 30, - "symbol-spacing": [ - "interpolate", - [ - "linear", - 1 - ], - [ - "zoom" - ], - 15, - 250, - 17, - 400 - ], - "text-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 13, - 12, - 18, - 18 - ], - "symbol-placement": "line", - "text-pitch-alignment": "viewport", - "text-field": [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ] - }, - "paint": { - "text-color": "hsl(205, 43%, 90%)", - "text-halo-color": "hsla(60, 17%, 84%, 0.5)" - }, - "metadata": { - "mapbox:featureComponent": "natural-features", - "mapbox:group": "Natural features, natural-labels" - } - }, - { - "id": "natural-line-label", - "type": "symbol", - "metadata": { - "mapbox:featureComponent": "natural-features", - "mapbox:group": "Natural features, natural-labels" - }, - "source": "composite", - "source-layer": "natural_label", - "minzoom": 4, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "glacier", - "landform", - "disputed_glacier", - "disputed_landform" - ], - [ - "match", - [ - "get", - "worldview" - ], - [ - "all", - "US" - ], - true, - false - ], - false - ], - [ - "<=", - [ - "get", - "filterrank" - ], - 4 - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "text-size": [ - "step", - [ - "zoom" - ], - [ - "step", - [ - "get", - "sizerank" - ], - 18, - 5, - 12 - ], - 17, - [ - "step", - [ - "get", - "sizerank" - ], - 18, - 13, - 12 - ] - ], - "text-max-angle": 30, - "text-field": [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ], - "text-font": [ - "DIN Pro Medium", - "Arial Unicode MS Regular" - ], - "symbol-placement": "line-center", - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-halo-width": 0.5, - "text-halo-color": "hsl(60, 17%, 84%)", - "text-halo-blur": 0.5, - "text-color": "hsl(340, 10%, 38%)" - } - }, - { - "id": "natural-point-label", - "type": "symbol", - "source": "composite", - "source-layer": "natural_label", - "minzoom": 4, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "dock", - "glacier", - "landform", - "water_feature", - "wetland", - "disputed_dock", - "disputed_glacier", - "disputed_landform", - "disputed_water_feature", - "disputed_wetland" - ], - [ - "match", - [ - "get", - "worldview" - ], - [ - "all", - "US" - ], - true, - false - ], - false - ], - [ - "<=", - [ - "get", - "filterrank" - ], - 4 - ], - [ - "==", - [ - "geometry-type" - ], - "Point" - ] - ], - "layout": { - "text-size": [ - "step", - [ - "zoom" - ], - [ - "step", - [ - "get", - "sizerank" - ], - 18, - 5, - 12 - ], - 17, - [ - "step", - [ - "get", - "sizerank" - ], - 18, - 13, - 12 - ] - ], - "icon-image": [ - "get", - "maki" - ], - "text-font": [ - "DIN Pro Medium", - "Arial Unicode MS Regular" - ], - "text-offset": [ - "step", - [ - "zoom" - ], - [ - "step", - [ - "get", - "sizerank" - ], - [ - "literal", - [ - 0, - 0 - ] - ], - 5, - [ - "literal", - [ - 0, - 0.8 - ] - ] - ], - 17, - [ - "step", - [ - "get", - "sizerank" - ], - [ - "literal", - [ - 0, - 0 - ] - ], - 13, - [ - "literal", - [ - 0, - 0.8 - ] - ] - ] - ], - "text-anchor": [ - "step", - [ - "zoom" - ], - [ - "step", - [ - "get", - "sizerank" - ], - "center", - 5, - "top" - ], - 17, - [ - "step", - [ - "get", - "sizerank" - ], - "center", - 13, - "top" - ] - ], - "text-field": [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ] - }, - "paint": { - "icon-opacity": [ - "step", - [ - "zoom" - ], - [ - "step", - [ - "get", - "sizerank" - ], - 0, - 5, - 1 - ], - 17, - [ - "step", - [ - "get", - "sizerank" - ], - 0, - 13, - 1 - ] - ], - "text-halo-color": "hsl(60, 20%, 100%)", - "text-halo-width": 0.5, - "text-halo-blur": 0.5, - "text-color": "hsl(340, 10%, 38%)" - }, - "metadata": { - "mapbox:featureComponent": "natural-features", - "mapbox:group": "Natural features, natural-labels" - } - }, - { - "id": "water-line-label", - "type": "symbol", - "metadata": { - "mapbox:featureComponent": "natural-features", - "mapbox:group": "Natural features, natural-labels" - }, - "source": "composite", - "source-layer": "natural_label", - "minzoom": 1, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "bay", - "ocean", - "reservoir", - "sea", - "water", - "disputed_bay", - "disputed_ocean", - "disputed_reservoir", - "disputed_sea", - "disputed_water" - ], - [ - "match", - [ - "get", - "worldview" - ], - [ - "all", - "US" - ], - true, - false - ], - false - ], - [ - "==", - [ - "geometry-type" - ], - "LineString" - ] - ], - "layout": { - "text-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 0, - [ - "*", - [ - "-", - 16, - [ - "sqrt", + ], + "text-letter-spacing": 0.01, + "text-max-width": 9 + }, + "paint": { + "text-color": "hsl(230, 40%, 55%)", + "text-halo-color": "hsl(60, 20%, 100%)", + "text-halo-width": 1 + }, + "metadata": { + "mapbox:featureComponent": "transit", + "mapbox:group": "Transit, transit-labels" + } + }, + { + "id": "settlement-subdivision-label", + "type": "symbol", + "source": "composite", + "source-layer": "place_label", + "minzoom": 10, + "maxzoom": 15, + "filter": [ + "all", + [ + "match", + [ + "get", + "class" + ], + [ + "settlement_subdivision", + "disputed_settlement_subdivision" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false + ], [ - "get", - "sizerank" + "<=", + [ + "get", + "filterrank" + ], + 3 + ] + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-transform": "uppercase", + "text-font": [ + "DIN Pro Regular", + "Arial Unicode MS Regular" + ], + "text-letter-spacing": [ + "match", + [ + "get", + "type" + ], + "suburb", + 0.15, + 0.05 + ], + "text-max-width": 7, + "text-padding": 3, + "text-size": [ + "interpolate", + [ + "cubic-bezier", + 0.5, + 0, + 1, + 1 + ], + [ + "zoom" + ], + 11, + [ + "match", + [ + "get", + "type" + ], + "suburb", + 11, + 10.5 + ], + 15, + [ + "match", + [ + "get", + "type" + ], + "suburb", + 15, + 14 + ] ] - ] - ], - 1 - ], - 22, - [ - "*", - [ - "-", - 22, - [ - "sqrt", + }, + "paint": { + "text-halo-color": "hsla(60, 25%, 100%, 0.75)", + "text-halo-width": 1, + "text-color": "hsl(230, 29%, 36%)", + "text-halo-blur": 0.5 + }, + "metadata": { + "mapbox:featureComponent": "place-labels", + "mapbox:group": "Place labels, place-labels" + } + }, + { + "id": "settlement-minor-label", + "type": "symbol", + "source": "composite", + "source-layer": "place_label", + "minzoom": 2, + "maxzoom": 13, + "filter": [ + "all", [ - "get", - "sizerank" - ] - ] - ], - 1 - ] - ], - "text-max-angle": 30, - "text-letter-spacing": [ - "match", - [ - "get", - "class" - ], - "ocean", - 0.25, - [ - "sea", - "bay" - ], - 0.15, - 0 - ], - "text-font": [ - "DIN Pro Italic", - "Arial Unicode MS Regular" - ], - "symbol-placement": "line-center", - "text-pitch-alignment": "viewport", - "text-field": [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ] - }, - "paint": { - "text-color": [ - "match", - [ - "get", - "class" - ], - [ - "bay", - "ocean", - "sea" - ], - "hsl(205, 71%, 90%)", - "hsl(205, 43%, 90%)" - ], - "text-halo-color": "hsla(60, 17%, 84%, 0.5)" - } - }, - { - "id": "water-point-label", - "type": "symbol", - "source": "composite", - "source-layer": "natural_label", - "minzoom": 1, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "bay", - "ocean", - "reservoir", - "sea", - "water", - "disputed_bay", - "disputed_ocean", - "disputed_reservoir", - "disputed_sea", - "disputed_water" - ], - [ - "match", - [ - "get", - "worldview" - ], - [ - "all", - "US" - ], - true, - false - ], - false - ], - [ - "==", - [ - "geometry-type" - ], - "Point" - ] - ], - "layout": { - "text-line-height": 1.3, - "text-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 0, - [ - "*", - [ - "-", - 16, - [ - "sqrt", + "<=", + [ + "get", + "filterrank" + ], + 3 + ], [ - "get", - "sizerank" + "match", + [ + "get", + "class" + ], + [ + "settlement", + "disputed_settlement" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false + ], + [ + "step", + [ + "zoom" + ], + [ + ">", + [ + "get", + "symbolrank" + ], + 6 + ], + 4, + [ + ">=", + [ + "get", + "symbolrank" + ], + 7 + ], + 6, + [ + ">=", + [ + "get", + "symbolrank" + ], + 8 + ], + 7, + [ + ">=", + [ + "get", + "symbolrank" + ], + 10 + ], + 10, + [ + ">=", + [ + "get", + "symbolrank" + ], + 11 + ], + 11, + [ + ">=", + [ + "get", + "symbolrank" + ], + 13 + ], + 12, + [ + ">=", + [ + "get", + "symbolrank" + ], + 15 + ] ] - ] ], - 1 - ], - 22, - [ - "*", - [ - "-", - 22, - [ - "sqrt", + "layout": { + "symbol-sort-key": [ + "get", + "symbolrank" + ], + "icon-image": [ + "step", + [ + "zoom" + ], + [ + "case", + [ + "==", + [ + "get", + "capital" + ], + 2 + ], + "border-dot-13", + [ + "step", + [ + "get", + "symbolrank" + ], + "dot-11", + 9, + "dot-10", + 11, + "dot-9" + ] + ], + 8, + "" + ], + "text-font": [ + "DIN Pro Regular", + "Arial Unicode MS Regular" + ], + "text-radial-offset": [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "capital" + ], + 2, + 0.6, + 0.55 + ], + 8, + 0 + ], + "text-anchor": [ + "step", + [ + "zoom" + ], + [ + "get", + "text_anchor" + ], + 8, + "center" + ], + "text-justify": "auto", + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-max-width": 7, + "text-line-height": 1.1, + "text-size": [ + "interpolate", + [ + "cubic-bezier", + 0.2, + 0, + 0.9, + 1 + ], + [ + "zoom" + ], + 3, + [ + "step", + [ + "get", + "symbolrank" + ], + 11, + 9, + 10 + ], + 6, + [ + "step", + [ + "get", + "symbolrank" + ], + 14, + 9, + 12, + 12, + 10 + ], + 8, + [ + "step", + [ + "get", + "symbolrank" + ], + 16, + 9, + 14, + 12, + 12, + 15, + 10 + ], + 13, + [ + "step", + [ + "get", + "symbolrank" + ], + 22, + 9, + 20, + 12, + 16, + 15, + 14 + ] + ] + }, + "paint": { + "text-color": "hsl(230, 29%, 0%)", + "text-halo-color": "hsl(60, 25%, 100%)", + "text-halo-width": 1, + "text-halo-blur": 1 + }, + "metadata": { + "mapbox:featureComponent": "place-labels", + "mapbox:group": "Place labels, place-labels" + } + }, + { + "id": "settlement-major-label", + "type": "symbol", + "source": "composite", + "source-layer": "place_label", + "minzoom": 2, + "maxzoom": 15, + "filter": [ + "all", + [ + "<=", + [ + "get", + "filterrank" + ], + 3 + ], + [ + "match", + [ + "get", + "class" + ], + [ + "settlement", + "disputed_settlement" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false + ], [ - "get", - "sizerank" + "step", + [ + "zoom" + ], + false, + 2, + [ + "<=", + [ + "get", + "symbolrank" + ], + 6 + ], + 4, + [ + "<", + [ + "get", + "symbolrank" + ], + 7 + ], + 6, + [ + "<", + [ + "get", + "symbolrank" + ], + 8 + ], + 7, + [ + "<", + [ + "get", + "symbolrank" + ], + 10 + ], + 10, + [ + "<", + [ + "get", + "symbolrank" + ], + 11 + ], + 11, + [ + "<", + [ + "get", + "symbolrank" + ], + 13 + ], + 12, + [ + "<", + [ + "get", + "symbolrank" + ], + 15 + ], + 13, + [ + ">=", + [ + "get", + "symbolrank" + ], + 11 + ], + 14, + [ + ">=", + [ + "get", + "symbolrank" + ], + 15 + ] ] - ] - ], - 1 - ] - ], - "text-font": [ - "DIN Pro Italic", - "Arial Unicode MS Regular" - ], - "text-field": [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ], - "text-letter-spacing": [ - "match", - [ - "get", - "class" - ], - "ocean", - 0.25, - [ - "bay", - "sea" - ], - 0.15, - 0.01 - ], - "text-max-width": [ - "match", - [ - "get", - "class" - ], - "ocean", - 4, - "sea", - 5, - [ - "bay", - "water" - ], - 7, - 10 - ] - }, - "paint": { - "text-color": [ - "match", - [ - "get", - "class" - ], - [ - "bay", - "ocean", - "sea" - ], - "hsl(205, 71%, 90%)", - "hsl(205, 43%, 90%)" - ], - "text-halo-color": "hsla(60, 17%, 84%, 0.5)" - }, - "metadata": { - "mapbox:featureComponent": "natural-features", - "mapbox:group": "Natural features, natural-labels" - } - }, - { - "id": "poi-label", - "type": "symbol", - "source": "composite", - "source-layer": "poi_label", - "minzoom": 6, - "filter": [ - "<=", - [ - "get", - "filterrank" - ], - [ - "+", - [ - "step", - [ - "zoom" - ], - 0, - 16, - 1, - 17, - 2 - ], - [ - "match", - [ - "get", - "class" - ], - "food_and_drink_stores", - 3, - "historic", - 3, - "landmark", - 3, - "medical", - 3, - "motorist", - 3, - "park_like", - 4, - "sport_and_leisure", - 4, - "visitor_amenities", - 4, - 2 - ] - ] - ], - "layout": { - "text-size": [ - "step", - [ - "zoom" - ], - [ - "step", - [ - "get", - "sizerank" - ], - 18, - 5, - 12 - ], - 17, - [ - "step", - [ - "get", - "sizerank" - ], - 18, - 13, - 12 - ] - ], - "icon-image": [ - "case", - [ - "has", - "maki_beta" - ], - [ - "coalesce", - [ - "image", - [ - "get", - "maki_beta" - ] - ], - [ - "image", - [ - "get", - "maki" - ] - ] - ], - [ - "image", - [ - "get", - "maki" - ] - ] - ], - "text-font": [ - "DIN Pro Medium", - "Arial Unicode MS Regular" - ], - "text-offset": [ - "step", - [ - "zoom" - ], - [ - "step", - [ - "get", - "sizerank" - ], - [ - "literal", - [ - 0, - 0 - ] - ], - 5, - [ - "literal", - [ - 0, - 0.8 - ] - ] - ], - 17, - [ - "step", - [ - "get", - "sizerank" - ], - [ - "literal", - [ - 0, - 0 - ] - ], - 13, - [ - "literal", - [ - 0, - 0.8 - ] - ] - ] - ], - "text-anchor": [ - "step", - [ - "zoom" - ], - [ - "step", - [ - "get", - "sizerank" - ], - "center", - 5, - "top" - ], - 17, - [ - "step", - [ - "get", - "sizerank" - ], - "center", - 13, - "top" - ] - ], - "text-field": [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ] - }, - "paint": { - "icon-opacity": [ - "step", - [ - "zoom" - ], - [ - "step", - [ - "get", - "sizerank" - ], - 0, - 5, - 1 - ], - 17, - [ - "step", - [ - "get", - "sizerank" - ], - 0, - 13, - 1 - ] - ], - "text-halo-color": "hsl(60, 20%, 100%)", - "text-halo-width": 0.5, - "text-halo-blur": 0.5, - "text-color": [ - "match", - [ - "get", - "class" - ], - "food_and_drink", - "hsl(35, 80%, 38%)", - "park_like", - "hsl(100, 80%, 18%)", - "education", - "hsl(30, 60%, 28%)", - "medical", - "hsl(10, 60%, 43%)", - "sport_and_leisure", - "hsl(210, 60%, 38%)", - "hsl(340, 10%, 38%)" - ] - }, - "metadata": { - "mapbox:featureComponent": "point-of-interest-labels", - "mapbox:group": "Point of interest labels, poi-labels" - } - }, - { - "id": "transit-label", - "type": "symbol", - "source": "composite", - "source-layer": "transit_stop_label", - "minzoom": 12, - "filter": [ - "step", - [ - "zoom" - ], - [ - "all", - [ - "<=", - [ - "get", - "filterrank" - ], - 4 - ], - [ - "match", - [ - "get", - "mode" - ], - "rail", - true, - "metro_rail", - true, - false - ], - [ - "!=", - [ - "get", - "stop_type" - ], - "entrance" - ] - ], - 14, - [ - "all", - [ - "match", - [ - "get", - "mode" - ], - "rail", - true, - "metro_rail", - true, - false - ], - [ - "!=", - [ - "get", - "stop_type" - ], - "entrance" - ] - ], - 15, - [ - "all", - [ - "match", - [ - "get", - "mode" - ], - "rail", - true, - "metro_rail", - true, - "ferry", - true, - "light_rail", - true, - false - ], - [ - "!=", - [ - "get", - "stop_type" - ], - "entrance" - ] - ], - 16, - [ - "all", - [ - "match", - [ - "get", - "mode" - ], - "bus", - false, - true - ], - [ - "!=", - [ - "get", - "stop_type" - ], - "entrance" - ] - ], - 17, - [ - "!=", - [ - "get", - "stop_type" - ], - "entrance" - ], - 19, - true - ], - "layout": { - "text-size": 12, - "icon-image": [ - "get", - "network" - ], - "text-font": [ - "DIN Pro Medium", - "Arial Unicode MS Regular" - ], - "text-justify": [ - "match", - [ - "get", - "stop_type" - ], - "entrance", - "left", - "center" - ], - "text-offset": [ - "match", - [ - "get", - "stop_type" - ], - "entrance", - [ - "literal", - [ - 1, - 0 - ] - ], - [ - "literal", - [ - 0, - 0.8 - ] - ] - ], - "text-anchor": [ - "match", - [ - "get", - "stop_type" - ], - "entrance", - "left", - "top" - ], - "text-field": [ - "step", - [ - "zoom" - ], - "", - 13, - [ - "match", - [ - "get", - "mode" - ], - [ - "rail", - "metro_rail" - ], - [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ], - "" - ], - 14, - [ - "match", - [ - "get", - "mode" - ], - [ - "bus", - "bicycle" - ], - "", - [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ] - ], - 18, - [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ] - ], - "text-letter-spacing": 0.01, - "text-max-width": [ - "match", - [ - "get", - "stop_type" - ], - "entrance", - 15, - 9 - ] - }, - "paint": { - "text-halo-color": "hsl(60, 20%, 100%)", - "text-color": [ - "match", - [ - "get", - "network" - ], - "tokyo-metro", - "hsl(180, 30%, 30%)", - "mexico-city-metro", - "hsl(25, 63%, 63%)", - [ - "barcelona-metro", - "delhi-metro", - "hong-kong-mtr", - "milan-metro", - "osaka-subway" - ], - "hsl(0, 57%, 47%)", - [ - "boston-t", - "washington-metro" - ], - "hsl(230, 11%, 20%)", - [ - "chongqing-rail-transit", - "kiev-metro", - "singapore-mrt", - "taipei-metro" - ], - "hsl(140, 56%, 25%)", - "hsl(230, 50%, 60%)" - ], - "text-halo-blur": 0.5, - "text-halo-width": 0.5 - }, - "metadata": { - "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, transit-labels" - } - }, - { - "id": "airport-label", - "type": "symbol", - "source": "composite", - "source-layer": "airport_label", - "minzoom": 8, - "filter": [ - "match", - [ - "get", - "class" - ], - [ - "military", - "civil", - "disputed_military", - "disputed_civil" - ], - [ - "match", - [ - "get", - "worldview" - ], - [ - "all", - "US" - ], - true, - false - ], - false - ], - "layout": { - "text-line-height": 1.1, - "text-size": [ - "step", - [ - "get", - "sizerank" - ], - 18, - 9, - 12 - ], - "icon-image": [ - "get", - "maki" - ], - "text-font": [ - "DIN Pro Medium", - "Arial Unicode MS Regular" - ], - "text-offset": [ - 0, - 0.8 - ], - "text-rotation-alignment": "viewport", - "text-anchor": "top", - "text-field": [ - "step", - [ - "get", - "sizerank" - ], - [ - "case", - [ - "has", - "ref" ], - [ - "concat", - [ - "get", - "ref" - ], - " -\n", - [ - "coalesce", + "layout": { + "symbol-sort-key": [ + "get", + "symbolrank" + ], + "icon-image": [ + "step", + [ + "zoom" + ], + [ + "case", + [ + "==", + [ + "get", + "capital" + ], + 2 + ], + "border-dot-13", + [ + "step", + [ + "get", + "symbolrank" + ], + "dot-11", + 9, + "dot-10", + 11, + "dot-9" + ] + ], + 8, + "" + ], + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "text-radial-offset": [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "capital" + ], + 2, + 0.6, + 0.55 + ], + 8, + 0 + ], + "text-anchor": [ + "step", + [ + "zoom" + ], + [ + "get", + "text_anchor" + ], + 8, + "center" + ], + "text-justify": [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "text_anchor" + ], + [ + "left", + "bottom-left", + "top-left" + ], + "left", + [ + "right", + "bottom-right", + "top-right" + ], + "right", + "center" + ], + 8, + "center" + ], + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-max-width": 7, + "text-line-height": 1.1, + "text-size": [ + "interpolate", + [ + "cubic-bezier", + 0.2, + 0, + 0.9, + 1 + ], + [ + "zoom" + ], + 3, + [ + "step", + [ + "get", + "symbolrank" + ], + 13, + 6, + 11 + ], + 6, + [ + "step", + [ + "get", + "symbolrank" + ], + 18, + 6, + 16, + 7, + 14 + ], + 8, + [ + "step", + [ + "get", + "symbolrank" + ], + 20, + 9, + 16, + 10, + 14 + ], + 15, + [ + "step", + [ + "get", + "symbolrank" + ], + 24, + 9, + 20, + 12, + 16, + 15, + 14 + ] + ] + }, + "paint": { + "text-color": "hsl(230, 29%, 0%)", + "text-halo-color": "hsl(60, 25%, 100%)", + "text-halo-width": 1, + "text-halo-blur": 1 + }, + "metadata": { + "mapbox:featureComponent": "place-labels", + "mapbox:group": "Place labels, place-labels" + } + }, + { + "id": "state-label", + "type": "symbol", + "source": "composite", + "source-layer": "place_label", + "minzoom": 3, + "maxzoom": 9, + "filter": [ + "match", [ - "get", - "name_en" + "get", + "class" ], [ - "get", - "name" - ] - ] - ], - [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ] - ], - 15, - [ - "get", - "ref" - ] - ], - "text-letter-spacing": 0.01, - "text-max-width": 9 - }, - "paint": { - "text-color": "hsl(230, 40%, 55%)", - "text-halo-color": "hsl(60, 20%, 100%)", - "text-halo-width": 1 - }, - "metadata": { - "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, transit-labels" - } - }, - { - "id": "settlement-subdivision-label", - "type": "symbol", - "source": "composite", - "source-layer": "place_label", - "minzoom": 10, - "maxzoom": 15, - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "settlement_subdivision", - "disputed_settlement_subdivision" - ], - [ - "match", - [ - "get", - "worldview" - ], - [ - "all", - "US" - ], - true, - false - ], - false - ], - [ - "<=", - [ - "get", - "filterrank" - ], - 3 - ] - ], - "layout": { - "text-field": [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ], - "text-transform": "uppercase", - "text-font": [ - "DIN Pro Regular", - "Arial Unicode MS Regular" - ], - "text-letter-spacing": [ - "match", - [ - "get", - "type" - ], - "suburb", - 0.15, - 0.05 - ], - "text-max-width": 7, - "text-padding": 3, - "text-size": [ - "interpolate", - [ - "cubic-bezier", - 0.5, - 0, - 1, - 1 - ], - [ - "zoom" - ], - 11, - [ - "match", - [ - "get", - "type" - ], - "suburb", - 11, - 10.5 - ], - 15, - [ - "match", - [ - "get", - "type" - ], - "suburb", - 15, - 14 - ] - ] - }, - "paint": { - "text-halo-color": "hsla(60, 25%, 100%, 0.75)", - "text-halo-width": 1, - "text-color": "hsl(230, 29%, 36%)", - "text-halo-blur": 0.5 - }, - "metadata": { - "mapbox:featureComponent": "place-labels", - "mapbox:group": "Place labels, place-labels" - } - }, - { - "id": "settlement-minor-label", - "type": "symbol", - "source": "composite", - "source-layer": "place_label", - "minzoom": 2, - "maxzoom": 13, - "filter": [ - "all", - [ - "<=", - [ - "get", - "filterrank" - ], - 3 - ], - [ - "match", - [ - "get", - "class" - ], - [ - "settlement", - "disputed_settlement" - ], - [ - "match", - [ - "get", - "worldview" - ], - [ - "all", - "US" - ], - true, - false - ], - false - ], - [ - "step", - [ - "zoom" - ], - [ - ">", - [ - "get", - "symbolrank" - ], - 6 - ], - 4, - [ - ">=", - [ - "get", - "symbolrank" - ], - 7 - ], - 6, - [ - ">=", - [ - "get", - "symbolrank" - ], - 8 - ], - 7, - [ - ">=", - [ - "get", - "symbolrank" - ], - 10 - ], - 10, - [ - ">=", - [ - "get", - "symbolrank" - ], - 11 - ], - 11, - [ - ">=", - [ - "get", - "symbolrank" - ], - 13 - ], - 12, - [ - ">=", - [ - "get", - "symbolrank" - ], - 15 - ] - ] - ], - "layout": { - "symbol-sort-key": [ - "get", - "symbolrank" - ], - "icon-image": [ - "step", - [ - "zoom" - ], - [ - "case", - [ - "==", - [ - "get", - "capital" - ], - 2 - ], - "border-dot-13", - [ - "step", - [ - "get", - "symbolrank" - ], - "dot-11", - 9, - "dot-10", - 11, - "dot-9" - ] - ], - 8, - "" - ], - "text-font": [ - "DIN Pro Regular", - "Arial Unicode MS Regular" - ], - "text-radial-offset": [ - "step", - [ - "zoom" - ], - [ - "match", - [ - "get", - "capital" - ], - 2, - 0.6, - 0.55 - ], - 8, - 0 - ], - "text-anchor": [ - "step", - [ - "zoom" - ], - [ - "get", - "text_anchor" - ], - 8, - "center" - ], - "text-justify": "auto", - "text-field": [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ], - "text-max-width": 7, - "text-line-height": 1.1, - "text-size": [ - "interpolate", - [ - "cubic-bezier", - 0.2, - 0, - 0.9, - 1 - ], - [ - "zoom" - ], - 3, - [ - "step", - [ - "get", - "symbolrank" - ], - 11, - 9, - 10 - ], - 6, - [ - "step", - [ - "get", - "symbolrank" - ], - 14, - 9, - 12, - 12, - 10 - ], - 8, - [ - "step", - [ - "get", - "symbolrank" - ], - 16, - 9, - 14, - 12, - 12, - 15, - 10 - ], - 13, - [ - "step", - [ - "get", - "symbolrank" - ], - 22, - 9, - 20, - 12, - 16, - 15, - 14 - ] - ] - }, - "paint": { - "text-color": "hsl(230, 29%, 0%)", - "text-halo-color": "hsl(60, 25%, 100%)", - "text-halo-width": 1, - "text-halo-blur": 1 - }, - "metadata": { - "mapbox:featureComponent": "place-labels", - "mapbox:group": "Place labels, place-labels" - } - }, - { - "id": "settlement-major-label", - "type": "symbol", - "source": "composite", - "source-layer": "place_label", - "minzoom": 2, - "maxzoom": 15, - "filter": [ - "all", - [ - "<=", - [ - "get", - "filterrank" - ], - 3 - ], - [ - "match", - [ - "get", - "class" - ], - [ - "settlement", - "disputed_settlement" - ], - [ - "match", - [ - "get", - "worldview" - ], - [ - "all", - "US" - ], - true, - false - ], - false - ], - [ - "step", - [ - "zoom" - ], - false, - 2, - [ - "<=", - [ - "get", - "symbolrank" - ], - 6 - ], - 4, - [ - "<", - [ - "get", - "symbolrank" - ], - 7 - ], - 6, - [ - "<", - [ - "get", - "symbolrank" - ], - 8 - ], - 7, - [ - "<", - [ - "get", - "symbolrank" - ], - 10 - ], - 10, - [ - "<", - [ - "get", - "symbolrank" - ], - 11 - ], - 11, - [ - "<", - [ - "get", - "symbolrank" - ], - 13 - ], - 12, - [ - "<", - [ - "get", - "symbolrank" - ], - 15 - ], - 13, - [ - ">=", - [ - "get", - "symbolrank" - ], - 11 - ], - 14, - [ - ">=", - [ - "get", - "symbolrank" - ], - 15 - ] - ] - ], - "layout": { - "symbol-sort-key": [ - "get", - "symbolrank" - ], - "icon-image": [ - "step", - [ - "zoom" - ], - [ - "case", - [ - "==", - [ - "get", - "capital" - ], - 2 - ], - "border-dot-13", - [ - "step", - [ - "get", - "symbolrank" - ], - "dot-11", - 9, - "dot-10", - 11, - "dot-9" - ] - ], - 8, - "" - ], - "text-font": [ - "DIN Pro Medium", - "Arial Unicode MS Regular" - ], - "text-radial-offset": [ - "step", - [ - "zoom" - ], - [ - "match", - [ - "get", - "capital" - ], - 2, - 0.6, - 0.55 - ], - 8, - 0 - ], - "text-anchor": [ - "step", - [ - "zoom" - ], - [ - "get", - "text_anchor" - ], - 8, - "center" - ], - "text-justify": [ - "step", - [ - "zoom" - ], - [ - "match", - [ - "get", - "text_anchor" - ], - [ - "left", - "bottom-left", - "top-left" - ], - "left", - [ - "right", - "bottom-right", - "top-right" - ], - "right", - "center" - ], - 8, - "center" - ], - "text-field": [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ], - "text-max-width": 7, - "text-line-height": 1.1, - "text-size": [ - "interpolate", - [ - "cubic-bezier", - 0.2, - 0, - 0.9, - 1 - ], - [ - "zoom" - ], - 3, - [ - "step", - [ - "get", - "symbolrank" - ], - 13, - 6, - 11 - ], - 6, - [ - "step", - [ - "get", - "symbolrank" - ], - 18, - 6, - 16, - 7, - 14 - ], - 8, - [ - "step", - [ - "get", - "symbolrank" - ], - 20, - 9, - 16, - 10, - 14 - ], - 15, - [ - "step", - [ - "get", - "symbolrank" - ], - 24, - 9, - 20, - 12, - 16, - 15, - 14 - ] - ] - }, - "paint": { - "text-color": "hsl(230, 29%, 0%)", - "text-halo-color": "hsl(60, 25%, 100%)", - "text-halo-width": 1, - "text-halo-blur": 1 - }, - "metadata": { - "mapbox:featureComponent": "place-labels", - "mapbox:group": "Place labels, place-labels" - } - }, - { - "id": "state-label", - "type": "symbol", - "source": "composite", - "source-layer": "place_label", - "minzoom": 3, - "maxzoom": 9, - "filter": [ - "match", - [ - "get", - "class" - ], - [ - "state", - "disputed_state" - ], - [ - "match", - [ - "get", - "worldview" - ], - [ - "all", - "US" - ], - true, - false - ], - false - ], - "layout": { - "text-size": [ - "interpolate", - [ - "cubic-bezier", - 0.85, - 0.7, - 0.65, - 1 - ], - [ - "zoom" - ], - 4, - [ - "step", - [ - "get", - "symbolrank" - ], - 9, - 6, - 8, - 7, - 7 - ], - 9, - [ - "step", - [ - "get", - "symbolrank" - ], - 21, - 6, - 16, - 7, - 14 - ] - ], - "text-transform": "uppercase", - "text-font": [ - "DIN Pro Bold", - "Arial Unicode MS Bold" - ], - "text-field": [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ], - "text-letter-spacing": 0.15, - "text-max-width": 6 - }, - "paint": { - "text-color": "hsl(230, 29%, 0%)", - "text-halo-color": "hsl(60, 25%, 100%)", - "text-halo-width": 1, - "text-opacity": 0.5 - }, - "metadata": { - "mapbox:featureComponent": "place-labels", - "mapbox:group": "Place labels, place-labels" - } - }, - { - "id": "country-label", - "type": "symbol", - "source": "composite", - "source-layer": "place_label", - "minzoom": 1, - "maxzoom": 10, - "filter": [ - "match", - [ - "get", - "class" - ], - [ - "country", - "disputed_country" - ], - [ - "match", - [ - "get", - "worldview" - ], - [ - "all", - "US" - ], - true, - false - ], - false - ], - "layout": { - "icon-image": "", - "text-field": [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ], - "text-line-height": 1.1, - "text-max-width": 6, - "text-font": [ - "DIN Pro Medium", - "Arial Unicode MS Regular" - ], - "text-radial-offset": [ - "step", - [ - "zoom" - ], - 0.6, - 8, - 0 - ], - "text-justify": [ - "step", - [ - "zoom" - ], - [ - "match", - [ - "get", - "text_anchor" - ], - [ - "left", - "bottom-left", - "top-left" - ], - "left", - [ - "right", - "bottom-right", - "top-right" - ], - "right", - "center" - ], - 7, - "auto" - ], - "text-size": [ - "interpolate", - [ - "cubic-bezier", - 0.2, - 0, - 0.7, - 1 - ], - [ - "zoom" - ], - 1, - [ - "step", - [ - "get", - "symbolrank" + "state", + "disputed_state" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false ], - 11, - 4, - 9, - 5, - 8 - ], - 9, - [ - "step", - [ - "get", - "symbolrank" + "layout": { + "text-size": [ + "interpolate", + [ + "cubic-bezier", + 0.85, + 0.7, + 0.65, + 1 + ], + [ + "zoom" + ], + 4, + [ + "step", + [ + "get", + "symbolrank" + ], + 9, + 6, + 8, + 7, + 7 + ], + 9, + [ + "step", + [ + "get", + "symbolrank" + ], + 21, + 6, + 16, + 7, + 14 + ] + ], + "text-transform": "uppercase", + "text-font": [ + "DIN Pro Bold", + "Arial Unicode MS Bold" + ], + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-letter-spacing": 0.15, + "text-max-width": 6 + }, + "paint": { + "text-color": "hsl(230, 29%, 0%)", + "text-halo-color": "hsl(60, 25%, 100%)", + "text-halo-width": 1, + "text-opacity": 0.5 + }, + "metadata": { + "mapbox:featureComponent": "place-labels", + "mapbox:group": "Place labels, place-labels" + } + }, + { + "id": "country-label", + "type": "symbol", + "source": "composite", + "source-layer": "place_label", + "minzoom": 1, + "maxzoom": 10, + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "country", + "disputed_country" + ], + [ + "match", + [ + "get", + "worldview" + ], + [ + "all", + "US" + ], + true, + false + ], + false ], - 22, - 4, - 19, - 5, - 17 - ] - ] - }, - "paint": { - "icon-opacity": [ - "step", - [ - "zoom" - ], - [ - "case", - [ - "has", - "text_anchor" + "layout": { + "icon-image": "", + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-line-height": 1.1, + "text-max-width": 6, + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "text-radial-offset": [ + "step", + [ + "zoom" + ], + 0.6, + 8, + 0 + ], + "text-justify": [ + "step", + [ + "zoom" + ], + [ + "match", + [ + "get", + "text_anchor" + ], + [ + "left", + "bottom-left", + "top-left" + ], + "left", + [ + "right", + "bottom-right", + "top-right" + ], + "right", + "center" + ], + 7, + "auto" + ], + "text-size": [ + "interpolate", + [ + "cubic-bezier", + 0.2, + 0, + 0.7, + 1 + ], + [ + "zoom" + ], + 1, + [ + "step", + [ + "get", + "symbolrank" + ], + 11, + 4, + 9, + 5, + 8 + ], + 9, + [ + "step", + [ + "get", + "symbolrank" + ], + 22, + 4, + 19, + 5, + 17 + ] + ] + }, + "paint": { + "icon-opacity": [ + "step", + [ + "zoom" + ], + [ + "case", + [ + "has", + "text_anchor" + ], + 1, + 0 + ], + 7, + 0 + ], + "text-color": "hsl(230, 29%, 0%)", + "text-halo-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 2, + "hsla(60, 25%, 100%, 0.75)", + 3, + "hsl(60, 25%, 100%)" + ], + "text-halo-width": 1.25 + }, + "metadata": { + "mapbox:featureComponent": "place-labels", + "mapbox:group": "Place labels, place-labels" + } + }, + { + "id": "continent-label", + "type": "symbol", + "source": "composite", + "source-layer": "natural_label", + "minzoom": 0.75, + "maxzoom": 3, + "filter": [ + "==", + [ + "get", + "class" + ], + "continent" ], - 1, - 0 - ], - 7, - 0 - ], - "text-color": "hsl(230, 29%, 0%)", - "text-halo-color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 2, - "hsla(60, 25%, 100%, 0.75)", - 3, - "hsl(60, 25%, 100%)" - ], - "text-halo-width": 1.25 - }, - "metadata": { - "mapbox:featureComponent": "place-labels", - "mapbox:group": "Place labels, place-labels" - } - }, - { - "id": "continent-label", - "type": "symbol", - "source": "composite", - "source-layer": "natural_label", - "minzoom": 0.75, - "maxzoom": 3, - "filter": [ - "==", - [ - "get", - "class" - ], - "continent" - ], - "layout": { - "text-field": [ - "coalesce", - [ - "get", - "name_en" - ], - [ - "get", - "name" - ] - ], - "text-line-height": 1.1, - "text-max-width": 6, - "text-font": [ - "DIN Pro Medium", - "Arial Unicode MS Regular" - ], - "text-size": [ - "interpolate", - [ - "exponential", - 0.5 - ], - [ - "zoom" - ], - 0, - 10, - 2.5, - 15 - ], - "text-transform": "uppercase", - "text-letter-spacing": 0.05 - }, - "paint": { - "text-color": "hsl(230, 29%, 0%)", - "text-halo-color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 0, - "hsla(60, 25%, 100%, 0.75)", - 3, - "hsl(60, 25%, 100%)" - ], - "text-halo-width": 1.5, - "text-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 0, - 0.8, - 1.5, - 0.5, - 2.5, - 0 - ] - }, - "metadata": { - "mapbox:featureComponent": "place-labels", - "mapbox:group": "Place labels, place-labels" - } - } - ], - "sources": { - "composite": { - "url": "mapbox://mapbox.mapbox-streets-v8,mapbox.mapbox-terrain-v2,mapbox.mapbox-bathymetry-v2", - "type": "vector" - } - }, - "created": "1970-01-01T00:00:00.000Z", - "modified": "1970-01-01T00:00:00.000Z", - "owner": "mapbox", - "id": "outdoors-v12", - "draft": false + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ], + "text-line-height": 1.1, + "text-max-width": 6, + "text-font": [ + "DIN Pro Medium", + "Arial Unicode MS Regular" + ], + "text-size": [ + "interpolate", + [ + "exponential", + 0.5 + ], + [ + "zoom" + ], + 0, + 10, + 2.5, + 15 + ], + "text-transform": "uppercase", + "text-letter-spacing": 0.05 + }, + "paint": { + "text-color": "hsl(230, 29%, 0%)", + "text-halo-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 0, + "hsla(60, 25%, 100%, 0.75)", + 3, + "hsl(60, 25%, 100%)" + ], + "text-halo-width": 1.5, + "text-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 0, + 0.8, + 1.5, + 0.5, + 2.5, + 0 + ] + }, + "metadata": { + "mapbox:featureComponent": "place-labels", + "mapbox:group": "Place labels, place-labels" + } + } + ], + "sources": { + "composite": { + "url": "mapbox://mapbox.mapbox-streets-v8,mapbox.mapbox-terrain-v2,mapbox.mapbox-bathymetry-v2", + "type": "vector" + } + }, + "created": "1970-01-01T00:00:00.000Z", + "modified": "1970-01-01T00:00:00.000Z", + "owner": "mapbox", + "id": "outdoors-v12", + "draft": false } diff --git a/play-services-maps-core-mapbox/src/main/assets/style-microg-normal.json b/play-services-maps-core-mapbox/src/main/assets/style-microg-normal.json index ed39d1b6c..9490b1108 100644 --- a/play-services-maps-core-mapbox/src/main/assets/style-microg-normal.json +++ b/play-services-maps-core-mapbox/src/main/assets/style-microg-normal.json @@ -43,7 +43,10 @@ }, "mapbox:uiParadigm": "layers" }, - "center": [12.819420849458652, 50.03325860617235], + "center": [ + 12.819420849458652, + 50.03325860617235 + ], "zoom": 3.315829104862067, "bearing": 0, "pitch": 1.5, @@ -68,8 +71,12 @@ "paint": { "background-color": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 4, "hsl(43, 30%, 91%)", 5, @@ -88,16 +95,33 @@ { "id": "grass", "type": "fill", - "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "metadata": { + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + }, "source": "composite", "source-layer": "landcover", - "filter": ["match", ["get", "class"], ["grass"], true, false], + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "grass" + ], + true, + false + ], "layout": {}, "paint": { "fill-color": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 9, "hsl(124, 30%, 90%)", 11, @@ -112,13 +136,21 @@ { "id": "forrest", "type": "fill", - "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "metadata": { + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + }, "source": "composite", "source-layer": "landcover", "filter": [ "match", - ["get", "class"], - ["wood", "scrub"], + [ + "get", + "class" + ], + [ + "wood", + "scrub" + ], true, false ], @@ -126,8 +158,12 @@ "paint": { "fill-color": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 9, "hsl(124, 42%, 86%)", 11, @@ -142,41 +178,71 @@ { "id": "national_park", "type": "fill", - "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "metadata": { + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + }, "source": "composite", "source-layer": "landuse_overlay", "filter": [ "match", - ["get", "class"], - ["national_park"], + [ + "get", + "class" + ], + [ + "national_park" + ], true, false ], "layout": {}, - "paint": {"fill-color": "hsl(106, 58%, 85%)"} + "paint": { + "fill-color": "hsl(106, 58%, 85%)" + } }, { "id": "snow", "type": "fill", - "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "metadata": { + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + }, "source": "composite", "source-layer": "landcover", - "filter": ["match", ["get", "class"], ["snow"], true, false], + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "snow" + ], + true, + false + ], "layout": {}, - "paint": {"fill-color": "#f9fafc"} + "paint": { + "fill-color": "#f9fafc" + } }, { "id": "hillshade", "type": "fill", - "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "metadata": { + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + }, "source": "composite", "source-layer": "hillshade", "layout": {}, "paint": { "fill-opacity": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 9, 0.03, 13, @@ -187,106 +253,229 @@ { "id": "park", "type": "fill", - "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "metadata": { + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + }, "source": "composite", "source-layer": "landuse", "filter": [ "match", - ["get", "class"], - ["park", "scrub"], + [ + "get", + "class" + ], + [ + "park", + "scrub" + ], true, false ], "layout": {}, - "paint": {"fill-color": "#c1ecaf"} + "paint": { + "fill-color": "#c1ecaf" + } }, { "id": "pitch", "type": "fill", - "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "metadata": { + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + }, "source": "composite", "source-layer": "landuse", - "filter": ["match", ["get", "class"], ["pitch"], true, false], + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "pitch" + ], + true, + false + ], "layout": {}, - "paint": {"fill-color": "#c8efbb"} + "paint": { + "fill-color": "#c8efbb" + } }, { "id": "landuse", "type": "fill", - "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "metadata": { + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + }, "source": "composite", "source-layer": "landuse", "filter": [ "match", - ["get", "class"], - ["airport", "school", "hospital"], + [ + "get", + "class" + ], + [ + "airport", + "school", + "hospital" + ], true, false ], "layout": {}, - "paint": {"fill-color": "hsl(202, 26%, 94%)"} + "paint": { + "fill-color": "hsl(202, 26%, 94%)" + } }, { "id": "river", "type": "fill", - "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "metadata": { + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + }, "source": "composite", "source-layer": "water", "layout": {}, - "paint": {"fill-color": "hsl(206, 100%, 83%)"} + "paint": { + "fill-color": "hsl(206, 100%, 83%)" + } }, { "id": "path", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", - ["match", ["get", "class"], ["path"], true, false], - ["match", ["get", "type"], ["platform", "steps"], false, true] + [ + "match", + [ + "get", + "class" + ], + [ + "path" + ], + true, + false + ], + [ + "match", + [ + "get", + "type" + ], + [ + "platform", + "steps" + ], + false, + true + ] ], "layout": {}, "paint": { "line-color": "hsl(118, 34%, 66%)", - "line-dasharray": [4, 2] + "line-dasharray": [ + 4, + 2 + ] } }, { "id": "steps", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", - ["match", ["get", "class"], ["path"], true, false], - ["match", ["get", "type"], ["steps"], true, false] + [ + "match", + [ + "get", + "class" + ], + [ + "path" + ], + true, + false + ], + [ + "match", + [ + "get", + "type" + ], + [ + "steps" + ], + true, + false + ] ], "layout": {}, "paint": { "line-color": "hsl(118, 5%, 66%)", - "line-dasharray": [1, 1], + "line-dasharray": [ + 1, + 1 + ], "line-gap-width": 1 } }, { "id": "platform", "type": "fill", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", - ["match", ["get", "type"], ["platform"], true, false], - ["match", ["get", "structure"], ["tunnel"], false, true] + [ + "match", + [ + "get", + "type" + ], + [ + "platform" + ], + true, + false + ], + [ + "match", + [ + "get", + "structure" + ], + [ + "tunnel" + ], + false, + true + ] ], "layout": {}, "paint": { "fill-color": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 15, "hsl(2, 20%, 92%)", 16, @@ -294,8 +483,12 @@ ], "fill-outline-color": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 15, "hsl(1, 10%, 76%)", 16, @@ -303,8 +496,12 @@ ], "fill-opacity": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 0, 16, @@ -315,26 +512,50 @@ { "id": "primary_tunnel_border", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", [ "match", - ["get", "class"], - ["primary_link", "primary", "motorway_link"], + [ + "get", + "class" + ], + [ + "primary_link", + "primary", + "motorway_link" + ], true, false ], - ["match", ["get", "structure"], ["tunnel"], true, false] + [ + "match", + [ + "get", + "structure" + ], + [ + "tunnel" + ], + true, + false + ] ], "layout": {}, "paint": { "line-gap-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 7, 0, 8, @@ -354,26 +575,50 @@ { "id": "primary_tunnel", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", [ "match", - ["get", "class"], - ["primary_link", "primary", "motorway_link"], + [ + "get", + "class" + ], + [ + "primary_link", + "primary", + "motorway_link" + ], true, false ], - ["match", ["get", "structure"], ["tunnel"], true, false] + [ + "match", + [ + "get", + "structure" + ], + [ + "tunnel" + ], + true, + false + ] ], "layout": {}, "paint": { "line-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 8, 1, 12, @@ -391,39 +636,78 @@ { "id": "aeroway", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "aeroway", "layout": {}, - "paint": {"line-color": "hsla(0, 0%, 0%, 0.1)"} + "paint": { + "line-color": "hsla(0, 0%, 0%, 0.1)" + } }, { "id": "service_road", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", - "filter": ["match", ["get", "class"], ["service"], true, false], + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "service" + ], + true, + false + ], "layout": {}, - "paint": {"line-color": "hsla(0, 0%, 0%, 0.1)"} + "paint": { + "line-color": "hsla(0, 0%, 0%, 0.1)" + } }, { "id": "pedestrian_border", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", - ["match", ["get", "class"], ["pedestrian"], true, false], - ["has", "name"] + [ + "match", + [ + "get", + "class" + ], + [ + "pedestrian" + ], + true, + false + ], + [ + "has", + "name" + ] ], "layout": {}, "paint": { "line-gap-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 13, 1, 16, @@ -434,8 +718,12 @@ "line-color": "#e3e3e3", "line-opacity": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 12.5, 0, 13.5, @@ -446,16 +734,33 @@ { "id": "street_border", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", - "filter": ["match", ["get", "class"], ["street"], true, false], + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "street" + ], + true, + false + ], "layout": {}, "paint": { "line-gap-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 12, 1, 16, @@ -469,12 +774,17 @@ { "id": "secondary_border", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "match", - ["get", "class"], + [ + "get", + "class" + ], [ "secondary", "secondary_link", @@ -490,8 +800,12 @@ "paint": { "line-gap-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 10, 1, 17, @@ -502,8 +816,12 @@ "line-color": "#e3e3e3", "line-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 16, 1, 20, @@ -514,26 +832,52 @@ { "id": "primary_border", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", [ "match", - ["get", "class"], - ["primary_link", "primary", "motorway_link"], + [ + "get", + "class" + ], + [ + "primary_link", + "primary", + "motorway_link" + ], true, false ], - ["match", ["get", "structure"], ["tunnel"], false, true] - ], - "layout": {"line-cap": "round"}, - "paint": { - "line-gap-width": [ + [ + "match", + [ + "get", + "structure" + ], + [ + "tunnel" + ], + false, + true + ] + ], + "layout": { + "line-cap": "round" + }, + "paint": { + "line-gap-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 9, 1, 16, @@ -547,16 +891,33 @@ { "id": "motorway_border", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", - "filter": ["match", ["get", "class"], ["motorway"], true, false], + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "motorway" + ], + true, + false + ], "layout": {}, "paint": { "line-gap-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 8, 1, 15.5, @@ -565,48 +926,113 @@ 78 ], "line-color": "#ecd283", - "line-width": ["interpolate", ["linear"], ["zoom"], 8, 1, 15, 2] + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 8, + 1, + 15, + 2 + ] } }, { "id": "railway", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", [ "match", - ["get", "class"], - ["major_rail", "minor_rail", "service_rail"], + [ + "get", + "class" + ], + [ + "major_rail", + "minor_rail", + "service_rail" + ], true, false ], - ["match", ["get", "structure"], ["tunnel"], false, true] + [ + "match", + [ + "get", + "structure" + ], + [ + "tunnel" + ], + false, + true + ] ], "layout": {}, - "paint": {"line-color": "hsl(220, 4%, 85%)"} + "paint": { + "line-color": "hsl(220, 4%, 85%)" + } }, { "id": "pedestrian", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", - ["match", ["get", "class"], ["pedestrian"], true, false], - ["has", "name"], - ["match", ["get", "type"], ["platform"], false, true] + [ + "match", + [ + "get", + "class" + ], + [ + "pedestrian" + ], + true, + false + ], + [ + "has", + "name" + ], + [ + "match", + [ + "get", + "type" + ], + [ + "platform" + ], + false, + true + ] ], "layout": {}, "paint": { "line-color": "#ffffff", "line-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 13, 1, 16, @@ -616,8 +1042,12 @@ ], "line-opacity": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 12.5, 0, 13.5, @@ -628,17 +1058,34 @@ { "id": "street", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", - "filter": ["match", ["get", "class"], ["street"], true, false], + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "street" + ], + true, + false + ], "layout": {}, "paint": { "line-color": "#ffffff", "line-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 12, 1, 16, @@ -651,12 +1098,17 @@ { "id": "secondary", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "match", - ["get", "class"], + [ + "get", + "class" + ], [ "secondary", "secondary_link", @@ -673,8 +1125,12 @@ "line-color": "#ffffff", "line-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 10, 1, 17, @@ -687,33 +1143,61 @@ { "id": "primary", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", [ "match", - ["get", "class"], - ["primary_link", "primary", "motorway_link"], + [ + "get", + "class" + ], + [ + "primary_link", + "primary", + "motorway_link" + ], true, false ], - ["match", ["get", "structure"], ["tunnel"], false, true] + [ + "match", + [ + "get", + "structure" + ], + [ + "tunnel" + ], + false, + true + ] ], - "layout": {"line-cap": "round"}, + "layout": { + "line-cap": "round" + }, "paint": { "line-color": [ "step", - ["zoom"], + [ + "zoom" + ], "hsl(50, 100%, 75%)", 7, "hsl(50, 100%, 85%)" ], "line-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 9, 1, 16, @@ -726,17 +1210,34 @@ { "id": "motorway", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", - "filter": ["match", ["get", "class"], ["motorway"], true, false], + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "motorway" + ], + true, + false + ], "layout": {}, "paint": { "line-color": "#ffeba3", "line-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 8, 1, 15.5, @@ -749,26 +1250,50 @@ { "id": "primary_bridge_border", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", [ "match", - ["get", "class"], - ["primary_link", "primary", "motorway_link"], + [ + "get", + "class" + ], + [ + "primary_link", + "primary", + "motorway_link" + ], true, false ], - ["match", ["get", "structure"], ["bridge"], true, false] + [ + "match", + [ + "get", + "structure" + ], + [ + "bridge" + ], + true, + false + ] ], "layout": {}, "paint": { "line-gap-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 9, 1, 16, @@ -782,33 +1307,59 @@ { "id": "primary_bridge", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", [ "match", - ["get", "class"], - ["primary_link", "primary", "motorway_link"], + [ + "get", + "class" + ], + [ + "primary_link", + "primary", + "motorway_link" + ], true, false ], - ["match", ["get", "structure"], ["bridge"], true, false] + [ + "match", + [ + "get", + "structure" + ], + [ + "bridge" + ], + true, + false + ] ], "layout": {}, "paint": { "line-color": [ "step", - ["zoom"], + [ + "zoom" + ], "hsl(50, 100%, 75%)", 7, "hsl(50, 100%, 85%)" ], "line-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 9, 1, 16, @@ -821,15 +1372,31 @@ { "id": "building", "type": "fill", - "metadata": {"mapbox:group": "29bb589e8d1b9b402583363648b70302"}, + "metadata": { + "mapbox:group": "29bb589e8d1b9b402583363648b70302" + }, "source": "composite", "source-layer": "building", - "filter": ["match", ["get", "type"], ["roof"], false, true], + "filter": [ + "match", + [ + "get", + "type" + ], + [ + "roof" + ], + false, + true + ], "layout": {}, "paint": { "fill-color": [ "match", - ["get", "type"], + [ + "get", + "type" + ], [ "store", "retail", @@ -846,8 +1413,12 @@ ], "fill-opacity": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 15, 0, 17, @@ -858,15 +1429,31 @@ { "id": "building_border", "type": "line", - "metadata": {"mapbox:group": "29bb589e8d1b9b402583363648b70302"}, + "metadata": { + "mapbox:group": "29bb589e8d1b9b402583363648b70302" + }, "source": "composite", "source-layer": "building", - "filter": ["match", ["get", "type"], ["roof"], false, true], + "filter": [ + "match", + [ + "get", + "type" + ], + [ + "roof" + ], + false, + true + ], "layout": {}, "paint": { "line-color": [ "match", - ["get", "type"], + [ + "get", + "type" + ], [ "store", "retail", @@ -883,8 +1470,12 @@ ], "line-opacity": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 15, 0, 17, @@ -895,20 +1486,40 @@ { "id": "building_3d", "type": "fill-extrusion", - "metadata": {"mapbox:group": "29bb589e8d1b9b402583363648b70302"}, + "metadata": { + "mapbox:group": "29bb589e8d1b9b402583363648b70302" + }, "source": "composite", "source-layer": "building", - "filter": ["match", ["get", "extrude"], ["true"], true, false], + "filter": [ + "match", + [ + "get", + "extrude" + ], + [ + "true" + ], + true, + false + ], "layout": {}, "paint": { "fill-extrusion-height": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 15, 0, 16, - ["get", "height"] + [ + "get", + "height" + ] ], "fill-extrusion-opacity": 0.3, "fill-extrusion-color": "hsl(0, 0%, 93%)" @@ -917,19 +1528,50 @@ { "id": "admin_0", "type": "line", - "metadata": {"mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa"}, + "metadata": { + "mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa" + }, "source": "composite", "source-layer": "admin", "filter": [ "all", - ["match", ["get", "maritime"], ["false"], true, false], - ["match", ["get", "admin_level"], [0], true, false] + [ + "match", + [ + "get", + "maritime" + ], + [ + "false" + ], + true, + false + ], + [ + "match", + [ + "get", + "admin_level" + ], + [ + 0 + ], + true, + false + ] ], "layout": {}, "paint": { "line-color": [ "case", - ["==", ["get", "disputed"], true], + [ + "==", + [ + "get", + "disputed" + ], + true + ], "hsl(0, 24%, 48%)", "#787a7b" ] @@ -938,37 +1580,92 @@ { "id": "admin_1", "type": "line", - "metadata": {"mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa"}, + "metadata": { + "mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa" + }, "source": "composite", "source-layer": "admin", "filter": [ "all", - ["match", ["get", "maritime"], ["false"], true, false], - ["match", ["get", "admin_level"], [1], true, false] - ], - "layout": {}, - "paint": { - "line-color": [ - "case", - ["==", ["get", "disputed"], true], - "hsl(0, 24%, 48%)", - "#787a7b" - ], - "line-dasharray": [1, 1] - } - }, - { - "id": "river_name", - "type": "symbol", - "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + [ + "match", + [ + "get", + "maritime" + ], + [ + "false" + ], + true, + false + ], + [ + "match", + [ + "get", + "admin_level" + ], + [ + 1 + ], + true, + false + ] + ], + "layout": {}, + "paint": { + "line-color": [ + "case", + [ + "==", + [ + "get", + "disputed" + ], + true + ], + "hsl(0, 24%, 48%)", + "#787a7b" + ], + "line-dasharray": [ + 1, + 1 + ] + } + }, + { + "id": "river_name", + "type": "symbol", + "metadata": { + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + }, "source": "composite", "source-layer": "natural_label", - "filter": ["match", ["get", "class"], ["river"], true, false], + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "river" + ], + true, + false + ], "layout": { - "text-field": ["to-string", ["get", "name"]], + "text-field": [ + "to-string", + [ + "get", + "name" + ] + ], "symbol-placement": "line", "symbol-spacing": 500, - "text-font": ["Roboto Regular"] + "text-font": [ + "Roboto Regular" + ] }, "paint": { "text-color": "#5083c1", @@ -979,17 +1676,38 @@ { "id": "city_label_right", "type": "symbol", - "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "metadata": { + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + }, "source": "composite", "source-layer": "place_label", "maxzoom": 8, "filter": [ "all", - ["<=", ["get", "filterrank"], ["/", ["zoom"], 3]], + [ + "<=", + [ + "get", + "filterrank" + ], + [ + "/", + [ + "zoom" + ], + 3 + ] + ], [ "match", - ["get", "class"], - ["settlement", "settlement_subdivision"], + [ + "get", + "class" + ], + [ + "settlement", + "settlement_subdivision" + ], true, false ] @@ -998,50 +1716,141 @@ "text-optional": true, "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 0, - ["-", 14, ["max", 0, ["-", ["get", "symbolrank"], 8]]], + [ + "-", + 14, + [ + "max", + 0, + [ + "-", + [ + "get", + "symbolrank" + ], + 8 + ] + ] + ], 22, - ["-", 20, ["/", ["get", "symbolrank"], 4]] + [ + "-", + 20, + [ + "/", + [ + "get", + "symbolrank" + ], + 4 + ] + ] ], "icon-image": [ "match", - ["get", "capital"], - [0, 2], + [ + "get", + "capital" + ], + [ + 0, + 2 + ], "capital", "city" ], "text-font": [ "step", - ["get", "symbolrank"], - ["literal", ["Roboto Medium"]], + [ + "get", + "symbolrank" + ], + [ + "literal", + [ + "Roboto Medium" + ] + ], 10, - ["literal", ["Roboto Regular"]] + [ + "literal", + [ + "Roboto Regular" + ] + ] ], "text-justify": "left", - "text-offset": [0.5, 0.1], - "icon-size": ["/", 5, ["get", "symbolrank"]], + "text-offset": [ + 0.5, + 0.1 + ], + "icon-size": [ + "/", + 5, + [ + "get", + "symbolrank" + ] + ], "text-anchor": "left", - "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]] + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] }, "paint": { "text-color": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 0, [ "concat", "hsl(213, 11%, ", - ["+", ["*", ["get", "symbolrank"], 2], 5], + [ + "+", + [ + "*", + [ + "get", + "symbolrank" + ], + 2 + ], + 5 + ], "%)" ], 22, [ "concat", "hsl(213, 11%, ", - ["+", ["get", "symbolrank"], 25], + [ + "+", + [ + "get", + "symbolrank" + ], + 25 + ], "%)" ] ], @@ -1054,17 +1863,38 @@ { "id": "city_label_left", "type": "symbol", - "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "metadata": { + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + }, "source": "composite", "source-layer": "place_label", "maxzoom": 8, "filter": [ "all", - ["<=", ["get", "filterrank"], ["/", ["zoom"], 3]], + [ + "<=", + [ + "get", + "filterrank" + ], + [ + "/", + [ + "zoom" + ], + 3 + ] + ], [ "match", - ["get", "class"], - ["settlement", "settlement_subdivision"], + [ + "get", + "class" + ], + [ + "settlement", + "settlement_subdivision" + ], true, false ] @@ -1072,50 +1902,141 @@ "layout": { "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 0, - ["-", 14, ["max", 0, ["-", ["get", "symbolrank"], 8]]], + [ + "-", + 14, + [ + "max", + 0, + [ + "-", + [ + "get", + "symbolrank" + ], + 8 + ] + ] + ], 22, - ["-", 20, ["/", ["get", "symbolrank"], 4]] + [ + "-", + 20, + [ + "/", + [ + "get", + "symbolrank" + ], + 4 + ] + ] ], "icon-image": [ "match", - ["get", "capital"], - [0, 2], + [ + "get", + "capital" + ], + [ + 0, + 2 + ], "capital", "city" ], "text-font": [ "step", - ["get", "symbolrank"], - ["literal", ["Roboto Medium"]], + [ + "get", + "symbolrank" + ], + [ + "literal", + [ + "Roboto Medium" + ] + ], 10, - ["literal", ["Roboto Regular"]] + [ + "literal", + [ + "Roboto Regular" + ] + ] ], "text-justify": "right", - "text-offset": [-0.5, 0.1], - "icon-size": ["/", 5, ["get", "symbolrank"]], + "text-offset": [ + -0.5, + 0.1 + ], + "icon-size": [ + "/", + 5, + [ + "get", + "symbolrank" + ] + ], "text-anchor": "right", - "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]] + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] }, "paint": { "text-color": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 0, [ "concat", "hsl(213, 11%, ", - ["+", ["*", ["get", "symbolrank"], 2], 5], + [ + "+", + [ + "*", + [ + "get", + "symbolrank" + ], + 2 + ], + 5 + ], "%)" ], 22, [ "concat", "hsl(213, 11%, ", - ["+", ["get", "symbolrank"], 25], + [ + "+", + [ + "get", + "symbolrank" + ], + 25 + ], "%)" ] ], @@ -1128,17 +2049,38 @@ { "id": "city_label_below", "type": "symbol", - "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "metadata": { + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + }, "source": "composite", "source-layer": "place_label", "maxzoom": 8, "filter": [ "all", - ["<=", ["get", "filterrank"], ["/", ["zoom"], 3]], + [ + "<=", + [ + "get", + "filterrank" + ], + [ + "/", + [ + "zoom" + ], + 3 + ] + ], [ "match", - ["get", "class"], - ["settlement", "settlement_subdivision"], + [ + "get", + "class" + ], + [ + "settlement", + "settlement_subdivision" + ], true, false ] @@ -1146,49 +2088,140 @@ "layout": { "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 0, - ["-", 14, ["max", 0, ["-", ["get", "symbolrank"], 8]]], + [ + "-", + 14, + [ + "max", + 0, + [ + "-", + [ + "get", + "symbolrank" + ], + 8 + ] + ] + ], 22, - ["-", 20, ["/", ["get", "symbolrank"], 4]] + [ + "-", + 20, + [ + "/", + [ + "get", + "symbolrank" + ], + 4 + ] + ] ], "icon-image": [ "match", - ["get", "capital"], - [0, 2], + [ + "get", + "capital" + ], + [ + 0, + 2 + ], "capital", "city" ], "text-font": [ "step", - ["get", "symbolrank"], - ["literal", ["Roboto Medium"]], + [ + "get", + "symbolrank" + ], + [ + "literal", + [ + "Roboto Medium" + ] + ], 10, - ["literal", ["Roboto Regular"]] + [ + "literal", + [ + "Roboto Regular" + ] + ] + ], + "text-offset": [ + 0, + 0.4 + ], + "icon-size": [ + "/", + 5, + [ + "get", + "symbolrank" + ] ], - "text-offset": [0, 0.4], - "icon-size": ["/", 5, ["get", "symbolrank"]], "text-anchor": "top", - "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]] + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] }, "paint": { "text-color": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 0, [ "concat", "hsl(213, 11%, ", - ["+", ["*", ["get", "symbolrank"], 2], 5], + [ + "+", + [ + "*", + [ + "get", + "symbolrank" + ], + 2 + ], + 5 + ], "%)" ], 22, [ "concat", "hsl(213, 11%, ", - ["+", ["get", "symbolrank"], 25], + [ + "+", + [ + "get", + "symbolrank" + ], + 25 + ], "%)" ] ], @@ -1201,16 +2234,37 @@ { "id": "city_name", "type": "symbol", - "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "metadata": { + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + }, "source": "composite", "source-layer": "place_label", "filter": [ "all", - ["<=", ["get", "filterrank"], ["/", ["zoom"], 3]], + [ + "<=", + [ + "get", + "filterrank" + ], + [ + "/", + [ + "zoom" + ], + 3 + ] + ], [ "match", - ["get", "class"], - ["settlement", "settlement_subdivision"], + [ + "get", + "class" + ], + [ + "settlement", + "settlement_subdivision" + ], true, false ] @@ -1218,48 +2272,152 @@ "layout": { "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 0, - ["-", 14, ["max", 0, ["-", ["get", "symbolrank"], 8]]], + [ + "-", + 14, + [ + "max", + 0, + [ + "-", + [ + "get", + "symbolrank" + ], + 8 + ] + ] + ], 22, - ["-", 20, ["/", ["get", "symbolrank"], 4]] + [ + "-", + 20, + [ + "/", + [ + "get", + "symbolrank" + ], + 4 + ] + ] ], "icon-image": [ "step", - ["zoom"], - ["match", ["get", "capital"], [0, 2], "capital", "city"], + [ + "zoom" + ], + [ + "match", + [ + "get", + "capital" + ], + [ + 0, + 2 + ], + "capital", + "city" + ], 8, "" ], "text-transform": [ "step", - ["get", "symbolrank"], + [ + "get", + "symbolrank" + ], "none", 15, "uppercase" ], - "text-font": [ - "step", - ["get", "symbolrank"], - ["literal", ["Roboto Medium"]], - 10, - ["literal", ["Roboto Regular"]] + "text-font": [ + "step", + [ + "get", + "symbolrank" + ], + [ + "literal", + [ + "Roboto Medium" + ] + ], + 10, + [ + "literal", + [ + "Roboto Regular" + ] + ] + ], + "text-offset": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 0, + -0.2 + ] + ], + 8, + [ + "literal", + [ + 0, + 0 + ] + ] + ], + "icon-size": [ + "/", + 5, + [ + "get", + "symbolrank" + ] ], - "text-offset": [ + "text-anchor": [ "step", - ["zoom"], - ["literal", [0, -0.2]], + [ + "zoom" + ], + "bottom", 8, - ["literal", [0, 0]] + "center" + ], + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] ], - "icon-size": ["/", 5, ["get", "symbolrank"]], - "text-anchor": ["step", ["zoom"], "bottom", 8, "center"], - "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]], "text-letter-spacing": [ "interpolate", - ["linear"], - ["get", "symbolrank"], + [ + "linear" + ], + [ + "get", + "symbolrank" + ], 0, 0, 8, @@ -1273,20 +2431,42 @@ "paint": { "text-color": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 0, [ "concat", "hsl(213, 11%, ", - ["+", ["*", ["get", "symbolrank"], 2], 5], + [ + "+", + [ + "*", + [ + "get", + "symbolrank" + ], + 2 + ], + 5 + ], "%)" ], 22, [ "concat", "hsl(213, 11%, ", - ["+", ["get", "symbolrank"], 25], + [ + "+", + [ + "get", + "symbolrank" + ], + 25 + ], "%)" ] ], @@ -1299,18 +2479,52 @@ { "id": "park_name", "type": "symbol", - "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "metadata": { + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce", + "microg:gms-type-feature": "poi", + "microg:gms-type-element": "label" + }, "source": "composite", "source-layer": "poi_label", "filter": [ "all", - ["has", "name"], - ["match", ["get", "maki"], ["park", "cemetery"], true, false], - ["<=", ["get", "sizerank"], 10] + [ + "has", + "name" + ], + [ + "match", + [ + "get", + "maki" + ], + [ + "park", + "cemetery" + ], + true, + false + ], + [ + "<=", + [ + "get", + "sizerank" + ], + 10 + ] ], "layout": { - "text-field": ["to-string", ["get", "name"]], - "text-font": ["Roboto Regular"], + "text-field": [ + "to-string", + [ + "get", + "name" + ] + ], + "text-font": [ + "Roboto Regular" + ], "text-size": 14 }, "paint": { @@ -1323,17 +2537,36 @@ { "id": "road-number-shield", "type": "symbol", - "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "metadata": { + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + }, "source": "composite", "source-layer": "road", - "filter": ["all", ["has", "ref"], ["<=", ["get", "reflen"], 6]], + "filter": [ + "all", + [ + "has", + "ref" + ], + [ + "<=", + [ + "get", + "reflen" + ], + 6 + ] + ], "layout": { "text-size": 9, "icon-image": [ "case", [ "match", - ["get", "shield"], + [ + "get", + "shield" + ], [ "de-motorway", "rectangle-green", @@ -1349,35 +2582,96 @@ [ "concat", "shield_", - ["get", "shield"], + [ + "get", + "shield" + ], "_", - ["get", "reflen"] + [ + "get", + "reflen" + ] ], [ "match", - ["get", "shield_text_color"], - ["white"], + [ + "get", + "shield_text_color" + ], + [ + "white" + ], true, false ], - ["concat", "shield_rectangle-blue_", ["get", "reflen"]], - ["concat", "shield_rectangle-white_", ["get", "reflen"]] + [ + "concat", + "shield_rectangle-blue_", + [ + "get", + "reflen" + ] + ], + [ + "concat", + "shield_rectangle-white_", + [ + "get", + "reflen" + ] + ] ], "icon-rotation-alignment": "viewport", "text-font": [ "match", - ["get", "shield_text_color"], - ["white"], - ["literal", ["Roboto Bold"]], - ["black"], - ["literal", ["Roboto Medium"]], - ["literal", ["Roboto Bold"]] - ], - "symbol-placement": ["step", ["zoom"], "point", 11, "line"], - "text-offset": [0, 0.1], + [ + "get", + "shield_text_color" + ], + [ + "white" + ], + [ + "literal", + [ + "Roboto Bold" + ] + ], + [ + "black" + ], + [ + "literal", + [ + "Roboto Medium" + ] + ], + [ + "literal", + [ + "Roboto Bold" + ] + ] + ], + "symbol-placement": [ + "step", + [ + "zoom" + ], + "point", + 11, + "line" + ], + "text-offset": [ + 0, + 0.1 + ], "text-rotation-alignment": "viewport", "icon-size": 0.75, - "text-field": ["get", "ref"], + "text-field": [ + "get", + "ref" + ], "text-letter-spacing": 0.05 }, "paint": { @@ -1385,40 +2679,65 @@ "case", [ "match", - ["get", "shield_text_color"], - ["white"], + [ + "get", + "shield_text_color" + ], + [ + "white" + ], true, false ], "#ffffff", [ "match", - ["get", "shield_text_color"], - ["black"], + [ + "get", + "shield_text_color" + ], + [ + "black" + ], true, false ], "hsl(0, 0%, 7%)", [ "match", - ["get", "shield_text_color"], - ["yellow"], + [ + "get", + "shield_text_color" + ], + [ + "yellow" + ], true, false ], "hsl(50, 100%, 70%)", [ "match", - ["get", "shield_text_color"], - ["orange"], + [ + "get", + "shield_text_color" + ], + [ + "orange" + ], true, false ], "hsl(25, 100%, 75%)", [ "match", - ["get", "shield_text_color"], - ["blue"], + [ + "get", + "shield_text_color" + ], + [ + "blue" + ], true, false ], @@ -1430,31 +2749,72 @@ { "id": "country_name", "type": "symbol", - "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "metadata": { + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + }, "source": "composite", "source-layer": "place_label", - "filter": ["match", ["get", "class"], ["country"], true, false], + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "country" + ], + true, + false + ], "layout": { "text-letter-spacing": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 1, 0, 3, 0.15 ], - "text-font": ["Roboto Medium"], + "text-font": [ + "Roboto Medium" + ], "text-size": [ "interpolate", - ["exponential", 1.2], - ["zoom"], + [ + "exponential", + 1.2 + ], + [ + "zoom" + ], 1, 12, 7, - ["/", 100, ["get", "symbolrank"]] + [ + "/", + 100, + [ + "get", + "symbolrank" + ] + ] ], - "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]] + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] }, "paint": { "text-color": "hsl(0, 0%, 10%)", @@ -1463,8 +2823,12 @@ "text-halo-blur": 1, "text-opacity": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 6, 1, 7, @@ -1475,24 +2839,60 @@ { "id": "pedestrian_name", "type": "symbol", - "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "metadata": { + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + }, "source": "composite", "source-layer": "road", "minzoom": 16, "filter": [ "all", - ["has", "name"], - ["match", ["get", "class"], ["pedestrian"], true, false], - ["match", ["get", "type"], ["platform"], false, true] + [ + "has", + "name" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "pedestrian" + ], + true, + false + ], + [ + "match", + [ + "get", + "type" + ], + [ + "platform" + ], + false, + true + ] ], "layout": { - "text-field": ["get", "name"], + "text-field": [ + "get", + "name" + ], "symbol-placement": "line", - "text-font": ["Roboto Regular"], + "text-font": [ + "Roboto Regular" + ], "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 17, 10, 22, @@ -1510,22 +2910,47 @@ { "id": "street_name", "type": "symbol", - "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "metadata": { + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + }, "source": "composite", "source-layer": "road", "filter": [ "all", - ["has", "name"], - ["match", ["get", "class"], ["street"], true, false] + [ + "has", + "name" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "street" + ], + true, + false + ] ], "layout": { - "text-field": ["get", "name"], + "text-field": [ + "get", + "name" + ], "symbol-placement": "line", - "text-font": ["Roboto Regular"], + "text-font": [ + "Roboto Regular" + ], "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 8, 6, 16, @@ -1543,15 +2968,23 @@ { "id": "secondary_name", "type": "symbol", - "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "metadata": { + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + }, "source": "composite", "source-layer": "road", "filter": [ "all", - ["has", "name"], + [ + "has", + "name" + ], [ "match", - ["get", "class"], + [ + "get", + "class" + ], [ "secondary", "secondary_link", @@ -1565,13 +2998,22 @@ ] ], "layout": { - "text-field": ["get", "name"], + "text-field": [ + "get", + "name" + ], "symbol-placement": "line", - "text-font": ["Roboto Regular"], + "text-font": [ + "Roboto Regular" + ], "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 8, 8, 16, @@ -1590,28 +3032,48 @@ { "id": "primary_name", "type": "symbol", - "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "metadata": { + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + }, "source": "composite", "source-layer": "road", "filter": [ "all", - ["has", "name"], + [ + "has", + "name" + ], [ "match", - ["get", "class"], - ["primary", "primary_link"], + [ + "get", + "class" + ], + [ + "primary", + "primary_link" + ], true, false ] ], "layout": { - "text-field": ["get", "name"], + "text-field": [ + "get", + "name" + ], "symbol-placement": "line", - "text-font": ["Roboto Regular"], + "text-font": [ + "Roboto Regular" + ], "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 8, 10, 18, @@ -1630,25 +3092,56 @@ { "id": "poi_label_below", "type": "symbol", - "metadata": {"mapbox:group": "124a9d7a8e5226775d947c592110dfad"}, + "metadata": { + "mapbox:group": "124a9d7a8e5226775d947c592110dfad" + }, "source": "composite", "source-layer": "poi_label", "filter": [ "all", - ["has", "name"], - ["<=", ["get", "filterrank"], ["/", ["zoom"], 3.5]], + [ + "has", + "name" + ], + [ + "<=", + [ + "get", + "filterrank" + ], + [ + "/", + [ + "zoom" + ], + 3.5 + ] + ], [ "!", [ "all", [ "match", - ["get", "maki"], - ["park", "cemetery"], + [ + "get", + "maki" + ], + [ + "park", + "cemetery" + ], true, false ], - ["<=", ["get", "sizerank"], 10] + [ + "<=", + [ + "get", + "sizerank" + ], + 10 + ] ] ] ], @@ -1656,8 +3149,12 @@ "text-optional": true, "text-line-height": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 1, 15, @@ -1665,19 +3162,42 @@ ], "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 13, 15, 14 ], - "icon-offset": [0, -36], + "icon-offset": [ + 0, + -36 + ], "icon-image": [ "match", - ["get", "maki"], - ["museum", "lodging", "theatre", "grocery", "restaurant"], - ["concat", "poi_", ["get", "maki"]], + [ + "get", + "maki" + ], + [ + "museum", + "lodging", + "theatre", + "grocery", + "restaurant" + ], + [ + "concat", + "poi_", + [ + "get", + "maki" + ] + ], [ "fitness-centre", "golf", @@ -1694,9 +3214,17 @@ "cemetery" ], "poi_generic_green", - ["bank", "parking", "parking-garage"], + [ + "bank", + "parking", + "parking-garage" + ], "poi_generic_purple", - ["bar", "cafe", "bakery"], + [ + "bar", + "cafe", + "bakery" + ], "poi_generic_orange", [ "alcohol-shop", @@ -1717,7 +3245,10 @@ "monument" ], "poi_generic_teal", - ["hospital", "doctor"], + [ + "hospital", + "doctor" + ], "poi_generic_red", [ "restaurant-pizza", @@ -1729,24 +3260,42 @@ "poi_restaurant", "poi_generic" ], - "text-font": ["Roboto Regular"], - "text-offset": [0, 0.5], + "text-font": [ + "Roboto Regular" + ], + "text-offset": [ + 0, + 0.5 + ], "icon-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 0.25, 15, 0.32 ], "text-anchor": "top", - "text-field": ["to-string", ["get", "name"]] + "text-field": [ + "to-string", + [ + "get", + "name" + ] + ] }, "paint": { "text-color": [ "match", - ["get", "maki"], + [ + "get", + "maki" + ], [ "museum", "casino", @@ -1759,7 +3308,9 @@ "monument" ], "hsl(186, 78%, 44%)", - ["lodging"], + [ + "lodging" + ], "#df7db1", [ "fitness-centre", @@ -1799,41 +3350,85 @@ "jewelry-store" ], "hsl(213, 40%, 48%)", - ["bank", "parking", "parking-garage"], + [ + "bank", + "parking", + "parking-garage" + ], "#737b9b", - ["hospital", "doctor"], + [ + "hospital", + "doctor" + ], "#a47172", "#67747b" ], "text-halo-color": "#ffffff", "text-halo-width": 1, - "icon-translate": [0, 0], - "text-translate": [0, 0], + "icon-translate": [ + 0, + 0 + ], + "text-translate": [ + 0, + 0 + ], "text-halo-blur": 1 } }, { "id": "poi_label_above", "type": "symbol", - "metadata": {"mapbox:group": "124a9d7a8e5226775d947c592110dfad"}, + "metadata": { + "mapbox:group": "124a9d7a8e5226775d947c592110dfad" + }, "source": "composite", "source-layer": "poi_label", "filter": [ "all", - ["has", "name"], - ["<=", ["get", "filterrank"], ["/", ["zoom"], 3.5]], + [ + "has", + "name" + ], + [ + "<=", + [ + "get", + "filterrank" + ], + [ + "/", + [ + "zoom" + ], + 3.5 + ] + ], [ "!", [ "all", [ "match", - ["get", "maki"], - ["park", "cemetery"], + [ + "get", + "maki" + ], + [ + "park", + "cemetery" + ], true, false ], - ["<=", ["get", "sizerank"], 10] + [ + "<=", + [ + "get", + "sizerank" + ], + 10 + ] ] ] ], @@ -1841,8 +3436,12 @@ "text-optional": true, "text-line-height": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 1, 15, @@ -1850,19 +3449,42 @@ ], "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 13, 15, 14 ], - "icon-offset": [0, -36], + "icon-offset": [ + 0, + -36 + ], "icon-image": [ "match", - ["get", "maki"], - ["museum", "lodging", "theatre", "grocery", "restaurant"], - ["concat", "poi_", ["get", "maki"]], + [ + "get", + "maki" + ], + [ + "museum", + "lodging", + "theatre", + "grocery", + "restaurant" + ], + [ + "concat", + "poi_", + [ + "get", + "maki" + ] + ], [ "fitness-centre", "golf", @@ -1879,9 +3501,17 @@ "cemetery" ], "poi_generic_green", - ["bank", "parking", "parking-garage"], + [ + "bank", + "parking", + "parking-garage" + ], "poi_generic_purple", - ["bar", "cafe", "bakery"], + [ + "bar", + "cafe", + "bakery" + ], "poi_generic_orange", [ "alcohol-shop", @@ -1902,7 +3532,10 @@ "monument" ], "poi_generic_teal", - ["hospital", "doctor"], + [ + "hospital", + "doctor" + ], "poi_generic_red", [ "restaurant-pizza", @@ -1914,24 +3547,42 @@ "poi_restaurant", "poi_generic" ], - "text-font": ["Roboto Regular"], - "text-offset": [0, -2], + "text-font": [ + "Roboto Regular" + ], + "text-offset": [ + 0, + -2 + ], "icon-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 0.25, 15, 0.32 ], "text-anchor": "bottom", - "text-field": ["to-string", ["get", "name"]] + "text-field": [ + "to-string", + [ + "get", + "name" + ] + ] }, "paint": { "text-color": [ "match", - ["get", "maki"], + [ + "get", + "maki" + ], [ "museum", "casino", @@ -1944,7 +3595,9 @@ "monument" ], "hsl(186, 78%, 44%)", - ["lodging"], + [ + "lodging" + ], "#df7db1", [ "fitness-centre", @@ -1984,49 +3637,97 @@ "jewelry-store" ], "hsl(213, 40%, 48%)", - ["bank", "parking", "parking-garage"], + [ + "bank", + "parking", + "parking-garage" + ], "#737b9b", - ["hospital", "doctor"], + [ + "hospital", + "doctor" + ], "#a47172", "#67747b" ], "text-halo-color": "#ffffff", "text-halo-width": 1, - "icon-translate": [0, 0], - "text-translate": [0, 0], + "icon-translate": [ + 0, + 0 + ], + "text-translate": [ + 0, + 0 + ], "text-halo-blur": 1 } }, { "id": "poi_label_left", "type": "symbol", - "metadata": {"mapbox:group": "124a9d7a8e5226775d947c592110dfad"}, + "metadata": { + "mapbox:group": "124a9d7a8e5226775d947c592110dfad" + }, "source": "composite", "source-layer": "poi_label", "filter": [ "all", - ["has", "name"], - ["<=", ["get", "filterrank"], ["/", ["zoom"], 3.5]], + [ + "has", + "name" + ], + [ + "<=", + [ + "get", + "filterrank" + ], + [ + "/", + [ + "zoom" + ], + 3.5 + ] + ], [ "!", [ "all", [ "match", - ["get", "maki"], - ["park", "cemetery"], + [ + "get", + "maki" + ], + [ + "park", + "cemetery" + ], true, false ], - ["<=", ["get", "sizerank"], 10] + [ + "<=", + [ + "get", + "sizerank" + ], + 10 + ] ] ] ], "layout": { "text-line-height": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 1, 15, @@ -2034,19 +3735,42 @@ ], "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 13, 15, 14 ], - "icon-offset": [0, -36], + "icon-offset": [ + 0, + -36 + ], "icon-image": [ "match", - ["get", "maki"], - ["museum", "lodging", "theatre", "grocery", "restaurant"], - ["concat", "poi_", ["get", "maki"]], + [ + "get", + "maki" + ], + [ + "museum", + "lodging", + "theatre", + "grocery", + "restaurant" + ], + [ + "concat", + "poi_", + [ + "get", + "maki" + ] + ], [ "fitness-centre", "golf", @@ -2063,9 +3787,17 @@ "cemetery" ], "poi_generic_green", - ["bank", "parking", "parking-garage"], + [ + "bank", + "parking", + "parking-garage" + ], "poi_generic_purple", - ["bar", "cafe", "bakery"], + [ + "bar", + "cafe", + "bakery" + ], "poi_generic_orange", [ "alcohol-shop", @@ -2086,7 +3818,10 @@ "monument" ], "poi_generic_teal", - ["hospital", "doctor"], + [ + "hospital", + "doctor" + ], "poi_generic_red", [ "restaurant-pizza", @@ -2098,33 +3833,64 @@ "poi_restaurant", "poi_generic" ], - "text-font": ["Roboto Regular"], + "text-font": [ + "Roboto Regular" + ], "text-justify": "right", "text-offset": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, - ["literal", [-1.1, -0.7]], + [ + "literal", + [ + -1.1, + -0.7 + ] + ], 15, - ["literal", [-1.1, -0.9]] + [ + "literal", + [ + -1.1, + -0.9 + ] + ] ], "icon-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 0.25, 15, 0.32 ], "text-anchor": "right", - "text-field": ["to-string", ["get", "name"]] + "text-field": [ + "to-string", + [ + "get", + "name" + ] + ] }, "paint": { "text-color": [ "match", - ["get", "maki"], + [ + "get", + "maki" + ], [ "museum", "casino", @@ -2137,7 +3903,9 @@ "monument" ], "hsl(186, 78%, 44%)", - ["lodging"], + [ + "lodging" + ], "#df7db1", [ "fitness-centre", @@ -2177,49 +3945,97 @@ "jewelry-store" ], "hsl(213, 40%, 48%)", - ["bank", "parking", "parking-garage"], + [ + "bank", + "parking", + "parking-garage" + ], "#737b9b", - ["hospital", "doctor"], + [ + "hospital", + "doctor" + ], "#a47172", "#67747b" ], "text-halo-color": "#ffffff", "text-halo-width": 1, - "icon-translate": [0, 0], - "text-translate": [0, 0], + "icon-translate": [ + 0, + 0 + ], + "text-translate": [ + 0, + 0 + ], "text-halo-blur": 1 } }, { "id": "poi_label_right", "type": "symbol", - "metadata": {"mapbox:group": "124a9d7a8e5226775d947c592110dfad"}, + "metadata": { + "mapbox:group": "124a9d7a8e5226775d947c592110dfad" + }, "source": "composite", "source-layer": "poi_label", "filter": [ "all", - ["has", "name"], - ["<=", ["get", "filterrank"], ["/", ["zoom"], 3.5]], + [ + "has", + "name" + ], + [ + "<=", + [ + "get", + "filterrank" + ], + [ + "/", + [ + "zoom" + ], + 3.5 + ] + ], [ "!", [ "all", [ "match", - ["get", "maki"], - ["park", "cemetery"], + [ + "get", + "maki" + ], + [ + "park", + "cemetery" + ], true, false ], - ["<=", ["get", "sizerank"], 10] + [ + "<=", + [ + "get", + "sizerank" + ], + 10 + ] ] ] ], "layout": { "text-line-height": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 1, 15, @@ -2227,19 +4043,42 @@ ], "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 13, 15, 14 ], - "icon-offset": [0, -36], + "icon-offset": [ + 0, + -36 + ], "icon-image": [ "match", - ["get", "maki"], - ["museum", "lodging", "theatre", "grocery", "restaurant"], - ["concat", "poi_", ["get", "maki"]], + [ + "get", + "maki" + ], + [ + "museum", + "lodging", + "theatre", + "grocery", + "restaurant" + ], + [ + "concat", + "poi_", + [ + "get", + "maki" + ] + ], [ "fitness-centre", "golf", @@ -2256,9 +4095,17 @@ "cemetery" ], "poi_generic_green", - ["bank", "parking", "parking-garage"], + [ + "bank", + "parking", + "parking-garage" + ], "poi_generic_purple", - ["bar", "cafe", "bakery"], + [ + "bar", + "cafe", + "bakery" + ], "poi_generic_orange", [ "alcohol-shop", @@ -2279,7 +4126,10 @@ "monument" ], "poi_generic_teal", - ["hospital", "doctor"], + [ + "hospital", + "doctor" + ], "poi_generic_red", [ "restaurant-pizza", @@ -2291,33 +4141,64 @@ "poi_restaurant", "poi_generic" ], - "text-font": ["Roboto Regular"], + "text-font": [ + "Roboto Regular" + ], "text-justify": "left", "text-offset": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, - ["literal", [1.1, -0.7]], + [ + "literal", + [ + 1.1, + -0.7 + ] + ], 15, - ["literal", [1.1, -0.9]] + [ + "literal", + [ + 1.1, + -0.9 + ] + ] ], "icon-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 0.25, 15, 0.32 ], "text-anchor": "left", - "text-field": ["to-string", ["get", "name"]] + "text-field": [ + "to-string", + [ + "get", + "name" + ] + ] }, "paint": { "text-color": [ "match", - ["get", "maki"], + [ + "get", + "maki" + ], [ "museum", "casino", @@ -2330,7 +4211,9 @@ "monument" ], "hsl(186, 78%, 44%)", - ["lodging"], + [ + "lodging" + ], "#df7db1", [ "fitness-centre", @@ -2370,16 +4253,29 @@ "jewelry-store" ], "hsl(213, 40%, 48%)", - ["bank", "parking", "parking-garage"], + [ + "bank", + "parking", + "parking-garage" + ], "#737b9b", - ["hospital", "doctor"], + [ + "hospital", + "doctor" + ], "#a47172", "#67747b" ], "text-halo-color": "#ffffff", "text-halo-width": 1, - "icon-translate": [0, 0], - "text-translate": [0, 0], + "icon-translate": [ + 0, + 0 + ], + "text-translate": [ + 0, + 0 + ], "text-halo-blur": 1 } } @@ -2391,4 +4287,4 @@ "visibility": "public", "protected": false, "draft": false -} \ No newline at end of file +} diff --git a/play-services-maps-core-mapbox/src/main/assets/style-microg-satellite.json b/play-services-maps-core-mapbox/src/main/assets/style-microg-satellite.json index b2a91277e..1a6e2e974 100644 --- a/play-services-maps-core-mapbox/src/main/assets/style-microg-satellite.json +++ b/play-services-maps-core-mapbox/src/main/assets/style-microg-satellite.json @@ -43,11 +43,17 @@ }, "mapbox:uiParadigm": "layers" }, - "center": [12.819420849458652, 50.03325860617235], + "center": [ + 12.819420849458652, + 50.03325860617235 + ], "zoom": 3.315829104862067, "bearing": 0, "pitch": 1.5, - "light": {"intensity": 0.5, "color": "hsl(0, 0%, 0%)"}, + "light": { + "intensity": 0.5, + "color": "hsl(0, 0%, 0%)" + }, "sources": { "mapbox://mapbox.satellite": { "url": "mapbox://mapbox.satellite", @@ -72,22 +78,36 @@ { "id": "forrest", "type": "fill", - "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "metadata": { + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + }, "source": "composite", "source-layer": "landcover", "filter": [ "match", - ["get", "class"], - ["wood", "scrub"], + [ + "get", + "class" + ], + [ + "wood", + "scrub" + ], true, false ], - "layout": {"visibility": "none"}, + "layout": { + "visibility": "none" + }, "paint": { "fill-color": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 9, "hsl(124, 42%, 86%)", 11, @@ -102,41 +122,77 @@ { "id": "national_park", "type": "fill", - "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "metadata": { + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + }, "source": "composite", "source-layer": "landuse_overlay", "filter": [ "match", - ["get", "class"], - ["national_park"], + [ + "get", + "class" + ], + [ + "national_park" + ], true, false ], - "layout": {"visibility": "none"}, - "paint": {"fill-color": "hsl(106, 58%, 85%)"} + "layout": { + "visibility": "none" + }, + "paint": { + "fill-color": "hsl(106, 58%, 85%)" + } }, { "id": "snow", "type": "fill", - "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "metadata": { + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + }, "source": "composite", "source-layer": "landcover", - "filter": ["match", ["get", "class"], ["snow"], true, false], - "layout": {"visibility": "none"}, - "paint": {"fill-color": "#f9fafc"} + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "snow" + ], + true, + false + ], + "layout": { + "visibility": "none" + }, + "paint": { + "fill-color": "#f9fafc" + } }, { "id": "hillshade", "type": "fill", - "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "metadata": { + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + }, "source": "composite", "source-layer": "hillshade", - "layout": {"visibility": "none"}, + "layout": { + "visibility": "none" + }, "paint": { "fill-opacity": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 9, 0.03, 13, @@ -147,87 +203,190 @@ { "id": "park", "type": "fill", - "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "metadata": { + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + }, "source": "composite", "source-layer": "landuse", "filter": [ "match", - ["get", "class"], - ["park", "scrub"], + [ + "get", + "class" + ], + [ + "park", + "scrub" + ], true, false ], - "layout": {"visibility": "none"}, - "paint": {"fill-color": "#c1ecaf"} + "layout": { + "visibility": "none" + }, + "paint": { + "fill-color": "#c1ecaf" + } }, { "id": "pitch", "type": "fill", - "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "metadata": { + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + }, "source": "composite", "source-layer": "landuse", - "filter": ["match", ["get", "class"], ["pitch"], true, false], - "layout": {"visibility": "none"}, - "paint": {"fill-color": "#c8efbb"} + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "pitch" + ], + true, + false + ], + "layout": { + "visibility": "none" + }, + "paint": { + "fill-color": "#c8efbb" + } }, { "id": "landuse", "type": "fill", - "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "metadata": { + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + }, "source": "composite", "source-layer": "landuse", "filter": [ "match", - ["get", "class"], - ["airport", "school", "hospital"], + [ + "get", + "class" + ], + [ + "airport", + "school", + "hospital" + ], true, false ], - "layout": {"visibility": "none"}, - "paint": {"fill-color": "hsl(202, 26%, 94%)"} + "layout": { + "visibility": "none" + }, + "paint": { + "fill-color": "hsl(202, 26%, 94%)" + } }, { "id": "river", "type": "fill", - "metadata": {"mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e"}, + "metadata": { + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + }, "source": "composite", "source-layer": "water", - "layout": {"visibility": "none"}, - "paint": {"fill-color": "hsl(206, 100%, 83%)"} + "layout": { + "visibility": "none" + }, + "paint": { + "fill-color": "hsl(206, 100%, 83%)" + } }, { "id": "path", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", - ["match", ["get", "class"], ["path"], true, false], - ["match", ["get", "type"], ["platform", "steps"], false, true] + [ + "match", + [ + "get", + "class" + ], + [ + "path" + ], + true, + false + ], + [ + "match", + [ + "get", + "type" + ], + [ + "platform", + "steps" + ], + false, + true + ] ], "layout": {}, "paint": { "line-color": "hsl(118, 34%, 66%)", - "line-dasharray": [4, 2], + "line-dasharray": [ + 4, + 2 + ], "line-opacity": 0.3 } }, { "id": "steps", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", - ["match", ["get", "class"], ["path"], true, false], - ["match", ["get", "type"], ["steps"], true, false] + [ + "match", + [ + "get", + "class" + ], + [ + "path" + ], + true, + false + ], + [ + "match", + [ + "get", + "type" + ], + [ + "steps" + ], + true, + false + ] ], "layout": {}, "paint": { "line-color": "hsl(118, 5%, 66%)", - "line-dasharray": [1, 1], + "line-dasharray": [ + 1, + 1 + ], "line-gap-width": 1, "line-opacity": 0.3 } @@ -235,16 +394,33 @@ { "id": "platform", "type": "fill", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", - "filter": ["match", ["get", "type"], ["platform"], true, false], + "filter": [ + "match", + [ + "get", + "type" + ], + [ + "platform" + ], + true, + false + ], "layout": {}, "paint": { "fill-color": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 15, "hsl(2, 20%, 92%)", 16, @@ -252,8 +428,12 @@ ], "fill-outline-color": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 15, "hsl(1, 10%, 76%)", 16, @@ -261,8 +441,12 @@ ], "fill-opacity": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 0, 16, @@ -273,26 +457,52 @@ { "id": "primary_tunnel_border", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", [ "match", - ["get", "class"], - ["primary_link", "primary", "motorway_link"], + [ + "get", + "class" + ], + [ + "primary_link", + "primary", + "motorway_link" + ], true, false ], - ["match", ["get", "structure"], ["tunnel"], true, false] + [ + "match", + [ + "get", + "structure" + ], + [ + "tunnel" + ], + true, + false + ] ], - "layout": {"visibility": "none"}, + "layout": { + "visibility": "none" + }, "paint": { "line-gap-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 7, 0, 8, @@ -312,26 +522,50 @@ { "id": "primary_tunnel", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", [ "match", - ["get", "class"], - ["primary_link", "primary", "motorway_link"], + [ + "get", + "class" + ], + [ + "primary_link", + "primary", + "motorway_link" + ], true, false ], - ["match", ["get", "structure"], ["tunnel"], true, false] + [ + "match", + [ + "get", + "structure" + ], + [ + "tunnel" + ], + true, + false + ] ], "layout": {}, "paint": { "line-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 8, 1, 12, @@ -350,39 +584,82 @@ { "id": "aeroway", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "aeroway", "layout": {}, - "paint": {"line-color": "hsla(0, 0%, 0%, 0.1)", "line-opacity": 0.3} + "paint": { + "line-color": "hsla(0, 0%, 0%, 0.1)", + "line-opacity": 0.3 + } }, { "id": "service_road", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", - "filter": ["match", ["get", "class"], ["service"], true, false], + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "service" + ], + true, + false + ], "layout": {}, - "paint": {"line-color": "hsla(0, 0%, 0%, 0.1)", "line-opacity": 0.3} + "paint": { + "line-color": "hsla(0, 0%, 0%, 0.1)", + "line-opacity": 0.3 + } }, { "id": "pedestrian_border", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", - ["match", ["get", "class"], ["pedestrian"], true, false], - ["has", "name"] + [ + "match", + [ + "get", + "class" + ], + [ + "pedestrian" + ], + true, + false + ], + [ + "has", + "name" + ] ], - "layout": {"visibility": "none"}, + "layout": { + "visibility": "none" + }, "paint": { "line-gap-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 13, 1, 16, @@ -393,8 +670,12 @@ "line-color": "#e3e3e3", "line-opacity": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 12.5, 0, 13.5, @@ -405,16 +686,35 @@ { "id": "street_border", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", - "filter": ["match", ["get", "class"], ["street"], true, false], - "layout": {"visibility": "none"}, + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "street" + ], + true, + false + ], + "layout": { + "visibility": "none" + }, "paint": { "line-gap-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 12, 1, 16, @@ -428,12 +728,17 @@ { "id": "secondary_border", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "match", - ["get", "class"], + [ + "get", + "class" + ], [ "secondary", "secondary_link", @@ -445,12 +750,18 @@ true, false ], - "layout": {"visibility": "none"}, + "layout": { + "visibility": "none" + }, "paint": { "line-gap-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 10, 1, 17, @@ -461,8 +772,12 @@ "line-color": "#e3e3e3", "line-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 16, 1, 20, @@ -473,26 +788,53 @@ { "id": "primary_border", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", [ "match", - ["get", "class"], - ["primary_link", "primary", "motorway_link"], + [ + "get", + "class" + ], + [ + "primary_link", + "primary", + "motorway_link" + ], true, false ], - ["match", ["get", "structure"], ["tunnel"], false, true] - ], - "layout": {"line-cap": "round", "visibility": "none"}, + [ + "match", + [ + "get", + "structure" + ], + [ + "tunnel" + ], + false, + true + ] + ], + "layout": { + "line-cap": "round", + "visibility": "none" + }, "paint": { "line-gap-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 9, 1, 16, @@ -506,16 +848,35 @@ { "id": "motorway_border", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", - "filter": ["match", ["get", "class"], ["motorway"], true, false], - "layout": {"visibility": "none"}, + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "motorway" + ], + true, + false + ], + "layout": { + "visibility": "none" + }, "paint": { "line-gap-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 8, 1, 15.5, @@ -524,44 +885,99 @@ 78 ], "line-color": "#ecd283", - "line-width": ["interpolate", ["linear"], ["zoom"], 8, 1, 15, 2] + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 8, + 1, + 15, + 2 + ] } }, { "id": "railway", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "match", - ["get", "class"], - ["major_rail", "minor_rail", "service_rail"], + [ + "get", + "class" + ], + [ + "major_rail", + "minor_rail", + "service_rail" + ], true, false ], "layout": {}, - "paint": {"line-color": "hsl(220, 4%, 85%)", "line-opacity": 0.3} + "paint": { + "line-color": "hsl(220, 4%, 85%)", + "line-opacity": 0.3 + } }, { "id": "pedestrian", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", - ["match", ["get", "class"], ["pedestrian"], true, false], - ["has", "name"], - ["match", ["get", "type"], ["platform"], false, true] + [ + "match", + [ + "get", + "class" + ], + [ + "pedestrian" + ], + true, + false + ], + [ + "has", + "name" + ], + [ + "match", + [ + "get", + "type" + ], + [ + "platform" + ], + false, + true + ] ], "layout": {}, "paint": { "line-color": "hsl(0, 0%, 100%)", "line-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 13, 1, 16, @@ -571,8 +987,12 @@ ], "line-opacity": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 12.5, 0, 13.5, @@ -583,17 +1003,34 @@ { "id": "street", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", - "filter": ["match", ["get", "class"], ["street"], true, false], + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "street" + ], + true, + false + ], "layout": {}, "paint": { "line-color": "hsl(0, 0%, 100%)", "line-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 12, 1, 16, @@ -607,12 +1044,17 @@ { "id": "secondary", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "match", - ["get", "class"], + [ + "get", + "class" + ], [ "secondary", "secondary_link", @@ -629,8 +1071,12 @@ "line-color": "hsl(0, 0%, 100%)", "line-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 10, 1, 17, @@ -644,33 +1090,61 @@ { "id": "primary", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", [ "match", - ["get", "class"], - ["primary_link", "primary", "motorway_link"], + [ + "get", + "class" + ], + [ + "primary_link", + "primary", + "motorway_link" + ], true, false ], - ["match", ["get", "structure"], ["tunnel"], false, true] + [ + "match", + [ + "get", + "structure" + ], + [ + "tunnel" + ], + false, + true + ] ], - "layout": {"line-cap": "round"}, + "layout": { + "line-cap": "round" + }, "paint": { "line-color": [ "step", - ["zoom"], + [ + "zoom" + ], "hsl(50, 100%, 75%)", 7, "hsl(50, 100%, 85%)" ], "line-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 9, 1, 16, @@ -684,17 +1158,34 @@ { "id": "motorway", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", - "filter": ["match", ["get", "class"], ["motorway"], true, false], + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "motorway" + ], + true, + false + ], "layout": {}, "paint": { "line-color": "hsl(47, 100%, 82%)", "line-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 8, 1, 15.5, @@ -708,26 +1199,52 @@ { "id": "primary_bridge_border", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", [ "match", - ["get", "class"], - ["primary_link", "primary", "motorway_link"], + [ + "get", + "class" + ], + [ + "primary_link", + "primary", + "motorway_link" + ], true, false ], - ["match", ["get", "structure"], ["bridge"], true, false] + [ + "match", + [ + "get", + "structure" + ], + [ + "bridge" + ], + true, + false + ] ], - "layout": {"visibility": "none"}, + "layout": { + "visibility": "none" + }, "paint": { "line-gap-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 9, 1, 16, @@ -741,33 +1258,61 @@ { "id": "primary_bridge", "type": "line", - "metadata": {"mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990"}, + "metadata": { + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + }, "source": "composite", "source-layer": "road", "filter": [ "all", [ "match", - ["get", "class"], - ["primary_link", "primary", "motorway_link"], + [ + "get", + "class" + ], + [ + "primary_link", + "primary", + "motorway_link" + ], true, false ], - ["match", ["get", "structure"], ["bridge"], true, false] + [ + "match", + [ + "get", + "structure" + ], + [ + "bridge" + ], + true, + false + ] ], - "layout": {"visibility": "none"}, + "layout": { + "visibility": "none" + }, "paint": { "line-color": [ "step", - ["zoom"], + [ + "zoom" + ], "hsl(50, 100%, 75%)", 7, "hsl(50, 100%, 85%)" ], "line-width": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 9, 1, 16, @@ -780,15 +1325,33 @@ { "id": "building", "type": "fill", - "metadata": {"mapbox:group": "29bb589e8d1b9b402583363648b70302"}, + "metadata": { + "mapbox:group": "29bb589e8d1b9b402583363648b70302" + }, "source": "composite", "source-layer": "building", - "filter": ["match", ["get", "type"], ["roof"], false, true], - "layout": {"visibility": "none"}, + "filter": [ + "match", + [ + "get", + "type" + ], + [ + "roof" + ], + false, + true + ], + "layout": { + "visibility": "none" + }, "paint": { "fill-color": [ "match", - ["get", "type"], + [ + "get", + "type" + ], [ "store", "retail", @@ -805,8 +1368,12 @@ ], "fill-opacity": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 15, 0, 17, @@ -817,15 +1384,33 @@ { "id": "building_border", "type": "line", - "metadata": {"mapbox:group": "29bb589e8d1b9b402583363648b70302"}, + "metadata": { + "mapbox:group": "29bb589e8d1b9b402583363648b70302" + }, "source": "composite", "source-layer": "building", - "filter": ["match", ["get", "type"], ["roof"], false, true], - "layout": {"visibility": "none"}, + "filter": [ + "match", + [ + "get", + "type" + ], + [ + "roof" + ], + false, + true + ], + "layout": { + "visibility": "none" + }, "paint": { "line-color": [ "match", - ["get", "type"], + [ + "get", + "type" + ], [ "store", "retail", @@ -842,8 +1427,12 @@ ], "line-opacity": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 15, 0, 17, @@ -854,20 +1443,42 @@ { "id": "building_3d", "type": "fill-extrusion", - "metadata": {"mapbox:group": "29bb589e8d1b9b402583363648b70302"}, + "metadata": { + "mapbox:group": "29bb589e8d1b9b402583363648b70302" + }, "source": "composite", "source-layer": "building", - "filter": ["match", ["get", "extrude"], ["true"], true, false], - "layout": {"visibility": "none"}, + "filter": [ + "match", + [ + "get", + "extrude" + ], + [ + "true" + ], + true, + false + ], + "layout": { + "visibility": "none" + }, "paint": { "fill-extrusion-height": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 15, 0, 16, - ["get", "height"] + [ + "get", + "height" + ] ], "fill-extrusion-color": "#ededed", "fill-extrusion-opacity": 0.3 @@ -876,19 +1487,50 @@ { "id": "admin_0", "type": "line", - "metadata": {"mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa"}, + "metadata": { + "mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa" + }, "source": "composite", "source-layer": "admin", "filter": [ "all", - ["match", ["get", "maritime"], ["false"], true, false], - ["match", ["get", "admin_level"], [0], true, false] + [ + "match", + [ + "get", + "maritime" + ], + [ + "false" + ], + true, + false + ], + [ + "match", + [ + "get", + "admin_level" + ], + [ + 0 + ], + true, + false + ] ], "layout": {}, "paint": { "line-color": [ "case", - ["==", ["get", "disputed"], true], + [ + "==", + [ + "get", + "disputed" + ], + true + ], "hsl(0, 24%, 85%)", "hsl(200, 1%, 85%)" ] @@ -897,37 +1539,93 @@ { "id": "admin_1", "type": "line", - "metadata": {"mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa"}, + "metadata": { + "mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa" + }, "source": "composite", "source-layer": "admin", "filter": [ "all", - ["match", ["get", "maritime"], ["false"], true, false], - ["match", ["get", "admin_level"], [1], true, false] - ], - "layout": {}, - "paint": { - "line-color": [ - "case", - ["==", ["get", "disputed"], true], - "hsl(0, 24%, 85%)", - "hsl(200, 1%, 85%)" - ], - "line-dasharray": [1, 1] - } + [ + "match", + [ + "get", + "maritime" + ], + [ + "false" + ], + true, + false + ], + [ + "match", + [ + "get", + "admin_level" + ], + [ + 1 + ], + true, + false + ] + ], + "layout": {}, + "paint": { + "line-color": [ + "case", + [ + "==", + [ + "get", + "disputed" + ], + true + ], + "hsl(0, 24%, 85%)", + "hsl(200, 1%, 85%)" + ], + "line-dasharray": [ + 1, + 1 + ] + } }, { "id": "river_name", "type": "symbol", - "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "metadata": { + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + }, "source": "composite", "source-layer": "natural_label", - "filter": ["match", ["get", "class"], ["river"], true, false], + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "river" + ], + true, + false + ], "layout": { - "text-field": ["to-string", ["get", "name"]], + "text-field": [ + "to-string", + [ + "get", + "name" + ] + ], "symbol-placement": "line", "symbol-spacing": 500, - "text-font": ["Roboto Regular", "Arial Unicode MS Regular"] + "text-font": [ + "Roboto Regular", + "Arial Unicode MS Regular" + ] }, "paint": { "text-color": "#5083c1", @@ -938,17 +1636,38 @@ { "id": "city_label_right", "type": "symbol", - "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "metadata": { + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + }, "source": "composite", "source-layer": "place_label", "maxzoom": 8, "filter": [ "all", - ["<=", ["get", "filterrank"], ["/", ["zoom"], 4]], + [ + "<=", + [ + "get", + "filterrank" + ], + [ + "/", + [ + "zoom" + ], + 4 + ] + ], [ "match", - ["get", "class"], - ["settlement", "settlement_subdivision"], + [ + "get", + "class" + ], + [ + "settlement", + "settlement_subdivision" + ], true, false ] @@ -957,50 +1676,147 @@ "text-optional": true, "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 0, - ["-", 14, ["max", 0, ["-", ["get", "symbolrank"], 8]]], + [ + "-", + 14, + [ + "max", + 0, + [ + "-", + [ + "get", + "symbolrank" + ], + 8 + ] + ] + ], 22, - ["-", 20, ["/", ["get", "symbolrank"], 4]] + [ + "-", + 20, + [ + "/", + [ + "get", + "symbolrank" + ], + 4 + ] + ] ], "icon-image": [ "match", - ["get", "capital"], - [0, 2], + [ + "get", + "capital" + ], + [ + 0, + 2 + ], "capital", "city" ], "text-font": [ "step", - ["get", "symbolrank"], - ["literal", ["Roboto Medium", "Arial Unicode MS Regular"]], + [ + "get", + "symbolrank" + ], + [ + "literal", + [ + "Roboto Medium", + "Arial Unicode MS Regular" + ] + ], 10, - ["literal", ["Roboto Regular", "Arial Unicode MS Regular"]] + [ + "literal", + [ + "Roboto Regular", + "Arial Unicode MS Regular" + ] + ] ], "text-justify": "left", - "text-offset": [0.5, 0.1], - "icon-size": ["/", 5, ["get", "symbolrank"]], + "text-offset": [ + 0.5, + 0.1 + ], + "icon-size": [ + "/", + 5, + [ + "get", + "symbolrank" + ] + ], "text-anchor": "left", - "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]] + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] }, "paint": { "text-color": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 0, [ "concat", "hsl(213, 11%, ", - ["-", 100, ["*", ["get", "symbolrank"], 2]], + [ + "-", + 100, + [ + "*", + [ + "get", + "symbolrank" + ], + 2 + ] + ], "%)" ], 22, [ "concat", "hsl(213, 11%, ", - ["+", ["-", 100, ["get", "symbolrank"]], 5], + [ + "+", + [ + "-", + 100, + [ + "get", + "symbolrank" + ] + ], + 5 + ], "%)" ] ], @@ -1013,17 +1829,38 @@ { "id": "city_label_left", "type": "symbol", - "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "metadata": { + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + }, "source": "composite", "source-layer": "place_label", "maxzoom": 8, "filter": [ "all", - ["<=", ["get", "filterrank"], ["/", ["zoom"], 4]], + [ + "<=", + [ + "get", + "filterrank" + ], + [ + "/", + [ + "zoom" + ], + 4 + ] + ], [ "match", - ["get", "class"], - ["settlement", "settlement_subdivision"], + [ + "get", + "class" + ], + [ + "settlement", + "settlement_subdivision" + ], true, false ] @@ -1031,50 +1868,147 @@ "layout": { "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 0, - ["-", 14, ["max", 0, ["-", ["get", "symbolrank"], 8]]], + [ + "-", + 14, + [ + "max", + 0, + [ + "-", + [ + "get", + "symbolrank" + ], + 8 + ] + ] + ], 22, - ["-", 20, ["/", ["get", "symbolrank"], 4]] + [ + "-", + 20, + [ + "/", + [ + "get", + "symbolrank" + ], + 4 + ] + ] ], "icon-image": [ "match", - ["get", "capital"], - [0, 2], + [ + "get", + "capital" + ], + [ + 0, + 2 + ], "capital", "city" ], "text-font": [ "step", - ["get", "symbolrank"], - ["literal", ["Roboto Medium", "Arial Unicode MS Regular"]], + [ + "get", + "symbolrank" + ], + [ + "literal", + [ + "Roboto Medium", + "Arial Unicode MS Regular" + ] + ], 10, - ["literal", ["Roboto Regular", "Arial Unicode MS Regular"]] + [ + "literal", + [ + "Roboto Regular", + "Arial Unicode MS Regular" + ] + ] ], "text-justify": "right", - "text-offset": [-0.5, 0.1], - "icon-size": ["/", 5, ["get", "symbolrank"]], + "text-offset": [ + -0.5, + 0.1 + ], + "icon-size": [ + "/", + 5, + [ + "get", + "symbolrank" + ] + ], "text-anchor": "right", - "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]] + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] }, "paint": { "text-color": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 0, [ "concat", "hsl(213, 11%, ", - ["-", 100, ["*", ["get", "symbolrank"], 2]], + [ + "-", + 100, + [ + "*", + [ + "get", + "symbolrank" + ], + 2 + ] + ], "%)" ], 22, [ "concat", "hsl(213, 11%, ", - ["+", ["-", 100, ["get", "symbolrank"]], 5], + [ + "+", + [ + "-", + 100, + [ + "get", + "symbolrank" + ] + ], + 5 + ], "%)" ] ], @@ -1087,17 +2021,38 @@ { "id": "city_label_below", "type": "symbol", - "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "metadata": { + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + }, "source": "composite", "source-layer": "place_label", "maxzoom": 8, "filter": [ "all", - ["<=", ["get", "filterrank"], ["/", ["zoom"], 4]], + [ + "<=", + [ + "get", + "filterrank" + ], + [ + "/", + [ + "zoom" + ], + 4 + ] + ], [ "match", - ["get", "class"], - ["settlement", "settlement_subdivision"], + [ + "get", + "class" + ], + [ + "settlement", + "settlement_subdivision" + ], true, false ] @@ -1105,49 +2060,146 @@ "layout": { "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 0, - ["-", 14, ["max", 0, ["-", ["get", "symbolrank"], 8]]], + [ + "-", + 14, + [ + "max", + 0, + [ + "-", + [ + "get", + "symbolrank" + ], + 8 + ] + ] + ], 22, - ["-", 20, ["/", ["get", "symbolrank"], 4]] + [ + "-", + 20, + [ + "/", + [ + "get", + "symbolrank" + ], + 4 + ] + ] ], "icon-image": [ "match", - ["get", "capital"], - [0, 2], + [ + "get", + "capital" + ], + [ + 0, + 2 + ], "capital", "city" ], "text-font": [ "step", - ["get", "symbolrank"], - ["literal", ["Roboto Medium", "Arial Unicode MS Regular"]], + [ + "get", + "symbolrank" + ], + [ + "literal", + [ + "Roboto Medium", + "Arial Unicode MS Regular" + ] + ], 10, - ["literal", ["Roboto Regular", "Arial Unicode MS Regular"]] + [ + "literal", + [ + "Roboto Regular", + "Arial Unicode MS Regular" + ] + ] + ], + "text-offset": [ + 0, + 0.4 + ], + "icon-size": [ + "/", + 5, + [ + "get", + "symbolrank" + ] ], - "text-offset": [0, 0.4], - "icon-size": ["/", 5, ["get", "symbolrank"]], "text-anchor": "top", - "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]] + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] }, "paint": { "text-color": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 0, [ "concat", "hsl(213, 11%, ", - ["-", 100, ["*", ["get", "symbolrank"], 2]], + [ + "-", + 100, + [ + "*", + [ + "get", + "symbolrank" + ], + 2 + ] + ], "%)" ], 22, [ "concat", "hsl(213, 11%, ", - ["+", ["-", 100, ["get", "symbolrank"]], 5], + [ + "+", + [ + "-", + 100, + [ + "get", + "symbolrank" + ] + ], + 5 + ], "%)" ] ], @@ -1160,16 +2212,37 @@ { "id": "city_name", "type": "symbol", - "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "metadata": { + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + }, "source": "composite", "source-layer": "place_label", "filter": [ "all", - ["<=", ["get", "filterrank"], ["/", ["zoom"], 4]], + [ + "<=", + [ + "get", + "filterrank" + ], + [ + "/", + [ + "zoom" + ], + 4 + ] + ], [ "match", - ["get", "class"], - ["settlement", "settlement_subdivision"], + [ + "get", + "class" + ], + [ + "settlement", + "settlement_subdivision" + ], true, false ] @@ -1177,48 +2250,154 @@ "layout": { "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 0, - ["-", 14, ["max", 0, ["-", ["get", "symbolrank"], 8]]], + [ + "-", + 14, + [ + "max", + 0, + [ + "-", + [ + "get", + "symbolrank" + ], + 8 + ] + ] + ], 22, - ["-", 20, ["/", ["get", "symbolrank"], 4]] + [ + "-", + 20, + [ + "/", + [ + "get", + "symbolrank" + ], + 4 + ] + ] ], "icon-image": [ "step", - ["zoom"], - ["match", ["get", "capital"], [0, 2], "capital", "city"], + [ + "zoom" + ], + [ + "match", + [ + "get", + "capital" + ], + [ + 0, + 2 + ], + "capital", + "city" + ], + 8, + "" + ], + "text-transform": [ + "step", + [ + "get", + "symbolrank" + ], + "none", + 15, + "uppercase" + ], + "text-font": [ + "step", + [ + "get", + "symbolrank" + ], + [ + "literal", + [ + "Roboto Medium", + "Arial Unicode MS Regular" + ] + ], + 10, + [ + "literal", + [ + "Roboto Regular", + "Arial Unicode MS Regular" + ] + ] + ], + "text-offset": [ + "step", + [ + "zoom" + ], + [ + "literal", + [ + 0, + -0.2 + ] + ], 8, - "" - ], - "text-transform": [ - "step", - ["get", "symbolrank"], - "none", - 15, - "uppercase" + [ + "literal", + [ + 0, + 0 + ] + ] ], - "text-font": [ - "step", - ["get", "symbolrank"], - ["literal", ["Roboto Medium", "Arial Unicode MS Regular"]], - 10, - ["literal", ["Roboto Regular", "Arial Unicode MS Regular"]] + "icon-size": [ + "/", + 5, + [ + "get", + "symbolrank" + ] ], - "text-offset": [ + "text-anchor": [ "step", - ["zoom"], - ["literal", [0, -0.2]], + [ + "zoom" + ], + "bottom", 8, - ["literal", [0, 0]] + "center" + ], + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] ], - "icon-size": ["/", 5, ["get", "symbolrank"]], - "text-anchor": ["step", ["zoom"], "bottom", 8, "center"], - "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]], "text-letter-spacing": [ "interpolate", - ["linear"], - ["get", "symbolrank"], + [ + "linear" + ], + [ + "get", + "symbolrank" + ], 0, 0, 8, @@ -1232,20 +2411,46 @@ "paint": { "text-color": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 0, [ "concat", "hsl(213, 11%, ", - ["-", 100, ["*", ["get", "symbolrank"], 2]], + [ + "-", + 100, + [ + "*", + [ + "get", + "symbolrank" + ], + 2 + ] + ], "%)" ], 22, [ "concat", "hsl(213, 11%, ", - ["+", ["-", 100, ["get", "symbolrank"]], 5], + [ + "+", + [ + "-", + 100, + [ + "get", + "symbolrank" + ] + ], + 5 + ], "%)" ] ], @@ -1258,18 +2463,51 @@ { "id": "park_name", "type": "symbol", - "metadata": {"mapbox:group": "7b44201d7f1682d99f7140188aff23ce"}, + "metadata": { + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + }, "source": "composite", "source-layer": "poi_label", "filter": [ "all", - ["has", "name"], - ["match", ["get", "maki"], ["park", "cemetery"], true, false], - ["<=", ["get", "sizerank"], 10] + [ + "has", + "name" + ], + [ + "match", + [ + "get", + "maki" + ], + [ + "park", + "cemetery" + ], + true, + false + ], + [ + "<=", + [ + "get", + "sizerank" + ], + 10 + ] ], "layout": { - "text-field": ["to-string", ["get", "name"]], - "text-font": ["Roboto Regular", "Arial Unicode MS Regular"], + "text-field": [ + "to-string", + [ + "get", + "name" + ] + ], + "text-font": [ + "Roboto Regular", + "Arial Unicode MS Regular" + ], "text-size": 14 }, "paint": { @@ -1282,17 +2520,36 @@ { "id": "road-number-shield", "type": "symbol", - "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "metadata": { + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + }, "source": "composite", "source-layer": "road", - "filter": ["all", ["has", "ref"], ["<=", ["get", "reflen"], 6]], + "filter": [ + "all", + [ + "has", + "ref" + ], + [ + "<=", + [ + "get", + "reflen" + ], + 6 + ] + ], "layout": { "text-size": 9, "icon-image": [ "case", [ "match", - ["get", "shield"], + [ + "get", + "shield" + ], [ "de-motorway", "rectangle-green", @@ -1308,43 +2565,95 @@ [ "concat", "shield_", - ["get", "shield"], + [ + "get", + "shield" + ], "_", - ["get", "reflen"] + [ + "get", + "reflen" + ] ], [ "match", - ["get", "shield_text_color"], - ["white"], + [ + "get", + "shield_text_color" + ], + [ + "white" + ], true, false ], - ["concat", "shield_rectangle-blue_", ["get", "reflen"]], - ["concat", "shield_rectangle-white_", ["get", "reflen"]] + [ + "concat", + "shield_rectangle-blue_", + [ + "get", + "reflen" + ] + ], + [ + "concat", + "shield_rectangle-white_", + [ + "get", + "reflen" + ] + ] ], "icon-rotation-alignment": "viewport", "text-font": [ "match", - ["get", "shield_text_color"], - ["white"], + [ + "get", + "shield_text_color" + ], + [ + "white" + ], [ "literal", - ["DIN Offc Pro Bold", "Arial Unicode MS Regular"] + [ + "DIN Offc Pro Bold", + "Arial Unicode MS Regular" + ] + ], + [ + "black" ], - ["black"], [ "literal", - ["DIN Offc Pro Medium", "Arial Unicode MS Regular"] + [ + "DIN Offc Pro Medium", + "Arial Unicode MS Regular" + ] ], [ "literal", - ["DIN Offc Pro Bold", "Arial Unicode MS Regular"] + [ + "DIN Offc Pro Bold", + "Arial Unicode MS Regular" + ] ] ], - "symbol-placement": ["step", ["zoom"], "point", 11, "line"], + "symbol-placement": [ + "step", + [ + "zoom" + ], + "point", + 11, + "line" + ], "text-rotation-alignment": "viewport", "icon-size": 0.75, - "text-field": ["get", "ref"], + "text-field": [ + "get", + "ref" + ], "text-letter-spacing": 0.05 }, "paint": { @@ -1352,40 +2661,65 @@ "case", [ "match", - ["get", "shield_text_color"], - ["white"], + [ + "get", + "shield_text_color" + ], + [ + "white" + ], true, false ], "#ffffff", [ "match", - ["get", "shield_text_color"], - ["black"], + [ + "get", + "shield_text_color" + ], + [ + "black" + ], true, false ], "hsl(0, 0%, 7%)", [ "match", - ["get", "shield_text_color"], - ["yellow"], + [ + "get", + "shield_text_color" + ], + [ + "yellow" + ], true, false ], "hsl(50, 100%, 70%)", [ "match", - ["get", "shield_text_color"], - ["orange"], + [ + "get", + "shield_text_color" + ], + [ + "orange" + ], true, false ], "hsl(25, 100%, 75%)", [ "match", - ["get", "shield_text_color"], - ["blue"], + [ + "get", + "shield_text_color" + ], + [ + "blue" + ], true, false ], @@ -1397,37 +2731,83 @@ { "id": "country_name", "type": "symbol", - "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "metadata": { + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + }, "source": "composite", "source-layer": "place_label", - "filter": ["match", ["get", "class"], ["country"], true, false], + "filter": [ + "match", + [ + "get", + "class" + ], + [ + "country" + ], + true, + false + ], "layout": { "text-letter-spacing": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 1, 0, 3, 0.15 ], - "text-font": ["Roboto Medium", "Arial Unicode MS Regular"], + "text-font": [ + "Roboto Medium", + "Arial Unicode MS Regular" + ], "text-size": [ "interpolate", - ["exponential", 1.2], - ["zoom"], + [ + "exponential", + 1.2 + ], + [ + "zoom" + ], 1, 12, 7, - ["/", 100, ["get", "symbolrank"]] + [ + "/", + 100, + [ + "get", + "symbolrank" + ] + ] ], - "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]] + "text-field": [ + "coalesce", + [ + "get", + "name_en" + ], + [ + "get", + "name" + ] + ] }, "paint": { "text-opacity": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 6, 1, 7, @@ -1442,24 +2822,61 @@ { "id": "pedestrian_name", "type": "symbol", - "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "metadata": { + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + }, "source": "composite", "source-layer": "road", "minzoom": 16, "filter": [ "all", - ["has", "name"], - ["match", ["get", "class"], ["pedestrian"], true, false], - ["match", ["get", "type"], ["platform"], false, true] + [ + "has", + "name" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "pedestrian" + ], + true, + false + ], + [ + "match", + [ + "get", + "type" + ], + [ + "platform" + ], + false, + true + ] ], "layout": { - "text-field": ["get", "name"], + "text-field": [ + "get", + "name" + ], "symbol-placement": "line", - "text-font": ["Roboto Regular", "Arial Unicode MS Regular"], + "text-font": [ + "Roboto Regular", + "Arial Unicode MS Regular" + ], "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 17, 10, 22, @@ -1477,22 +2894,48 @@ { "id": "street_name", "type": "symbol", - "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "metadata": { + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + }, "source": "composite", "source-layer": "road", "filter": [ "all", - ["has", "name"], - ["match", ["get", "class"], ["street"], true, false] + [ + "has", + "name" + ], + [ + "match", + [ + "get", + "class" + ], + [ + "street" + ], + true, + false + ] ], "layout": { - "text-field": ["get", "name"], + "text-field": [ + "get", + "name" + ], "symbol-placement": "line", - "text-font": ["Roboto Regular", "Arial Unicode MS Regular"], + "text-font": [ + "Roboto Regular", + "Arial Unicode MS Regular" + ], "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 8, 6, 16, @@ -1510,15 +2953,23 @@ { "id": "secondary_name", "type": "symbol", - "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "metadata": { + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + }, "source": "composite", "source-layer": "road", "filter": [ "all", - ["has", "name"], + [ + "has", + "name" + ], [ "match", - ["get", "class"], + [ + "get", + "class" + ], [ "secondary", "secondary_link", @@ -1532,13 +2983,23 @@ ] ], "layout": { - "text-field": ["get", "name"], + "text-field": [ + "get", + "name" + ], "symbol-placement": "line", - "text-font": ["Roboto Regular", "Arial Unicode MS Regular"], + "text-font": [ + "Roboto Regular", + "Arial Unicode MS Regular" + ], "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 8, 8, 16, @@ -1557,28 +3018,49 @@ { "id": "primary_name", "type": "symbol", - "metadata": {"mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312"}, + "metadata": { + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + }, "source": "composite", "source-layer": "road", "filter": [ "all", - ["has", "name"], + [ + "has", + "name" + ], [ "match", - ["get", "class"], - ["primary", "primary_link"], + [ + "get", + "class" + ], + [ + "primary", + "primary_link" + ], true, false ] ], "layout": { - "text-field": ["get", "name"], + "text-field": [ + "get", + "name" + ], "symbol-placement": "line", - "text-font": ["Roboto Regular", "Arial Unicode MS Regular"], + "text-font": [ + "Roboto Regular", + "Arial Unicode MS Regular" + ], "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 8, 10, 18, @@ -1597,25 +3079,56 @@ { "id": "poi_label_below", "type": "symbol", - "metadata": {"mapbox:group": "124a9d7a8e5226775d947c592110dfad"}, + "metadata": { + "mapbox:group": "124a9d7a8e5226775d947c592110dfad" + }, "source": "composite", "source-layer": "poi_label", "filter": [ "all", - ["has", "name"], - ["<=", ["get", "filterrank"], ["/", ["zoom"], 4]], + [ + "has", + "name" + ], + [ + "<=", + [ + "get", + "filterrank" + ], + [ + "/", + [ + "zoom" + ], + 4 + ] + ], [ "!", [ "all", [ "match", - ["get", "maki"], - ["park", "cemetery"], + [ + "get", + "maki" + ], + [ + "park", + "cemetery" + ], true, false ], - ["<=", ["get", "sizerank"], 10] + [ + "<=", + [ + "get", + "sizerank" + ], + 10 + ] ] ] ], @@ -1623,8 +3136,12 @@ "text-optional": true, "text-line-height": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 1, 15, @@ -1632,19 +3149,42 @@ ], "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 13, 15, 14 ], - "icon-offset": [0, -36], + "icon-offset": [ + 0, + -36 + ], "icon-image": [ "match", - ["get", "maki"], - ["museum", "lodging", "theatre", "grocery", "restaurant"], - ["concat", "poi_", ["get", "maki"]], + [ + "get", + "maki" + ], + [ + "museum", + "lodging", + "theatre", + "grocery", + "restaurant" + ], + [ + "concat", + "poi_", + [ + "get", + "maki" + ] + ], [ "fitness-centre", "golf", @@ -1661,9 +3201,17 @@ "cemetery" ], "poi_generic_green", - ["bank", "parking", "parking-garage"], + [ + "bank", + "parking", + "parking-garage" + ], "poi_generic_purple", - ["bar", "cafe", "bakery"], + [ + "bar", + "cafe", + "bakery" + ], "poi_generic_orange", [ "alcohol-shop", @@ -1684,7 +3232,10 @@ "monument" ], "poi_generic_teal", - ["hospital", "doctor"], + [ + "hospital", + "doctor" + ], "poi_generic_red", [ "restaurant-pizza", @@ -1696,24 +3247,43 @@ "poi_restaurant", "poi_generic" ], - "text-font": ["Roboto Regular", "Arial Unicode MS Regular"], - "text-offset": [0, 0.5], + "text-font": [ + "Roboto Regular", + "Arial Unicode MS Regular" + ], + "text-offset": [ + 0, + 0.5 + ], "icon-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 0.25, 15, 0.32 ], "text-anchor": "top", - "text-field": ["to-string", ["get", "name"]] + "text-field": [ + "to-string", + [ + "get", + "name" + ] + ] }, "paint": { "text-color": [ "match", - ["get", "maki"], + [ + "get", + "maki" + ], [ "museum", "casino", @@ -1726,7 +3296,9 @@ "monument" ], "hsl(186, 78%, 65%)", - ["lodging"], + [ + "lodging" + ], "#df7db1", [ "fitness-centre", @@ -1766,41 +3338,85 @@ "jewelry-store" ], "hsl(213, 40%, 65%)", - ["bank", "parking", "parking-garage"], + [ + "bank", + "parking", + "parking-garage" + ], "hsl(228, 17%, 65%)", - ["hospital", "doctor"], + [ + "hospital", + "doctor" + ], "hsl(359, 22%, 65%)", "hsl(201, 9%, 80%)" ], "text-halo-color": "hsl(0, 1%, 0%)", "text-halo-width": 1, - "icon-translate": [0, 0], - "text-translate": [0, 0], + "icon-translate": [ + 0, + 0 + ], + "text-translate": [ + 0, + 0 + ], "text-halo-blur": 1 } }, { "id": "poi_label_above", "type": "symbol", - "metadata": {"mapbox:group": "124a9d7a8e5226775d947c592110dfad"}, + "metadata": { + "mapbox:group": "124a9d7a8e5226775d947c592110dfad" + }, "source": "composite", "source-layer": "poi_label", "filter": [ "all", - ["has", "name"], - ["<=", ["get", "filterrank"], ["/", ["zoom"], 4]], + [ + "has", + "name" + ], + [ + "<=", + [ + "get", + "filterrank" + ], + [ + "/", + [ + "zoom" + ], + 4 + ] + ], [ "!", [ "all", [ "match", - ["get", "maki"], - ["park", "cemetery"], + [ + "get", + "maki" + ], + [ + "park", + "cemetery" + ], true, false ], - ["<=", ["get", "sizerank"], 10] + [ + "<=", + [ + "get", + "sizerank" + ], + 10 + ] ] ] ], @@ -1808,8 +3424,12 @@ "text-optional": true, "text-line-height": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 1, 15, @@ -1817,19 +3437,42 @@ ], "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 13, 15, 14 ], - "icon-offset": [0, -36], + "icon-offset": [ + 0, + -36 + ], "icon-image": [ "match", - ["get", "maki"], - ["museum", "lodging", "theatre", "grocery", "restaurant"], - ["concat", "poi_", ["get", "maki"]], + [ + "get", + "maki" + ], + [ + "museum", + "lodging", + "theatre", + "grocery", + "restaurant" + ], + [ + "concat", + "poi_", + [ + "get", + "maki" + ] + ], [ "fitness-centre", "golf", @@ -1846,9 +3489,17 @@ "cemetery" ], "poi_generic_green", - ["bank", "parking", "parking-garage"], + [ + "bank", + "parking", + "parking-garage" + ], "poi_generic_purple", - ["bar", "cafe", "bakery"], + [ + "bar", + "cafe", + "bakery" + ], "poi_generic_orange", [ "alcohol-shop", @@ -1869,7 +3520,10 @@ "monument" ], "poi_generic_teal", - ["hospital", "doctor"], + [ + "hospital", + "doctor" + ], "poi_generic_red", [ "restaurant-pizza", @@ -1881,24 +3535,43 @@ "poi_restaurant", "poi_generic" ], - "text-font": ["Roboto Regular", "Arial Unicode MS Regular"], - "text-offset": [0, -2], + "text-font": [ + "Roboto Regular", + "Arial Unicode MS Regular" + ], + "text-offset": [ + 0, + -2 + ], "icon-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 0.25, 15, 0.32 ], "text-anchor": "bottom", - "text-field": ["to-string", ["get", "name"]] + "text-field": [ + "to-string", + [ + "get", + "name" + ] + ] }, "paint": { "text-color": [ "match", - ["get", "maki"], + [ + "get", + "maki" + ], [ "museum", "casino", @@ -1911,7 +3584,9 @@ "monument" ], "hsl(186, 78%, 65%)", - ["lodging"], + [ + "lodging" + ], "#df7db1", [ "fitness-centre", @@ -1951,49 +3626,97 @@ "jewelry-store" ], "hsl(213, 40%, 65%)", - ["bank", "parking", "parking-garage"], + [ + "bank", + "parking", + "parking-garage" + ], "hsl(228, 17%, 65%)", - ["hospital", "doctor"], + [ + "hospital", + "doctor" + ], "hsl(359, 22%, 65%)", "hsl(201, 9%, 80%)" ], "text-halo-color": "hsl(0, 1%, 0%)", "text-halo-width": 1, - "icon-translate": [0, 0], - "text-translate": [0, 0], + "icon-translate": [ + 0, + 0 + ], + "text-translate": [ + 0, + 0 + ], "text-halo-blur": 1 } }, { "id": "poi_label_left", "type": "symbol", - "metadata": {"mapbox:group": "124a9d7a8e5226775d947c592110dfad"}, + "metadata": { + "mapbox:group": "124a9d7a8e5226775d947c592110dfad" + }, "source": "composite", "source-layer": "poi_label", "filter": [ "all", - ["has", "name"], - ["<=", ["get", "filterrank"], ["/", ["zoom"], 4]], + [ + "has", + "name" + ], + [ + "<=", + [ + "get", + "filterrank" + ], + [ + "/", + [ + "zoom" + ], + 4 + ] + ], [ "!", [ "all", [ "match", - ["get", "maki"], - ["park", "cemetery"], + [ + "get", + "maki" + ], + [ + "park", + "cemetery" + ], true, false ], - ["<=", ["get", "sizerank"], 10] + [ + "<=", + [ + "get", + "sizerank" + ], + 10 + ] ] ] ], "layout": { "text-line-height": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 1, 15, @@ -2001,19 +3724,42 @@ ], "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 13, 15, 14 ], - "icon-offset": [0, -36], + "icon-offset": [ + 0, + -36 + ], "icon-image": [ "match", - ["get", "maki"], - ["museum", "lodging", "theatre", "grocery", "restaurant"], - ["concat", "poi_", ["get", "maki"]], + [ + "get", + "maki" + ], + [ + "museum", + "lodging", + "theatre", + "grocery", + "restaurant" + ], + [ + "concat", + "poi_", + [ + "get", + "maki" + ] + ], [ "fitness-centre", "golf", @@ -2030,9 +3776,17 @@ "cemetery" ], "poi_generic_green", - ["bank", "parking", "parking-garage"], + [ + "bank", + "parking", + "parking-garage" + ], "poi_generic_purple", - ["bar", "cafe", "bakery"], + [ + "bar", + "cafe", + "bakery" + ], "poi_generic_orange", [ "alcohol-shop", @@ -2053,7 +3807,10 @@ "monument" ], "poi_generic_teal", - ["hospital", "doctor"], + [ + "hospital", + "doctor" + ], "poi_generic_red", [ "restaurant-pizza", @@ -2065,33 +3822,65 @@ "poi_restaurant", "poi_generic" ], - "text-font": ["Roboto Regular", "Arial Unicode MS Regular"], + "text-font": [ + "Roboto Regular", + "Arial Unicode MS Regular" + ], "text-justify": "right", "text-offset": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, - ["literal", [-1.1, -0.7]], + [ + "literal", + [ + -1.1, + -0.7 + ] + ], 15, - ["literal", [-1.1, -0.9]] + [ + "literal", + [ + -1.1, + -0.9 + ] + ] ], "icon-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 0.25, 15, 0.32 ], "text-anchor": "right", - "text-field": ["to-string", ["get", "name"]] + "text-field": [ + "to-string", + [ + "get", + "name" + ] + ] }, "paint": { "text-color": [ "match", - ["get", "maki"], + [ + "get", + "maki" + ], [ "museum", "casino", @@ -2104,7 +3893,9 @@ "monument" ], "hsl(186, 78%, 65%)", - ["lodging"], + [ + "lodging" + ], "#df7db1", [ "fitness-centre", @@ -2144,49 +3935,97 @@ "jewelry-store" ], "hsl(213, 40%, 65%)", - ["bank", "parking", "parking-garage"], + [ + "bank", + "parking", + "parking-garage" + ], "hsl(228, 17%, 65%)", - ["hospital", "doctor"], + [ + "hospital", + "doctor" + ], "hsl(359, 22%, 65%)", "hsl(201, 9%, 80%)" ], "text-halo-color": "hsl(0, 1%, 0%)", "text-halo-width": 1, - "icon-translate": [0, 0], - "text-translate": [0, 0], + "icon-translate": [ + 0, + 0 + ], + "text-translate": [ + 0, + 0 + ], "text-halo-blur": 1 } }, { "id": "poi_label_right", "type": "symbol", - "metadata": {"mapbox:group": "124a9d7a8e5226775d947c592110dfad"}, + "metadata": { + "mapbox:group": "124a9d7a8e5226775d947c592110dfad" + }, "source": "composite", "source-layer": "poi_label", "filter": [ "all", - ["has", "name"], - ["<=", ["get", "filterrank"], ["/", ["zoom"], 4]], + [ + "has", + "name" + ], + [ + "<=", + [ + "get", + "filterrank" + ], + [ + "/", + [ + "zoom" + ], + 4 + ] + ], [ "!", [ "all", [ "match", - ["get", "maki"], - ["park", "cemetery"], + [ + "get", + "maki" + ], + [ + "park", + "cemetery" + ], true, false ], - ["<=", ["get", "sizerank"], 10] + [ + "<=", + [ + "get", + "sizerank" + ], + 10 + ] ] ] ], "layout": { "text-line-height": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 1, 15, @@ -2194,19 +4033,42 @@ ], "text-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 13, 15, 14 ], - "icon-offset": [0, -36], + "icon-offset": [ + 0, + -36 + ], "icon-image": [ "match", - ["get", "maki"], - ["museum", "lodging", "theatre", "grocery", "restaurant"], - ["concat", "poi_", ["get", "maki"]], + [ + "get", + "maki" + ], + [ + "museum", + "lodging", + "theatre", + "grocery", + "restaurant" + ], + [ + "concat", + "poi_", + [ + "get", + "maki" + ] + ], [ "fitness-centre", "golf", @@ -2223,9 +4085,17 @@ "cemetery" ], "poi_generic_green", - ["bank", "parking", "parking-garage"], + [ + "bank", + "parking", + "parking-garage" + ], "poi_generic_purple", - ["bar", "cafe", "bakery"], + [ + "bar", + "cafe", + "bakery" + ], "poi_generic_orange", [ "alcohol-shop", @@ -2246,7 +4116,10 @@ "monument" ], "poi_generic_teal", - ["hospital", "doctor"], + [ + "hospital", + "doctor" + ], "poi_generic_red", [ "restaurant-pizza", @@ -2258,33 +4131,65 @@ "poi_restaurant", "poi_generic" ], - "text-font": ["Roboto Regular", "Arial Unicode MS Regular"], + "text-font": [ + "Roboto Regular", + "Arial Unicode MS Regular" + ], "text-justify": "left", "text-offset": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, - ["literal", [1.1, -0.7]], + [ + "literal", + [ + 1.1, + -0.7 + ] + ], 15, - ["literal", [1.1, -0.9]] + [ + "literal", + [ + 1.1, + -0.9 + ] + ] ], "icon-size": [ "interpolate", - ["linear"], - ["zoom"], + [ + "linear" + ], + [ + "zoom" + ], 14, 0.25, 15, 0.32 ], "text-anchor": "left", - "text-field": ["to-string", ["get", "name"]] + "text-field": [ + "to-string", + [ + "get", + "name" + ] + ] }, "paint": { "text-color": [ "match", - ["get", "maki"], + [ + "get", + "maki" + ], [ "museum", "casino", @@ -2297,7 +4202,9 @@ "monument" ], "hsl(186, 78%, 65%)", - ["lodging"], + [ + "lodging" + ], "#df7db1", [ "fitness-centre", @@ -2337,16 +4244,29 @@ "jewelry-store" ], "hsl(213, 40%, 65%)", - ["bank", "parking", "parking-garage"], + [ + "bank", + "parking", + "parking-garage" + ], "hsl(228, 17%, 65%)", - ["hospital", "doctor"], + [ + "hospital", + "doctor" + ], "hsl(359, 22%, 65%)", "hsl(201, 9%, 80%)" ], "text-halo-color": "hsl(0, 1%, 0%)", "text-halo-width": 1, - "icon-translate": [0, 0], - "text-translate": [0, 0], + "icon-translate": [ + 0, + 0 + ], + "text-translate": [ + 0, + 0 + ], "text-halo-blur": 1 } } @@ -2358,4 +4278,4 @@ "visibility": "public", "protected": false, "draft": false -} \ No newline at end of file +} -- GitLab From f5c8e84d7c147144f171158245e4c1b8c110766d Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Wed, 8 Mar 2023 16:44:29 +0100 Subject: [PATCH 23/38] Custom styles implementation --- .../org/microg/gms/maps/mapbox/Styles.kt | 276 ++++++++++++++++-- 1 file changed, 255 insertions(+), 21 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt index 6942ef7ef..233efc77d 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt @@ -1,14 +1,21 @@ package org.microg.gms.maps.mapbox +import android.graphics.Color +import android.util.Log +import androidx.annotation.ColorInt import androidx.annotation.FloatRange +import androidx.core.graphics.ColorUtils import com.google.android.gms.maps.model.MapStyleOptions import com.google.gson.Gson import com.google.gson.JsonSyntaxException import com.google.gson.annotations.SerializedName import com.mapbox.mapboxsdk.maps.Style +import org.json.JSONArray import org.json.JSONObject import org.microg.gms.maps.MapsConstants import org.microg.gms.maps.mapbox.utils.MapContext +import java.lang.NumberFormatException +import kotlin.math.pow const val TAG = "GmsMapStyles" @@ -16,14 +23,16 @@ const val TAG = "GmsMapStyles" fun getStyle(context: MapContext, storedMapType: Int, styleOptions: MapStyleOptions?): Style.Builder { // TODO: Serve map style resources locally - val styleJson = JSONObject(context.assets.open( - when (storedMapType) { - MapsConstants.MAP_TYPE_SATELLITE, MapsConstants.MAP_TYPE_HYBRID -> "style-microg-satellite.json" - MapsConstants.MAP_TYPE_TERRAIN -> "style-mapbox-outdoors-v12.json" - //MAP_TYPE_NONE, MAP_TYPE_NORMAL, - else -> "style-microg-normal.json" - } - ).bufferedReader().readText()) + val styleJson = JSONObject( + context.assets.open( + when (storedMapType) { + MapsConstants.MAP_TYPE_SATELLITE, MapsConstants.MAP_TYPE_HYBRID -> "style-microg-satellite.json" + MapsConstants.MAP_TYPE_TERRAIN -> "style-mapbox-outdoors-v12.json" + //MAP_TYPE_NONE, MAP_TYPE_NORMAL, + else -> "style-microg-normal.json" + } + ).bufferedReader().readText() + ) styleOptions?.apply(styleJson) @@ -35,19 +44,61 @@ fun MapStyleOptions.apply(style: JSONObject) { Gson().fromJson(json, Array::class.java).let { styleOperations -> val layerArray = style.getJSONArray("layers") - for (i in 0 until layerArray.length()) { - val layer = layerArray.getJSONObject(i) - if (layer.has("metadata") && layer.getJSONObject("metadata") - .let { it.has("microg:gms-type-feature") && it.has("microg:gms-type-element") } - ) { - val featureType = layer.getJSONObject("metadata").getString("microg:gms-type-feature") - val elementType = layer.getJSONObject("metadata").getString("microg:gms-type-element") - - for (operation in styleOperations) { - if (operation.featureType?.startsWith(featureType) != false && // Todo: "all" here as well? - (operation.elementType?.startsWith(elementType) != false || operation.elementType == "all") + + // Apply operations in order + operations@ for (operation in styleOperations.map { + // Fill in default values for optional fields + NonNullStyleOperation(it.featureType ?: "all", it.elementType ?: "all", it.stylers ?: emptyArray()) + }) { + + // Reverse direction allows removing hidden layers + layers@ for (i in layerArray.length() - 1 downTo 0) { + + // Test if layer has required fields (metadata and paint) + val layer = layerArray.getJSONObject(i) + if (layer.has("paint") && layer.has("metadata") && layer.getJSONObject("metadata") + .let { it.has("microg:gms-type-feature") && it.has("microg:gms-type-element") } + ) { + val layerFeatureType = layer.getJSONObject("metadata").getString("microg:gms-type-feature") + val layerElementType = layer.getJSONObject("metadata").getString("microg:gms-type-element") + + if (operation.featureType.startsWith("administrative") + && operation.elementType.startsWith("geometry") + ) { + /* Per docs: + * `administrative` selects all administrative areas. Styling affects only + * the labels of administrative areas, not the geographical borders or fill. + */ + continue@operations + } + + // Layer metadata always has the most concrete category; operation applies to all subcategories as well. + if ((layerFeatureType.startsWith(operation.featureType) || operation.featureType == "all") && + (layerElementType.startsWith(operation.elementType) || operation.elementType == "all") ) { - operation.stylers?.forEach { styler -> styler.apply(layer) } + // Here, operation should be applied to this layer. + + Log.v(TAG, "applying ${Gson().toJson(operation)} to $layer") + + // Interpretation of visibility "simplified": hide labels, display geometry + if ( + // A styler sets the layer to be invisible + operation.stylers.any { it.visibility == "off" } || + // A styler sets the layer to simplified and we are working with a label + (layerElementType.startsWith("labels") && operation.stylers.any { it.visibility == "simplified" }) + ) { + layerArray.remove(i) + Log.v(TAG, "removing $layer") + continue@layers + } + + operation.stylers.forEach { styler -> + when (operation.elementType) { + "labels.text.fill" -> styler.applyTextFill(layer.getJSONObject("paint")) + "labels.text.outline" -> styler.applyTextOutline(layer.getJSONObject("paint")) + else -> styler.traverseApply(layer.getJSONObject("paint")) + } + } } } } @@ -62,6 +113,8 @@ fun MapStyleOptions.apply(style: JSONObject) { class StyleOperation(val featureType: String?, val elementType: String?, val stylers: Array?) +class NonNullStyleOperation(val featureType: String, val elementType: String, val stylers: Array) + class Styler( val hue: String?, @FloatRange(from = -100.0, to = 100.0) val saturation: Float?, @@ -73,4 +126,185 @@ class Styler( val weight: Int? ) -fun Styler.apply(layer: JSONObject) { TODO() } \ No newline at end of file +/** + * Returns true if string is likely to contain a color. + */ +fun String.isColor() = startsWith("hsl(") || startsWith("#") || startsWith("rgba(") + +/** + * Can parse colors in the format '#rrggbb', '#aarrggbb', 'hsl(h, s, l)', and 'rgba(r, g, b, a)' + * Returns 0 and prints to log if an invalid color is provided. + */ +@ColorInt +fun String.parseColor(): Int { + if (startsWith("#") && length in listOf(7, 9)) { + return Color.parseColor(this) + } else if (startsWith("hsl(")) { + val hsvArray = replace("hsl(", "").replace(")", "").split(", ") + if (hsvArray.size != 3) { + Log.w(TAG, "Invalid color `$this`") + return 0 + } + + return try { + Color.HSVToColor( + floatArrayOf( + hsvArray[0].toFloat(), + hsvArray[1].parseFloat(), + hsvArray[2].parseFloat() + ) + ) + } catch (e: NumberFormatException) { + Log.w(TAG, "Invalid color `$this`") + 0 + } + } else if (startsWith("rgba(")) { + return com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor(this) + } + + Log.w(TAG, "Invalid color `$this`") + return 0 +} + +/** + * Formats color int in such a format that it MapLibre's rendering engine understands it. + */ +fun Int.colorToString() = com.mapbox.mapboxsdk.utils.ColorUtils.colorToRgbaString(this) + +/** + * Can parse string values that contain '%'. + */ +fun String.parseFloat(): Float { + return if (contains("%")) { + replace("%", "").toFloat() + } else { + toFloat() + } +} + +/** + * Applies operation specified by styler to the provided color int, and returns + * a new, corresponding color int. + */ +@ColorInt +fun Styler.applyColorChanges(color: Int): Int { + // There may only be one operation per styler per docs. + + hue?.let { hue -> + // Extract hue from input color + val hslResult = FloatArray(3) + ColorUtils.colorToHSL(hue.parseColor(), hslResult) + + val hueDegree = hslResult[0] + + // Apply hue to layer color + ColorUtils.colorToHSL(color, hslResult) + hslResult[0] = hueDegree + return ColorUtils.HSLToColor(hslResult) + } + + lightness?.let { lightness -> + // Apply lightness to layer color + val hsl = FloatArray(3) + ColorUtils.colorToHSL(color, hsl) + hsl[2] = if (lightness < 0) { + // Increase darkness. Percentage amount = relative reduction of is-lightness. + (lightness / 100 + 1) * hsl[2] + } else { + // Increase brightness. Percentage amount = relative reduction of difference between is-lightness and 1.0. + hsl[2] + (lightness / 100) * (1 - hsl[2]) + } + return ColorUtils.HSLToColor(hsl) + } + + saturation?.let { saturation -> + // Apply saturation to layer color + val hsl = FloatArray(3) + ColorUtils.colorToHSL(color, hsl) + hsl[1] = if (saturation < 0) { + // Reduce intensity. Percentage amount = relative reduction of is-saturation. + (saturation / 100 + 1) * hsl[1] + } else { + // Increase intensity. Percentage amount = relative reduction of difference between is-saturation and 1.0. + hsl[1] + (saturation / 100) * (1 - hsl[1]) + } + + return ColorUtils.HSLToColor(hsl) + } + + gamma?.let { gamma -> + // Apply gamma to layer color + val hsl = FloatArray(3) + ColorUtils.colorToHSL(color, hsl) + hsl[2] = hsl[2].toDouble().pow(gamma.toDouble()).toFloat() + + return ColorUtils.HSLToColor(hsl) + } + + if (invertLightness == true) { + // Invert layer color's lightness + val hsl = FloatArray(3) + ColorUtils.colorToHSL(color, hsl) + hsl[2] = 1 - hsl[2] + + return ColorUtils.HSLToColor(hsl) + } + + this.color?.let { + return it.parseColor() + } + + Log.w(TAG, "No applicable operation") + return color +} + +/** + * Traverse JSON object and replace any color strings according to styler + */ +fun Styler.traverseApply(json: JSONObject) { + // Traverse layer and replace any color strings + json.keys().forEach { key -> + json.get(key).let { + when (it) { + is JSONObject -> traverseApply(it) + is JSONArray -> traverseApply(it) + is String -> if (it.isColor()) { + json.put(key, applyColorChanges(it.parseColor()).colorToString()) + } + } + } + } +} + +/** + * Traverse array and replace any color strings according to styler + */ +fun Styler.traverseApply(array: JSONArray) { + for (i in 0 until array.length()) { + array.get(i).let { + when (it) { + is JSONObject -> traverseApply(it) + is JSONArray -> traverseApply(it) + is String -> if (it.isColor()) { + array.put(i, applyColorChanges(it.parseColor()).colorToString()) + } + } + } + } +} + +fun Styler.applyTextFill(paint: JSONObject) { + if (paint.has("text-color")) when (val textColor = paint.get("text-color")) { + is JSONObject -> traverseApply(textColor) + is JSONArray -> traverseApply(textColor) + is String -> paint.put("text-color", applyColorChanges(textColor.parseColor()).colorToString()) + } +} + +fun Styler.applyTextOutline(paint: JSONObject) { + if (paint.has("text-halo-color")) when (val textOutline = paint.get("text-halo-color")) { + is JSONObject -> traverseApply(textOutline) + is JSONArray -> traverseApply(textOutline) + is String -> paint.put("text-halo-color", applyColorChanges(textOutline.parseColor()).colorToString()) + } +} -- GitLab From 30369062fae7707377e4be5ab77d381dc2da7f37 Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Wed, 8 Mar 2023 16:44:47 +0100 Subject: [PATCH 24/38] Custom styles metadata in normal style --- .../src/main/assets/style-microg-normal.json | 204 +++++++++++++----- 1 file changed, 153 insertions(+), 51 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/assets/style-microg-normal.json b/play-services-maps-core-mapbox/src/main/assets/style-microg-normal.json index 9490b1108..295ffad44 100644 --- a/play-services-maps-core-mapbox/src/main/assets/style-microg-normal.json +++ b/play-services-maps-core-mapbox/src/main/assets/style-microg-normal.json @@ -90,13 +90,19 @@ 18, "#f8f9fb" ] + }, + "metadata": { + "microg:gms-type-feature": "landscape.natural.landcover", + "microg:gms-type-element": "geometry.fill" } }, { "id": "grass", "type": "fill", "metadata": { - "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e", + "microg:gms-type-feature": "landscape.natural.landcover", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "landcover", @@ -137,7 +143,9 @@ "id": "forrest", "type": "fill", "metadata": { - "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e", + "microg:gms-type-feature": "landscape.natural.landcover", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "landcover", @@ -179,7 +187,9 @@ "id": "national_park", "type": "fill", "metadata": { - "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e", + "microg:gms-type-feature": "landscape.natural.landcover", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "landuse_overlay", @@ -204,7 +214,9 @@ "id": "snow", "type": "fill", "metadata": { - "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e", + "microg:gms-type-feature": "landscape.natural.landcover", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "landcover", @@ -229,7 +241,9 @@ "id": "hillshade", "type": "fill", "metadata": { - "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e", + "microg:gms-type-feature": "landscape.natural.terrain", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "hillshade", @@ -254,7 +268,9 @@ "id": "park", "type": "fill", "metadata": { - "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e", + "microg:gms-type-feature": "poi.park", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "landuse", @@ -280,7 +296,9 @@ "id": "pitch", "type": "fill", "metadata": { - "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e", + "microg:gms-type-feature": "landscape.natural.terrain", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "landuse", @@ -305,7 +323,9 @@ "id": "landuse", "type": "fill", "metadata": { - "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e", + "microg:gms-type-feature": "landscape.man_made", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "landuse", @@ -332,7 +352,9 @@ "id": "river", "type": "fill", "metadata": { - "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" + "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e", + "microg:gms-type-feature": "water", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "water", @@ -345,7 +367,9 @@ "id": "path", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -390,7 +414,9 @@ "id": "steps", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -435,7 +461,9 @@ "id": "platform", "type": "fill", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "transit.station.rail", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -513,7 +541,9 @@ "id": "primary_tunnel_border", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.stroke" }, "source": "composite", "source-layer": "road", @@ -576,7 +606,9 @@ "id": "primary_tunnel", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -637,7 +669,9 @@ "id": "aeroway", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "transit.station.airport", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "aeroway", @@ -650,7 +684,9 @@ "id": "service_road", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -675,7 +711,9 @@ "id": "pedestrian_border", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" }, "source": "composite", "source-layer": "road", @@ -735,7 +773,9 @@ "id": "street_border", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" }, "source": "composite", "source-layer": "road", @@ -775,7 +815,9 @@ "id": "secondary_border", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" }, "source": "composite", "source-layer": "road", @@ -833,7 +875,9 @@ "id": "primary_border", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.stroke" }, "source": "composite", "source-layer": "road", @@ -892,7 +936,9 @@ "id": "motorway_border", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.arterial", + "microg:gms-type-element": "geometry.stroke" }, "source": "composite", "source-layer": "road", @@ -945,7 +991,9 @@ "id": "railway", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "transit.line", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -987,7 +1035,9 @@ "id": "pedestrian", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -1059,7 +1109,9 @@ "id": "street", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -1099,7 +1151,9 @@ "id": "secondary", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -1144,7 +1198,9 @@ "id": "primary", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -1211,7 +1267,9 @@ "id": "motorway", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.arterial", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -1251,7 +1309,9 @@ "id": "primary_bridge_border", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.stroke" }, "source": "composite", "source-layer": "road", @@ -1308,7 +1368,9 @@ "id": "primary_bridge", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -1373,7 +1435,9 @@ "id": "building", "type": "fill", "metadata": { - "mapbox:group": "29bb589e8d1b9b402583363648b70302" + "mapbox:group": "29bb589e8d1b9b402583363648b70302", + "microg:gms-type-feature": "landscape.man_made", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "building", @@ -1430,7 +1494,9 @@ "id": "building_border", "type": "line", "metadata": { - "mapbox:group": "29bb589e8d1b9b402583363648b70302" + "mapbox:group": "29bb589e8d1b9b402583363648b70302", + "microg:gms-type-feature": "landscape.man_made", + "microg:gms-type-element": "geometry.stroke" }, "source": "composite", "source-layer": "building", @@ -1487,7 +1553,9 @@ "id": "building_3d", "type": "fill-extrusion", "metadata": { - "mapbox:group": "29bb589e8d1b9b402583363648b70302" + "mapbox:group": "29bb589e8d1b9b402583363648b70302", + "microg:gms-type-feature": "landscape.man_made", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "building", @@ -1529,7 +1597,9 @@ "id": "admin_0", "type": "line", "metadata": { - "mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa" + "mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa", + "microg:gms-type-feature": "administrative.country", + "microg:gms-type-element": "geometry.stroke" }, "source": "composite", "source-layer": "admin", @@ -1581,7 +1651,9 @@ "id": "admin_1", "type": "line", "metadata": { - "mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa" + "mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa", + "microg:gms-type-feature": "administrative.province", + "microg:gms-type-element": "geometry.stroke" }, "source": "composite", "source-layer": "admin", @@ -1637,7 +1709,9 @@ "id": "river_name", "type": "symbol", "metadata": { - "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce", + "microg:gms-type-feature": "water", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "natural_label", @@ -1677,7 +1751,9 @@ "id": "city_label_right", "type": "symbol", "metadata": { - "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce", + "microg:gms-type-feature": "administrative.locality", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "place_label", @@ -1864,7 +1940,9 @@ "id": "city_label_left", "type": "symbol", "metadata": { - "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce", + "microg:gms-type-feature": "administrative.locality", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "place_label", @@ -2050,7 +2128,9 @@ "id": "city_label_below", "type": "symbol", "metadata": { - "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce", + "microg:gms-type-feature": "administrative.locality", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "place_label", @@ -2235,7 +2315,9 @@ "id": "city_name", "type": "symbol", "metadata": { - "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce", + "microg:gms-type-feature": "administrative.locality", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "place_label", @@ -2481,8 +2563,8 @@ "type": "symbol", "metadata": { "mapbox:group": "7b44201d7f1682d99f7140188aff23ce", - "microg:gms-type-feature": "poi", - "microg:gms-type-element": "label" + "microg:gms-type-feature": "poi.park", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "poi_label", @@ -2538,7 +2620,9 @@ "id": "road-number-shield", "type": "symbol", "metadata": { - "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312", + "microg:gms-type-feature": "road", + "microg:gms-type-element": "labels.icon" }, "source": "composite", "source-layer": "road", @@ -2750,7 +2834,9 @@ "id": "country_name", "type": "symbol", "metadata": { - "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312", + "microg:gms-type-feature": "administrative.country", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "place_label", @@ -2840,7 +2926,9 @@ "id": "pedestrian_name", "type": "symbol", "metadata": { - "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "road", @@ -2911,7 +2999,9 @@ "id": "street_name", "type": "symbol", "metadata": { - "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "road", @@ -2969,7 +3059,9 @@ "id": "secondary_name", "type": "symbol", "metadata": { - "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "road", @@ -3033,7 +3125,9 @@ "id": "primary_name", "type": "symbol", "metadata": { - "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "road", @@ -3093,7 +3187,9 @@ "id": "poi_label_below", "type": "symbol", "metadata": { - "mapbox:group": "124a9d7a8e5226775d947c592110dfad" + "mapbox:group": "124a9d7a8e5226775d947c592110dfad", + "microg:gms-type-element": "labels.text", + "microg:gms-type-feature": "poi" }, "source": "composite", "source-layer": "poi_label", @@ -3380,7 +3476,9 @@ "id": "poi_label_above", "type": "symbol", "metadata": { - "mapbox:group": "124a9d7a8e5226775d947c592110dfad" + "mapbox:group": "124a9d7a8e5226775d947c592110dfad", + "microg:gms-type-element": "labels.text", + "microg:gms-type-feature": "poi" }, "source": "composite", "source-layer": "poi_label", @@ -3667,7 +3765,9 @@ "id": "poi_label_left", "type": "symbol", "metadata": { - "mapbox:group": "124a9d7a8e5226775d947c592110dfad" + "mapbox:group": "124a9d7a8e5226775d947c592110dfad", + "microg:gms-type-element": "labels.text", + "microg:gms-type-feature": "poi" }, "source": "composite", "source-layer": "poi_label", @@ -3975,7 +4075,9 @@ "id": "poi_label_right", "type": "symbol", "metadata": { - "mapbox:group": "124a9d7a8e5226775d947c592110dfad" + "mapbox:group": "124a9d7a8e5226775d947c592110dfad", + "microg:gms-type-element": "labels.text", + "microg:gms-type-feature": "poi" }, "source": "composite", "source-layer": "poi_label", -- GitLab From 1b54cce1521ff2b64251ec01871f20a6e14925e8 Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Wed, 8 Mar 2023 16:50:53 +0100 Subject: [PATCH 25/38] Constantize metadata field keys --- .../src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt index 233efc77d..46e8db176 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt @@ -18,7 +18,8 @@ import java.lang.NumberFormatException import kotlin.math.pow const val TAG = "GmsMapStyles" - +const val KEY_METADATA_FEATURE_TYPE = "microg:gms-type-feature" +const val KEY_METADATA_ELEMENT_TYPE = "microg:gms-type-element" fun getStyle(context: MapContext, storedMapType: Int, styleOptions: MapStyleOptions?): Style.Builder { @@ -57,10 +58,10 @@ fun MapStyleOptions.apply(style: JSONObject) { // Test if layer has required fields (metadata and paint) val layer = layerArray.getJSONObject(i) if (layer.has("paint") && layer.has("metadata") && layer.getJSONObject("metadata") - .let { it.has("microg:gms-type-feature") && it.has("microg:gms-type-element") } + .let { it.has(KEY_METADATA_FEATURE_TYPE) && it.has(KEY_METADATA_ELEMENT_TYPE) } ) { - val layerFeatureType = layer.getJSONObject("metadata").getString("microg:gms-type-feature") - val layerElementType = layer.getJSONObject("metadata").getString("microg:gms-type-element") + val layerFeatureType = layer.getJSONObject("metadata").getString(KEY_METADATA_FEATURE_TYPE) + val layerElementType = layer.getJSONObject("metadata").getString(KEY_METADATA_ELEMENT_TYPE) if (operation.featureType.startsWith("administrative") && operation.elementType.startsWith("geometry") -- GitLab From 682ee3dca46146d2d160497bf09e6e7920a45d93 Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Thu, 9 Mar 2023 16:26:20 +0100 Subject: [PATCH 26/38] Remove hidden layers from satellite style --- .../main/assets/style-microg-satellite.json | 876 +----------------- 1 file changed, 10 insertions(+), 866 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/assets/style-microg-satellite.json b/play-services-maps-core-mapbox/src/main/assets/style-microg-satellite.json index 1a6e2e974..51dc9a3fd 100644 --- a/play-services-maps-core-mapbox/src/main/assets/style-microg-satellite.json +++ b/play-services-maps-core-mapbox/src/main/assets/style-microg-satellite.json @@ -75,230 +75,6 @@ "layout": {}, "paint": {} }, - { - "id": "forrest", - "type": "fill", - "metadata": { - "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" - }, - "source": "composite", - "source-layer": "landcover", - "filter": [ - "match", - [ - "get", - "class" - ], - [ - "wood", - "scrub" - ], - true, - false - ], - "layout": { - "visibility": "none" - }, - "paint": { - "fill-color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 9, - "hsl(124, 42%, 86%)", - 11, - "hsl(107, 47%, 94%)", - 12.5, - "hsl(107, 47%, 94%)", - 13.5, - "hsl(45, 12%, 93%)" - ] - } - }, - { - "id": "national_park", - "type": "fill", - "metadata": { - "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" - }, - "source": "composite", - "source-layer": "landuse_overlay", - "filter": [ - "match", - [ - "get", - "class" - ], - [ - "national_park" - ], - true, - false - ], - "layout": { - "visibility": "none" - }, - "paint": { - "fill-color": "hsl(106, 58%, 85%)" - } - }, - { - "id": "snow", - "type": "fill", - "metadata": { - "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" - }, - "source": "composite", - "source-layer": "landcover", - "filter": [ - "match", - [ - "get", - "class" - ], - [ - "snow" - ], - true, - false - ], - "layout": { - "visibility": "none" - }, - "paint": { - "fill-color": "#f9fafc" - } - }, - { - "id": "hillshade", - "type": "fill", - "metadata": { - "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" - }, - "source": "composite", - "source-layer": "hillshade", - "layout": { - "visibility": "none" - }, - "paint": { - "fill-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 9, - 0.03, - 13, - 0 - ] - } - }, - { - "id": "park", - "type": "fill", - "metadata": { - "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" - }, - "source": "composite", - "source-layer": "landuse", - "filter": [ - "match", - [ - "get", - "class" - ], - [ - "park", - "scrub" - ], - true, - false - ], - "layout": { - "visibility": "none" - }, - "paint": { - "fill-color": "#c1ecaf" - } - }, - { - "id": "pitch", - "type": "fill", - "metadata": { - "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" - }, - "source": "composite", - "source-layer": "landuse", - "filter": [ - "match", - [ - "get", - "class" - ], - [ - "pitch" - ], - true, - false - ], - "layout": { - "visibility": "none" - }, - "paint": { - "fill-color": "#c8efbb" - } - }, - { - "id": "landuse", - "type": "fill", - "metadata": { - "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" - }, - "source": "composite", - "source-layer": "landuse", - "filter": [ - "match", - [ - "get", - "class" - ], - [ - "airport", - "school", - "hospital" - ], - true, - false - ], - "layout": { - "visibility": "none" - }, - "paint": { - "fill-color": "hsl(202, 26%, 94%)" - } - }, - { - "id": "river", - "type": "fill", - "metadata": { - "mapbox:group": "f51b507d2a17e572c70a5db74b0fec7e" - }, - "source": "composite", - "source-layer": "water", - "layout": { - "visibility": "none" - }, - "paint": { - "fill-color": "hsl(206, 100%, 83%)" - } - }, { "id": "path", "type": "line", @@ -454,71 +230,6 @@ ] } }, - { - "id": "primary_tunnel_border", - "type": "line", - "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" - }, - "source": "composite", - "source-layer": "road", - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "primary_link", - "primary", - "motorway_link" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "tunnel" - ], - true, - false - ] - ], - "layout": { - "visibility": "none" - }, - "paint": { - "line-gap-width": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 7, - 0, - 8, - 1, - 12, - 4, - 14, - 6, - 16, - 10, - 22, - 64 - ], - "line-color": "#cbcccd" - } - }, { "id": "primary_tunnel", "type": "line", @@ -609,295 +320,16 @@ "get", "class" ], - [ - "service" - ], - true, - false - ], - "layout": {}, - "paint": { - "line-color": "hsla(0, 0%, 0%, 0.1)", - "line-opacity": 0.3 - } - }, - { - "id": "pedestrian_border", - "type": "line", - "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" - }, - "source": "composite", - "source-layer": "road", - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "pedestrian" - ], - true, - false - ], - [ - "has", - "name" - ] - ], - "layout": { - "visibility": "none" - }, - "paint": { - "line-gap-width": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 13, - 1, - 16, - 4, - 22, - 32 - ], - "line-color": "#e3e3e3", - "line-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 12.5, - 0, - 13.5, - 1 - ] - } - }, - { - "id": "street_border", - "type": "line", - "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" - }, - "source": "composite", - "source-layer": "road", - "filter": [ - "match", - [ - "get", - "class" - ], - [ - "street" - ], - true, - false - ], - "layout": { - "visibility": "none" - }, - "paint": { - "line-gap-width": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 12, - 1, - 16, - 6, - 22, - 40 - ], - "line-color": "#e3e3e3" - } - }, - { - "id": "secondary_border", - "type": "line", - "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" - }, - "source": "composite", - "source-layer": "road", - "filter": [ - "match", - [ - "get", - "class" - ], - [ - "secondary", - "secondary_link", - "tertiary_link", - "tertiary", - "trunk_link", - "trunk" - ], - true, - false - ], - "layout": { - "visibility": "none" - }, - "paint": { - "line-gap-width": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 10, - 1, - 17, - 10, - 22, - 48 - ], - "line-color": "#e3e3e3", - "line-width": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 16, - 1, - 20, - 2 - ] - } - }, - { - "id": "primary_border", - "type": "line", - "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" - }, - "source": "composite", - "source-layer": "road", - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "primary_link", - "primary", - "motorway_link" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "tunnel" - ], - false, - true - ] - ], - "layout": { - "line-cap": "round", - "visibility": "none" - }, - "paint": { - "line-gap-width": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 9, - 1, - 16, - 8, - 22, - 64 - ], - "line-color": "#ecd283" - } - }, - { - "id": "motorway_border", - "type": "line", - "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" - }, - "source": "composite", - "source-layer": "road", - "filter": [ - "match", - [ - "get", - "class" - ], - [ - "motorway" - ], - true, - false - ], - "layout": { - "visibility": "none" - }, - "paint": { - "line-gap-width": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 8, - 1, - 15.5, - 8, - 22, - 78 - ], - "line-color": "#ecd283", - "line-width": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 8, - 1, - 15, - 2 - ] + [ + "service" + ], + true, + false + ], + "layout": {}, + "paint": { + "line-color": "hsla(0, 0%, 0%, 0.1)", + "line-opacity": 0.3 } }, { @@ -1196,294 +628,6 @@ "line-opacity": 0.3 } }, - { - "id": "primary_bridge_border", - "type": "line", - "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" - }, - "source": "composite", - "source-layer": "road", - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "primary_link", - "primary", - "motorway_link" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "bridge" - ], - true, - false - ] - ], - "layout": { - "visibility": "none" - }, - "paint": { - "line-gap-width": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 9, - 1, - 16, - 8, - 22, - 64 - ], - "line-color": "hsl(45, 73%, 72%)" - } - }, - { - "id": "primary_bridge", - "type": "line", - "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" - }, - "source": "composite", - "source-layer": "road", - "filter": [ - "all", - [ - "match", - [ - "get", - "class" - ], - [ - "primary_link", - "primary", - "motorway_link" - ], - true, - false - ], - [ - "match", - [ - "get", - "structure" - ], - [ - "bridge" - ], - true, - false - ] - ], - "layout": { - "visibility": "none" - }, - "paint": { - "line-color": [ - "step", - [ - "zoom" - ], - "hsl(50, 100%, 75%)", - 7, - "hsl(50, 100%, 85%)" - ], - "line-width": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 9, - 1, - 16, - 8, - 22, - 64 - ] - } - }, - { - "id": "building", - "type": "fill", - "metadata": { - "mapbox:group": "29bb589e8d1b9b402583363648b70302" - }, - "source": "composite", - "source-layer": "building", - "filter": [ - "match", - [ - "get", - "type" - ], - [ - "roof" - ], - false, - true - ], - "layout": { - "visibility": "none" - }, - "paint": { - "fill-color": [ - "match", - [ - "get", - "type" - ], - [ - "store", - "retail", - "church", - "kiosk", - "civic", - "hotel", - "supermarket", - "pub", - "dormitory" - ], - "hsl(33, 100%, 96%)", - "#ededed" - ], - "fill-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 15, - 0, - 17, - 1 - ] - } - }, - { - "id": "building_border", - "type": "line", - "metadata": { - "mapbox:group": "29bb589e8d1b9b402583363648b70302" - }, - "source": "composite", - "source-layer": "building", - "filter": [ - "match", - [ - "get", - "type" - ], - [ - "roof" - ], - false, - true - ], - "layout": { - "visibility": "none" - }, - "paint": { - "line-color": [ - "match", - [ - "get", - "type" - ], - [ - "store", - "retail", - "church", - "kiosk", - "civic", - "commercial", - "hotel", - "supermarket", - "pub" - ], - "#f8e1c7", - "#dcdcdc" - ], - "line-opacity": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 15, - 0, - 17, - 1 - ] - } - }, - { - "id": "building_3d", - "type": "fill-extrusion", - "metadata": { - "mapbox:group": "29bb589e8d1b9b402583363648b70302" - }, - "source": "composite", - "source-layer": "building", - "filter": [ - "match", - [ - "get", - "extrude" - ], - [ - "true" - ], - true, - false - ], - "layout": { - "visibility": "none" - }, - "paint": { - "fill-extrusion-height": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 15, - 0, - 16, - [ - "get", - "height" - ] - ], - "fill-extrusion-color": "#ededed", - "fill-extrusion-opacity": 0.3 - } - }, { "id": "admin_0", "type": "line", -- GitLab From 0fbe623338f485e84e3c86e1607efbc1e3de9d1a Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Thu, 9 Mar 2023 16:29:16 +0100 Subject: [PATCH 27/38] Prepare satellite style for use with custom colors --- .../main/assets/style-microg-satellite.json | 126 +++++++++++++----- 1 file changed, 95 insertions(+), 31 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/assets/style-microg-satellite.json b/play-services-maps-core-mapbox/src/main/assets/style-microg-satellite.json index 51dc9a3fd..accb62735 100644 --- a/play-services-maps-core-mapbox/src/main/assets/style-microg-satellite.json +++ b/play-services-maps-core-mapbox/src/main/assets/style-microg-satellite.json @@ -73,13 +73,19 @@ "type": "raster", "source": "mapbox://mapbox.satellite", "layout": {}, - "paint": {} + "paint": {}, + "metadata": { + "microg:gms-type-feature": "landscape.natural.landcover", + "microg:gms-type-element": "geometry.fill" + } }, { "id": "path", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -125,7 +131,9 @@ "id": "steps", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -171,7 +179,9 @@ "id": "platform", "type": "fill", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "transit.station.rail", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -234,7 +244,9 @@ "id": "primary_tunnel", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -296,7 +308,9 @@ "id": "aeroway", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "transit.station.airport", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "aeroway", @@ -310,7 +324,9 @@ "id": "service_road", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -336,7 +352,9 @@ "id": "railway", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "transit.line", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -364,7 +382,9 @@ "id": "pedestrian", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -436,7 +456,9 @@ "id": "street", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -477,7 +499,9 @@ "id": "secondary", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -523,7 +547,9 @@ "id": "primary", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -591,7 +617,9 @@ "id": "motorway", "type": "line", "metadata": { - "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990" + "mapbox:group": "3f48b8dc54ff2e6544b9ef9cedbf2990", + "microg:gms-type-feature": "road.arterial", + "microg:gms-type-element": "geometry.fill" }, "source": "composite", "source-layer": "road", @@ -632,7 +660,9 @@ "id": "admin_0", "type": "line", "metadata": { - "mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa" + "mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa", + "microg:gms-type-feature": "administrative.country", + "microg:gms-type-element": "geometry.stroke" }, "source": "composite", "source-layer": "admin", @@ -684,7 +714,9 @@ "id": "admin_1", "type": "line", "metadata": { - "mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa" + "mapbox:group": "3c26e9cbc75335c6f0ba8de5439cf1fa", + "microg:gms-type-feature": "administrative.province", + "microg:gms-type-element": "geometry.stroke" }, "source": "composite", "source-layer": "admin", @@ -740,7 +772,9 @@ "id": "river_name", "type": "symbol", "metadata": { - "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce", + "microg:gms-type-feature": "water", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "natural_label", @@ -781,7 +815,9 @@ "id": "city_label_right", "type": "symbol", "metadata": { - "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce", + "microg:gms-type-feature": "administrative.locality", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "place_label", @@ -974,7 +1010,9 @@ "id": "city_label_left", "type": "symbol", "metadata": { - "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce", + "microg:gms-type-feature": "administrative.locality", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "place_label", @@ -1166,7 +1204,9 @@ "id": "city_label_below", "type": "symbol", "metadata": { - "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce", + "microg:gms-type-feature": "administrative.locality", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "place_label", @@ -1357,7 +1397,9 @@ "id": "city_name", "type": "symbol", "metadata": { - "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce", + "microg:gms-type-feature": "administrative.locality", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "place_label", @@ -1608,7 +1650,9 @@ "id": "park_name", "type": "symbol", "metadata": { - "mapbox:group": "7b44201d7f1682d99f7140188aff23ce" + "mapbox:group": "7b44201d7f1682d99f7140188aff23ce", + "microg:gms-type-feature": "poi.park", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "poi_label", @@ -1665,7 +1709,9 @@ "id": "road-number-shield", "type": "symbol", "metadata": { - "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "labels.icon" }, "source": "composite", "source-layer": "road", @@ -1876,7 +1922,9 @@ "id": "country_name", "type": "symbol", "metadata": { - "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312", + "microg:gms-type-feature": "administrative.country", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "place_label", @@ -1967,7 +2015,9 @@ "id": "pedestrian_name", "type": "symbol", "metadata": { - "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "road", @@ -2039,7 +2089,9 @@ "id": "street_name", "type": "symbol", "metadata": { - "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "road", @@ -2098,7 +2150,9 @@ "id": "secondary_name", "type": "symbol", "metadata": { - "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "road", @@ -2163,7 +2217,9 @@ "id": "primary_name", "type": "symbol", "metadata": { - "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312" + "mapbox:group": "24306bdccbff03e2ee08d5d1a4ca7312", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "road", @@ -2224,7 +2280,9 @@ "id": "poi_label_below", "type": "symbol", "metadata": { - "mapbox:group": "124a9d7a8e5226775d947c592110dfad" + "mapbox:group": "124a9d7a8e5226775d947c592110dfad", + "microg:gms-type-feature": "poi", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "poi_label", @@ -2512,7 +2570,9 @@ "id": "poi_label_above", "type": "symbol", "metadata": { - "mapbox:group": "124a9d7a8e5226775d947c592110dfad" + "mapbox:group": "124a9d7a8e5226775d947c592110dfad", + "microg:gms-type-feature": "poi", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "poi_label", @@ -2800,7 +2860,9 @@ "id": "poi_label_left", "type": "symbol", "metadata": { - "mapbox:group": "124a9d7a8e5226775d947c592110dfad" + "mapbox:group": "124a9d7a8e5226775d947c592110dfad", + "microg:gms-type-feature": "poi", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "poi_label", @@ -3109,7 +3171,9 @@ "id": "poi_label_right", "type": "symbol", "metadata": { - "mapbox:group": "124a9d7a8e5226775d947c592110dfad" + "mapbox:group": "124a9d7a8e5226775d947c592110dfad", + "microg:gms-type-feature": "poi", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "poi_label", -- GitLab From af3e452c9c44deacf71ccfb83904e9985a40c68e Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Thu, 9 Mar 2023 17:01:51 +0100 Subject: [PATCH 28/38] Fix important bugs --- .../kotlin/org/microg/gms/maps/mapbox/Styles.kt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt index 46e8db176..d2a1aef44 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt @@ -141,18 +141,18 @@ fun String.parseColor(): Int { if (startsWith("#") && length in listOf(7, 9)) { return Color.parseColor(this) } else if (startsWith("hsl(")) { - val hsvArray = replace("hsl(", "").replace(")", "").split(", ") - if (hsvArray.size != 3) { + val hslArray = replace("hsl(", "").replace(")", "").split(", ") + if (hslArray.size != 3) { Log.w(TAG, "Invalid color `$this`") return 0 } return try { - Color.HSVToColor( + ColorUtils.HSLToColor( floatArrayOf( - hsvArray[0].toFloat(), - hsvArray[1].parseFloat(), - hsvArray[2].parseFloat() + hslArray[0].toFloat(), + hslArray[1].parseFloat(), + hslArray[2].parseFloat() ) ) } catch (e: NumberFormatException) { @@ -177,7 +177,7 @@ fun Int.colorToString() = com.mapbox.mapboxsdk.utils.ColorUtils.colorToRgbaStrin */ fun String.parseFloat(): Float { return if (contains("%")) { - replace("%", "").toFloat() + replace("%", "").toFloat() / 100f } else { toFloat() } -- GitLab From a5685a0f529b33951af330f2f1dacf90c225c0ac Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Sun, 12 Mar 2023 18:04:05 +0100 Subject: [PATCH 29/38] Prepare outdoor style for custom colors --- .../assets/style-mapbox-outdoors-v12.json | 592 +++++++++++++----- 1 file changed, 444 insertions(+), 148 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/assets/style-mapbox-outdoors-v12.json b/play-services-maps-core-mapbox/src/main/assets/style-mapbox-outdoors-v12.json index e022a2916..21c4d40f5 100644 --- a/play-services-maps-core-mapbox/src/main/assets/style-mapbox-outdoors-v12.json +++ b/play-services-maps-core-mapbox/src/main/assets/style-mapbox-outdoors-v12.json @@ -97,7 +97,9 @@ }, "metadata": { "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, land" + "mapbox:group": "Land & water, land", + "microg:gms-type-feature": "landscape.natural.landcover", + "microg:gms-type-element": "geometry.fill" } }, { @@ -145,7 +147,9 @@ }, "metadata": { "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, land" + "mapbox:group": "Land & water, land", + "microg:gms-type-feature": "landscape.natural.landcover", + "microg:gms-type-element": "geometry.fill" } }, { @@ -183,7 +187,9 @@ }, "metadata": { "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, land" + "mapbox:group": "Land & water, land", + "microg:gms-type-feature": "landscape.natural.landcover", + "microg:gms-type-element": "geometry.fill" } }, { @@ -234,7 +240,9 @@ }, "metadata": { "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, land" + "mapbox:group": "Land & water, land", + "microg:gms-type-feature": "landscape.natural.landcover", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -569,7 +577,9 @@ }, "metadata": { "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, land" + "mapbox:group": "Land & water, land", + "microg:gms-type-feature": "landscape.man_made", + "microg:gms-type-element": "geometry.fill" } }, { @@ -592,7 +602,9 @@ }, "metadata": { "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, land" + "mapbox:group": "Land & water, land", + "microg:gms-type-feature": "landscape.natural.landcover", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -704,7 +716,9 @@ }, "metadata": { "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, water" + "mapbox:group": "Land & water, water", + "microg:gms-type-feature": "water", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -746,7 +760,9 @@ }, "metadata": { "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, water" + "mapbox:group": "Land & water, water", + "microg:gms-type-feature": "water", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -831,7 +847,9 @@ }, "metadata": { "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, water" + "mapbox:group": "Land & water, water", + "microg:gms-type-feature": "water", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -846,7 +864,9 @@ }, "metadata": { "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, water" + "mapbox:group": "Land & water, water", + "microg:gms-type-feature": "water", + "microg:gms-type-element": "geometry.fill" } }, { @@ -905,7 +925,9 @@ }, "metadata": { "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, water" + "mapbox:group": "Land & water, water", + "microg:gms-type-feature": "water", + "microg:gms-type-element": "geometry.fill" } }, { @@ -945,7 +967,9 @@ }, "metadata": { "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, water" + "mapbox:group": "Land & water, water", + "microg:gms-type-feature": "water", + "microg:gms-type-element": "geometry.fill" } }, { @@ -987,7 +1011,9 @@ }, "metadata": { "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, water" + "mapbox:group": "Land & water, water", + "microg:gms-type-feature": "water", + "microg:gms-type-element": "geometry.fill" } }, { @@ -1113,7 +1139,9 @@ }, "metadata": { "mapbox:featureComponent": "terrain", - "mapbox:group": "Terrain, land" + "mapbox:group": "Terrain, land", + "microg:gms-type-feature": "landscape.natural.terrain", + "microg:gms-type-element": "geometry.fill" } }, { @@ -1210,7 +1238,9 @@ }, "metadata": { "mapbox:featureComponent": "terrain", - "mapbox:group": "Terrain, land" + "mapbox:group": "Terrain, land", + "microg:gms-type-feature": "landscape.natural.terrain", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -1243,7 +1273,9 @@ }, "metadata": { "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, built" + "mapbox:group": "Land & water, built", + "microg:gms-type-feature": "landscape.natural.terrain", + "microg:gms-type-element": "geometry.fill" } }, { @@ -1292,7 +1324,9 @@ }, "metadata": { "mapbox:featureComponent": "land-and-water", - "mapbox:group": "Land & water, built" + "mapbox:group": "Land & water, built", + "microg:gms-type-feature": "landscape.natural.terrain", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -1343,7 +1377,9 @@ }, "metadata": { "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, built" + "mapbox:group": "Transit, built", + "microg:gms-type-feature": "transit.station.airport", + "microg:gms-type-element": "geometry.fill" } }, { @@ -1409,7 +1445,9 @@ }, "metadata": { "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, built" + "mapbox:group": "Transit, built", + "microg:gms-type-feature": "transit.station.airport", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -1457,7 +1495,9 @@ }, "metadata": { "mapbox:featureComponent": "buildings", - "mapbox:group": "Buildings, built" + "mapbox:group": "Buildings, built", + "microg:gms-type-feature": "landscape.man_made", + "microg:gms-type-element": "geometry.fill" } }, { @@ -1503,7 +1543,9 @@ }, "metadata": { "mapbox:featureComponent": "buildings", - "mapbox:group": "Buildings, built" + "mapbox:group": "Buildings, built", + "microg:gms-type-feature": "landscape.man_made", + "microg:gms-type-element": "geometry.fill" } }, { @@ -1591,7 +1633,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels-case" + "mapbox:group": "Road network, tunnels-case", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -1679,7 +1723,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels-case" + "mapbox:group": "Road network, tunnels-case", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -1784,7 +1830,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels-case" + "mapbox:group": "Road network, tunnels-case", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -1863,7 +1911,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels-case" + "mapbox:group": "Road network, tunnels-case", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -1937,7 +1987,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels-case" + "mapbox:group": "Road network, tunnels-case", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -2016,7 +2068,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels-case" + "mapbox:group": "Road network, tunnels-case", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -2095,7 +2149,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels-case" + "mapbox:group": "Road network, tunnels-case", + "microg:gms-type-feature": "road.arterial", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -2193,7 +2249,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., tunnels" + "mapbox:group": "Walking, cycling, etc., tunnels", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -2265,7 +2323,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., tunnels" + "mapbox:group": "Walking, cycling, etc., tunnels", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -2365,7 +2425,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., tunnels" + "mapbox:group": "Walking, cycling, etc., tunnels", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -2458,7 +2520,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., tunnels" + "mapbox:group": "Walking, cycling, etc., tunnels", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -2541,7 +2605,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., tunnels" + "mapbox:group": "Walking, cycling, etc., tunnels", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -2642,7 +2708,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" + "mapbox:group": "Road network, tunnels", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -2721,7 +2789,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" + "mapbox:group": "Road network, tunnels", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -2803,7 +2873,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" + "mapbox:group": "Road network, tunnels", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -2873,7 +2945,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" + "mapbox:group": "Road network, tunnels", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.fill" } }, { @@ -2952,7 +3026,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" + "mapbox:group": "Road network, tunnels", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -3034,7 +3110,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" + "mapbox:group": "Road network, tunnels", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -3095,7 +3173,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" + "mapbox:group": "Road network, tunnels", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -3151,7 +3231,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" + "mapbox:group": "Road network, tunnels", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.fill" } }, { @@ -3221,7 +3303,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" + "mapbox:group": "Road network, tunnels", + "microg:gms-type-feature": "road.arterial", + "microg:gms-type-element": "geometry.fill" } }, { @@ -3312,7 +3396,9 @@ "paint": {}, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" + "mapbox:group": "Road network, tunnels", + "microg:gms-type-feature": "road", + "microg:gms-type-element": "labels.icon" } }, { @@ -3374,7 +3460,9 @@ "paint": {}, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, tunnels" + "mapbox:group": "Road network, tunnels", + "microg:gms-type-feature": "road.arterial", + "microg:gms-type-element": "labels.icon" } }, { @@ -3414,7 +3502,9 @@ }, "metadata": { "mapbox:featureComponent": "terrain", - "mapbox:group": "Terrain, surface" + "mapbox:group": "Terrain, surface", + "microg:gms-type-feature": "landscape.natural.terrain", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -3483,7 +3573,9 @@ }, "metadata": { "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, ferries" + "mapbox:group": "Transit, ferries", + "microg:gms-type-feature": "transit.line", + "microg:gms-type-element": "geometry.fill" } }, { @@ -3531,7 +3623,9 @@ }, "metadata": { "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, ferries" + "mapbox:group": "Transit, ferries", + "microg:gms-type-feature": "transit.line", + "microg:gms-type-element": "geometry.fill" } }, { @@ -3597,7 +3691,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" + "mapbox:group": "Walking, cycling, etc., surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -3676,7 +3772,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" + "mapbox:group": "Walking, cycling, etc., surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -3797,7 +3895,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" + "mapbox:group": "Walking, cycling, etc., surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -3862,7 +3962,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" + "mapbox:group": "Walking, cycling, etc., surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -3948,7 +4050,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" + "mapbox:group": "Walking, cycling, etc., surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -4061,7 +4165,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" + "mapbox:group": "Walking, cycling, etc., surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -4148,7 +4254,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" + "mapbox:group": "Walking, cycling, etc., surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -4291,7 +4399,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" + "mapbox:group": "Walking, cycling, etc., surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -4392,7 +4502,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" + "mapbox:group": "Walking, cycling, etc., surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -4507,7 +4619,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" + "mapbox:group": "Walking, cycling, etc., surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -4529,7 +4643,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., surface" + "mapbox:group": "Walking, cycling, etc., surface", + "microg:gms-type-feature": "poi.attraction", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -4590,7 +4706,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" + "mapbox:group": "Road network, surface", + "microg:gms-type-feature": "road", + "microg:gms-type-element": "geometry.fill" } }, { @@ -4662,7 +4780,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" + "mapbox:group": "Road network, surface", + "microg:gms-type-feature": "road", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -4780,7 +4900,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" + "mapbox:group": "Road network, surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -4889,7 +5011,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" + "mapbox:group": "Road network, surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -4999,7 +5123,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" + "mapbox:group": "Road network, surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -5099,7 +5225,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" + "mapbox:group": "Road network, surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -5194,7 +5322,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" + "mapbox:group": "Road network, surface", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -5303,7 +5433,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" + "mapbox:group": "Road network, surface", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -5439,7 +5571,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" + "mapbox:group": "Road network, surface", + "microg:gms-type-feature": "road.arterial", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -5495,7 +5629,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" + "mapbox:group": "Road network, surface", + "microg:gms-type-feature": "road", + "microg:gms-type-element": "geometry.fill" } }, { @@ -5601,7 +5737,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" + "mapbox:group": "Road network, surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -5696,7 +5834,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" + "mapbox:group": "Road network, surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -5783,7 +5923,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" + "mapbox:group": "Road network, surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -5878,7 +6020,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" + "mapbox:group": "Road network, surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -5982,7 +6126,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" + "mapbox:group": "Road network, surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -6069,7 +6215,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" + "mapbox:group": "Road network, surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -6155,7 +6303,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" + "mapbox:group": "Road network, surface", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -6236,7 +6386,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" + "mapbox:group": "Road network, surface", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.fill" } }, { @@ -6386,7 +6538,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface" + "mapbox:group": "Road network, surface", + "microg:gms-type-feature": "road.arterial", + "microg:gms-type-element": "geometry.fill" } }, { @@ -6455,7 +6609,9 @@ }, "metadata": { "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, surface" + "mapbox:group": "Transit, surface", + "microg:gms-type-feature": "transit.line", + "microg:gms-type-element": "geometry.fill" } }, { @@ -6541,7 +6697,9 @@ }, "metadata": { "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, surface" + "mapbox:group": "Transit, surface", + "microg:gms-type-feature": "transit.line", + "microg:gms-type-element": "geometry.fill" } }, { @@ -6567,7 +6725,9 @@ "paint": {}, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface-icons" + "mapbox:group": "Road network, surface-icons", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "labels.icon" } }, { @@ -6663,7 +6823,9 @@ "paint": {}, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface-icons" + "mapbox:group": "Road network, surface-icons", + "microg:gms-type-feature": "road", + "microg:gms-type-element": "labels.icon" } }, { @@ -6730,7 +6892,9 @@ "paint": {}, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface-icons" + "mapbox:group": "Road network, surface-icons", + "microg:gms-type-feature": "road.arterial", + "microg:gms-type-element": "labels.icon" } }, { @@ -6795,7 +6959,9 @@ "paint": {}, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, surface-icons" + "mapbox:group": "Road network, surface-icons", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "labels.icon" } }, { @@ -6864,7 +7030,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" + "mapbox:group": "Walking, cycling, etc., barriers-bridges", + "microg:gms-type-feature": "landscape.man_made", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -6980,7 +7148,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" + "mapbox:group": "Walking, cycling, etc., barriers-bridges", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -7037,7 +7207,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" + "mapbox:group": "Walking, cycling, etc., barriers-bridges", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -7091,7 +7263,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" + "mapbox:group": "Walking, cycling, etc., barriers-bridges", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -7189,7 +7363,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" + "mapbox:group": "Walking, cycling, etc., barriers-bridges", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -7261,7 +7437,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" + "mapbox:group": "Walking, cycling, etc., barriers-bridges", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -7361,7 +7539,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" + "mapbox:group": "Walking, cycling, etc., barriers-bridges", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -7454,7 +7634,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" + "mapbox:group": "Walking, cycling, etc., barriers-bridges", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -7537,7 +7719,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" + "mapbox:group": "Walking, cycling, etc., barriers-bridges", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -7571,7 +7755,9 @@ "paint": {}, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., barriers-bridges" + "mapbox:group": "Walking, cycling, etc., barriers-bridges", + "microg:gms-type-feature": "road", + "microg:gms-type-element": "labels.icon" } }, { @@ -7664,7 +7850,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -7757,7 +7945,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -7853,7 +8043,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -7937,7 +8129,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -8016,7 +8210,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -8099,7 +8295,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -8182,7 +8380,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.arterial", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -8283,7 +8483,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -8364,7 +8566,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -8437,7 +8641,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -8526,7 +8732,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -8616,7 +8824,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -8698,7 +8908,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -8770,7 +8982,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "geometry.fill" } }, { @@ -8837,7 +9051,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.fill" } }, { @@ -8926,7 +9142,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.arterial", + "microg:gms-type-element": "geometry.fill" } }, { @@ -9009,7 +9227,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -9092,7 +9312,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.arterial", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -9181,7 +9403,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.highway", + "microg:gms-type-element": "geometry.fill" } }, { @@ -9270,7 +9494,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.arterial", + "microg:gms-type-element": "geometry.fill" } }, { @@ -9361,7 +9587,9 @@ "paint": {}, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road", + "microg:gms-type-element": "labels.icon" } }, { @@ -9415,7 +9643,9 @@ "paint": {}, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, bridges" + "mapbox:group": "Road network, bridges", + "microg:gms-type-feature": "road.arterial", + "microg:gms-type-element": "labels.icon" } }, { @@ -9479,7 +9709,9 @@ }, "metadata": { "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, bridges" + "mapbox:group": "Transit, bridges", + "microg:gms-type-feature": "transit.line", + "microg:gms-type-element": "geometry.fill" } }, { @@ -9560,7 +9792,9 @@ }, "metadata": { "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, bridges" + "mapbox:group": "Transit, bridges", + "microg:gms-type-feature": "transit.line", + "microg:gms-type-element": "geometry.fill" } }, { @@ -9600,7 +9834,9 @@ }, "metadata": { "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, elevated" + "mapbox:group": "Transit, elevated", + "microg:gms-type-feature": "transit.line", + "microg:gms-type-element": "geometry.fill" } }, { @@ -9689,7 +9925,9 @@ }, "metadata": { "mapbox:featureComponent": "admin-boundaries", - "mapbox:group": "Administrative boundaries, admin" + "mapbox:group": "Administrative boundaries, admin", + "microg:gms-type-feature": "administrative.province", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -9774,7 +10012,9 @@ }, "metadata": { "mapbox:featureComponent": "admin-boundaries", - "mapbox:group": "Administrative boundaries, admin" + "mapbox:group": "Administrative boundaries, admin", + "microg:gms-type-feature": "administrative.country", + "microg:gms-type-element": "geometry.stroke" } }, { @@ -9870,7 +10110,9 @@ }, "metadata": { "mapbox:featureComponent": "admin-boundaries", - "mapbox:group": "Administrative boundaries, admin" + "mapbox:group": "Administrative boundaries, admin", + "microg:gms-type-feature": "administrative.province", + "microg:gms-type-element": "geometry.fill" } }, { @@ -9961,7 +10203,9 @@ }, "metadata": { "mapbox:featureComponent": "admin-boundaries", - "mapbox:group": "Administrative boundaries, admin" + "mapbox:group": "Administrative boundaries, admin", + "microg:gms-type-feature": "administrative.country", + "microg:gms-type-element": "geometry.fill" } }, { @@ -10050,7 +10294,9 @@ }, "metadata": { "mapbox:featureComponent": "admin-boundaries", - "mapbox:group": "Administrative boundaries, admin" + "mapbox:group": "Administrative boundaries, admin", + "microg:gms-type-feature": "administrative.country", + "microg:gms-type-element": "geometry.fill" } }, { @@ -10116,7 +10362,9 @@ }, "metadata": { "mapbox:featureComponent": "terrain", - "mapbox:group": "Terrain, terrain-labels" + "mapbox:group": "Terrain, terrain-labels", + "microg:gms-type-feature": "landscape.natural.terrain", + "microg:gms-type-element": "labels.text" } }, { @@ -10157,7 +10405,9 @@ }, "metadata": { "mapbox:featureComponent": "buildings", - "mapbox:group": "Buildings, building-labels" + "mapbox:group": "Buildings, building-labels", + "microg:gms-type-feature": "poi", + "microg:gms-type-element": "labels.icon" } }, { @@ -10186,7 +10436,9 @@ }, "metadata": { "mapbox:featureComponent": "buildings", - "mapbox:group": "Buildings, building-labels" + "mapbox:group": "Buildings, building-labels", + "microg:gms-type-feature": "landscape.man_made", + "microg:gms-type-element": "labels.text" } }, { @@ -10234,7 +10486,9 @@ }, "metadata": { "mapbox:featureComponent": "buildings", - "mapbox:group": "Buildings, building-labels" + "mapbox:group": "Buildings, building-labels", + "microg:gms-type-feature": "landscape.man_made", + "microg:gms-type-element": "labels.text" } }, { @@ -10417,7 +10671,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, road-labels" + "mapbox:group": "Road network, road-labels", + "microg:gms-type-feature": "road", + "microg:gms-type-element": "labels.text" } }, { @@ -10485,7 +10741,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, road-labels" + "mapbox:group": "Road network, road-labels", + "microg:gms-type-feature": "road", + "microg:gms-type-element": "labels.text" } }, { @@ -10737,7 +10995,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, road-labels" + "mapbox:group": "Road network, road-labels", + "microg:gms-type-feature": "road", + "microg:gms-type-element": "labels.icon" } }, { @@ -10792,7 +11052,9 @@ }, "metadata": { "mapbox:featureComponent": "road-network", - "mapbox:group": "Road network, road-labels" + "mapbox:group": "Road network, road-labels", + "microg:gms-type-feature": "road", + "microg:gms-type-element": "labels.icon" } }, { @@ -10914,7 +11176,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., walking-cycling-labels" + "mapbox:group": "Walking, cycling, etc., walking-cycling-labels", + "microg:gms-type-feature": "road.local", + "microg:gms-type-element": "labels.text" } }, { @@ -10957,7 +11221,9 @@ }, "metadata": { "mapbox:featureComponent": "walking-cycling", - "mapbox:group": "Walking, cycling, etc., walking-cycling-labels" + "mapbox:group": "Walking, cycling, etc., walking-cycling-labels", + "microg:gms-type-feature": "poi.attraction", + "microg:gms-type-element": "labels.text" } }, { @@ -11040,7 +11306,9 @@ }, "metadata": { "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, ferry-aerialway-labels" + "mapbox:group": "Transit, ferry-aerialway-labels", + "microg:gms-type-feature": "transit.line", + "microg:gms-type-element": "labels.text" } }, { @@ -11141,7 +11409,9 @@ }, "metadata": { "mapbox:featureComponent": "natural-features", - "mapbox:group": "Natural features, natural-labels" + "mapbox:group": "Natural features, natural-labels", + "microg:gms-type-feature": "water", + "microg:gms-type-element": "labels.text" } }, { @@ -11149,7 +11419,9 @@ "type": "symbol", "metadata": { "mapbox:featureComponent": "natural-features", - "mapbox:group": "Natural features, natural-labels" + "mapbox:group": "Natural features, natural-labels", + "microg:gms-type-feature": "landscape.natural.landcover", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "natural_label", @@ -11471,7 +11743,9 @@ }, "metadata": { "mapbox:featureComponent": "natural-features", - "mapbox:group": "Natural features, natural-labels" + "mapbox:group": "Natural features, natural-labels", + "microg:gms-type-feature": "landscape.natural.landcover", + "microg:gms-type-element": "labels.text" } }, { @@ -11479,7 +11753,9 @@ "type": "symbol", "metadata": { "mapbox:featureComponent": "natural-features", - "mapbox:group": "Natural features, natural-labels" + "mapbox:group": "Natural features, natural-labels", + "microg:gms-type-feature": "water", + "microg:gms-type-element": "labels.text" }, "source": "composite", "source-layer": "natural_label", @@ -11780,7 +12056,9 @@ }, "metadata": { "mapbox:featureComponent": "natural-features", - "mapbox:group": "Natural features, natural-labels" + "mapbox:group": "Natural features, natural-labels", + "microg:gms-type-feature": "water", + "microg:gms-type-element": "labels.text" } }, { @@ -12039,7 +12317,9 @@ }, "metadata": { "mapbox:featureComponent": "point-of-interest-labels", - "mapbox:group": "Point of interest labels, poi-labels" + "mapbox:group": "Point of interest labels, poi-labels", + "microg:gms-type-feature": "poi", + "microg:gms-type-element": "labels.text" } }, { @@ -12340,7 +12620,9 @@ }, "metadata": { "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, transit-labels" + "mapbox:group": "Transit, transit-labels", + "microg:gms-type-feature": "transit.station.bus", + "microg:gms-type-element": "labels.text" } }, { @@ -12461,7 +12743,9 @@ }, "metadata": { "mapbox:featureComponent": "transit", - "mapbox:group": "Transit, transit-labels" + "mapbox:group": "Transit, transit-labels", + "microg:gms-type-feature": "transit.station.airport", + "microg:gms-type-element": "labels.text" } }, { @@ -12580,7 +12864,9 @@ }, "metadata": { "mapbox:featureComponent": "place-labels", - "mapbox:group": "Place labels, place-labels" + "mapbox:group": "Place labels, place-labels", + "microg:gms-type-feature": "administrative.neighborhood", + "microg:gms-type-element": "labels.text" } }, { @@ -12855,7 +13141,9 @@ }, "metadata": { "mapbox:featureComponent": "place-labels", - "mapbox:group": "Place labels, place-labels" + "mapbox:group": "Place labels, place-labels", + "microg:gms-type-feature": "administrative.locality", + "microg:gms-type-element": "labels.text" } }, { @@ -13175,7 +13463,9 @@ }, "metadata": { "mapbox:featureComponent": "place-labels", - "mapbox:group": "Place labels, place-labels" + "mapbox:group": "Place labels, place-labels", + "microg:gms-type-feature": "administrative.land_parcel", + "microg:gms-type-element": "labels.text" } }, { @@ -13277,7 +13567,9 @@ }, "metadata": { "mapbox:featureComponent": "place-labels", - "mapbox:group": "Place labels, place-labels" + "mapbox:group": "Place labels, place-labels", + "microg:gms-type-feature": "administrative.province", + "microg:gms-type-element": "labels.text" } }, { @@ -13444,7 +13736,9 @@ }, "metadata": { "mapbox:featureComponent": "place-labels", - "mapbox:group": "Place labels, place-labels" + "mapbox:group": "Place labels, place-labels", + "microg:gms-type-feature": "administrative.country", + "microg:gms-type-element": "labels.text" } }, { @@ -13531,7 +13825,9 @@ }, "metadata": { "mapbox:featureComponent": "place-labels", - "mapbox:group": "Place labels, place-labels" + "mapbox:group": "Place labels, place-labels", + "microg:gms-type-feature": "administrative.country", + "microg:gms-type-element": "labels.text" } } ], -- GitLab From 5c2f1e536c3e761dbfe427610ccf884cd129611b Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Sun, 12 Mar 2023 18:13:39 +0100 Subject: [PATCH 30/38] Parse hsla values --- .../org/microg/gms/maps/mapbox/Styles.kt | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt index d2a1aef44..c8070673b 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt @@ -16,6 +16,7 @@ import org.microg.gms.maps.MapsConstants import org.microg.gms.maps.mapbox.utils.MapContext import java.lang.NumberFormatException import kotlin.math.pow +import kotlin.math.roundToInt const val TAG = "GmsMapStyles" const val KEY_METADATA_FEATURE_TYPE = "microg:gms-type-feature" @@ -130,7 +131,7 @@ class Styler( /** * Returns true if string is likely to contain a color. */ -fun String.isColor() = startsWith("hsl(") || startsWith("#") || startsWith("rgba(") +fun String.isColor() = startsWith("hsl(") || startsWith("hsla(") || startsWith("#") || startsWith("rgba(") /** * Can parse colors in the format '#rrggbb', '#aarrggbb', 'hsl(h, s, l)', and 'rgba(r, g, b, a)' @@ -159,6 +160,26 @@ fun String.parseColor(): Int { Log.w(TAG, "Invalid color `$this`") 0 } + } else if (startsWith("hsla(")) { + val hslArray = replace("hsla(", "").replace(")", "").split(", ") + if (hslArray.size != 4) { + Log.w(TAG, "Invalid color `$this`") + return 0 + } + + return try { + ColorUtils.setAlphaComponent( + ColorUtils.HSLToColor( + floatArrayOf( + hslArray[0].toFloat(), hslArray[1].parseFloat(), hslArray[2].parseFloat() + ) + ), (hslArray[3].parseFloat() * 255).roundToInt() + ) + } catch (e: NumberFormatException) { + Log.w(TAG, "Invalid color `$this`") + 0 + } + } else if (startsWith("rgba(")) { return com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor(this) } -- GitLab From 26c990afa718bd6e907ccaa68a2412bf630d286a Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Mon, 13 Mar 2023 10:28:16 +0100 Subject: [PATCH 31/38] Apply review --- .../org/microg/gms/maps/mapbox/Styles.kt | 138 +++++++++++------- 1 file changed, 85 insertions(+), 53 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt index c8070673b..a6def5d55 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt @@ -22,6 +22,14 @@ const val TAG = "GmsMapStyles" const val KEY_METADATA_FEATURE_TYPE = "microg:gms-type-feature" const val KEY_METADATA_ELEMENT_TYPE = "microg:gms-type-element" +const val SELECTOR_ALL = "all" +const val SELECTOR_ELEMENT_LABEL_TEXT_FILL = "labels.text.fill" +const val SELECTOR_ELEMENT_LABEL_TEXT_OUTLINE = "labels.text.outline" +const val KEY_LAYER_METADATA = "metadata" +const val KEY_LAYER_PAINT = "paint" + + + fun getStyle(context: MapContext, storedMapType: Int, styleOptions: MapStyleOptions?): Style.Builder { // TODO: Serve map style resources locally @@ -48,58 +56,22 @@ fun MapStyleOptions.apply(style: JSONObject) { val layerArray = style.getJSONArray("layers") // Apply operations in order - operations@ for (operation in styleOperations.map { - // Fill in default values for optional fields - NonNullStyleOperation(it.featureType ?: "all", it.elementType ?: "all", it.stylers ?: emptyArray()) - }) { + operations@ for (operation in styleOperations.map { it.toNonNull() }) { // Reverse direction allows removing hidden layers layers@ for (i in layerArray.length() - 1 downTo 0) { - // Test if layer has required fields (metadata and paint) val layer = layerArray.getJSONObject(i) - if (layer.has("paint") && layer.has("metadata") && layer.getJSONObject("metadata") - .let { it.has(KEY_METADATA_FEATURE_TYPE) && it.has(KEY_METADATA_ELEMENT_TYPE) } - ) { - val layerFeatureType = layer.getJSONObject("metadata").getString(KEY_METADATA_FEATURE_TYPE) - val layerElementType = layer.getJSONObject("metadata").getString(KEY_METADATA_ELEMENT_TYPE) - - if (operation.featureType.startsWith("administrative") - && operation.elementType.startsWith("geometry") - ) { - /* Per docs: - * `administrative` selects all administrative areas. Styling affects only - * the labels of administrative areas, not the geographical borders or fill. - */ - continue@operations - } - - // Layer metadata always has the most concrete category; operation applies to all subcategories as well. - if ((layerFeatureType.startsWith(operation.featureType) || operation.featureType == "all") && - (layerElementType.startsWith(operation.elementType) || operation.elementType == "all") - ) { - // Here, operation should be applied to this layer. + if (layer.layerHasRequiredFields()) { + if (operation.isValid() && layer.matchesOperation(operation)) { Log.v(TAG, "applying ${Gson().toJson(operation)} to $layer") - // Interpretation of visibility "simplified": hide labels, display geometry - if ( - // A styler sets the layer to be invisible - operation.stylers.any { it.visibility == "off" } || - // A styler sets the layer to simplified and we are working with a label - (layerElementType.startsWith("labels") && operation.stylers.any { it.visibility == "simplified" }) - ) { - layerArray.remove(i) + if (layer.layerShouldBeRemoved(operation)) { Log.v(TAG, "removing $layer") - continue@layers - } - - operation.stylers.forEach { styler -> - when (operation.elementType) { - "labels.text.fill" -> styler.applyTextFill(layer.getJSONObject("paint")) - "labels.text.outline" -> styler.applyTextOutline(layer.getJSONObject("paint")) - else -> styler.traverseApply(layer.getJSONObject("paint")) - } + layerArray.remove(i) + } else { + layer.applyOperation(operation) } } } @@ -128,6 +100,66 @@ class Styler( val weight: Int? ) +/** + * Constructs a `NonNullStyleOperation` out of the `StyleOperation` while filling null fields with + * default values. + */ +fun StyleOperation.toNonNull() = + NonNullStyleOperation(featureType ?: SELECTOR_ALL, elementType ?: SELECTOR_ALL, stylers ?: emptyArray()) + +/** + * Returns false iff the operation is invalid. + * + * There is one invalid selector that is tested for – per docs: + * "`administrative` selects all administrative areas. Styling affects only + * the labels of administrative areas, not the geographical borders or fill." + */ +fun NonNullStyleOperation.isValid() = !(featureType.startsWith("administrative") && + elementType.startsWith("geometry")) + +/** + * True iff the layer represented by the JSON object should be modified according to the stylers in the operation. + * + * Layer metadata always has the most concrete category, while operation applies to all subcategories as well. + * Therefore, we test if the operation is a substring of the layer's metadata – i.e. the layer's metadata contains + * (more concretely: starts with) the operation's selector. + */ +fun JSONObject.matchesOperation(operation: NonNullStyleOperation) = + (getJSONObject(KEY_LAYER_METADATA).getString(KEY_METADATA_FEATURE_TYPE).startsWith(operation.featureType) + || operation.featureType == "all") + && (getJSONObject(KEY_LAYER_METADATA).getString(KEY_METADATA_ELEMENT_TYPE).startsWith(operation.elementType) + || operation.elementType == "all") + + +/** + * Layer has fields that allow applying style operations. + */ +fun JSONObject.layerHasRequiredFields() = has(KEY_LAYER_PAINT) && has(KEY_LAYER_METADATA) && + getJSONObject(KEY_LAYER_METADATA).let { it.has(KEY_METADATA_FEATURE_TYPE) && it.has(KEY_METADATA_ELEMENT_TYPE) } + +/** + * True iff the layer represented by the JSON object should be removed according to the provided style operation. + * + * Interpretation of visibility "simplified": hide labels, display geometry. + */ +fun JSONObject.layerShouldBeRemoved(operation: NonNullStyleOperation) = + // A styler sets the layer to be invisible + operation.stylers.any { it.visibility == "off" } || + // A styler sets the layer to simplified and we are working with a label + (getJSONObject("metadata").getString(KEY_METADATA_ELEMENT_TYPE) + .startsWith("labels") && operation.stylers.any { it.visibility == "simplified" }) + +/** + * Applies the provided style operation to the layer represented by the JSON object. + */ +fun JSONObject.applyOperation(operation: NonNullStyleOperation) = operation.stylers.forEach { styler -> + when (operation.elementType) { + SELECTOR_ELEMENT_LABEL_TEXT_FILL -> styler.applyTextFill(getJSONObject(KEY_LAYER_PAINT)) + SELECTOR_ELEMENT_LABEL_TEXT_OUTLINE -> styler.applyTextOutline(getJSONObject(KEY_LAYER_PAINT)) + else -> styler.traverse(getJSONObject(KEY_LAYER_PAINT)) + } +} + /** * Returns true if string is likely to contain a color. */ @@ -283,13 +315,13 @@ fun Styler.applyColorChanges(color: Int): Int { /** * Traverse JSON object and replace any color strings according to styler */ -fun Styler.traverseApply(json: JSONObject) { +fun Styler.traverse(json: JSONObject) { // Traverse layer and replace any color strings json.keys().forEach { key -> json.get(key).let { when (it) { - is JSONObject -> traverseApply(it) - is JSONArray -> traverseApply(it) + is JSONObject -> traverse(it) + is JSONArray -> traverse(it) is String -> if (it.isColor()) { json.put(key, applyColorChanges(it.parseColor()).colorToString()) } @@ -301,12 +333,12 @@ fun Styler.traverseApply(json: JSONObject) { /** * Traverse array and replace any color strings according to styler */ -fun Styler.traverseApply(array: JSONArray) { +fun Styler.traverse(array: JSONArray) { for (i in 0 until array.length()) { array.get(i).let { when (it) { - is JSONObject -> traverseApply(it) - is JSONArray -> traverseApply(it) + is JSONObject -> traverse(it) + is JSONArray -> traverse(it) is String -> if (it.isColor()) { array.put(i, applyColorChanges(it.parseColor()).colorToString()) } @@ -317,16 +349,16 @@ fun Styler.traverseApply(array: JSONArray) { fun Styler.applyTextFill(paint: JSONObject) { if (paint.has("text-color")) when (val textColor = paint.get("text-color")) { - is JSONObject -> traverseApply(textColor) - is JSONArray -> traverseApply(textColor) + is JSONObject -> traverse(textColor) + is JSONArray -> traverse(textColor) is String -> paint.put("text-color", applyColorChanges(textColor.parseColor()).colorToString()) } } fun Styler.applyTextOutline(paint: JSONObject) { if (paint.has("text-halo-color")) when (val textOutline = paint.get("text-halo-color")) { - is JSONObject -> traverseApply(textOutline) - is JSONArray -> traverseApply(textOutline) + is JSONObject -> traverse(textOutline) + is JSONArray -> traverse(textOutline) is String -> paint.put("text-halo-color", applyColorChanges(textOutline.parseColor()).colorToString()) } } -- GitLab From 86bb4be972341ec33401de15816f09621a9119f9 Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Mon, 13 Mar 2023 11:14:20 +0100 Subject: [PATCH 32/38] Apply review (2) --- .../src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt index a6def5d55..5cd4f8d47 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Styles.kt @@ -85,9 +85,9 @@ fun MapStyleOptions.apply(style: JSONObject) { } } -class StyleOperation(val featureType: String?, val elementType: String?, val stylers: Array?) +data class StyleOperation(val featureType: String?, val elementType: String?, val stylers: Array?) -class NonNullStyleOperation(val featureType: String, val elementType: String, val stylers: Array) +data class NonNullStyleOperation(val featureType: String, val elementType: String, val stylers: Array) class Styler( val hue: String?, -- GitLab From 3f8f79f55ec5c8abcadf4cc1539e84f48c099b76 Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Mon, 13 Mar 2023 14:30:39 +0000 Subject: [PATCH 33/38] Lite Mode --- .../android/gms/maps/GoogleMapOptions.java | 7 +- .../gms/maps/mapbox/AbstractGoogleMap.kt | 144 ++++ .../maps/mapbox/CameraBoundsWithSizeUpdate.kt | 7 +- .../gms/maps/mapbox/CameraUpdateFactory.kt | 107 ++- .../org/microg/gms/maps/mapbox/GoogleMap.kt | 164 +---- .../microg/gms/maps/mapbox/LiteGoogleMap.kt | 662 ++++++++++++++++++ .../org/microg/gms/maps/mapbox/MapFragment.kt | 45 +- .../org/microg/gms/maps/mapbox/MapView.kt | 30 +- .../org/microg/gms/maps/mapbox/Projection.kt | 46 ++ .../gms/maps/mapbox/model/BitmapDescriptor.kt | 10 + .../mapbox/model/BitmapDescriptorFactory.kt | 11 +- .../microg/gms/maps/mapbox/model/Circle.kt | 199 +++--- .../gms/maps/mapbox/model/InfoWindow.kt | 22 +- .../microg/gms/maps/mapbox/model/Marker.kt | 293 +++++--- .../microg/gms/maps/mapbox/model/Markup.kt | 2 +- .../microg/gms/maps/mapbox/model/Polygon.kt | 184 +++-- .../microg/gms/maps/mapbox/model/Polyline.kt | 100 ++- .../gms/maps/mapbox/utils/typeConverter.kt | 5 + .../src/main/res/drawable/location_dot.xml | 5 + 19 files changed, 1577 insertions(+), 466 deletions(-) create mode 100644 play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/AbstractGoogleMap.kt create mode 100644 play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/LiteGoogleMap.kt create mode 100644 play-services-maps-core-mapbox/src/main/res/drawable/location_dot.xml diff --git a/play-services-api/src/main/java/com/google/android/gms/maps/GoogleMapOptions.java b/play-services-api/src/main/java/com/google/android/gms/maps/GoogleMapOptions.java index 405f31d11..346660534 100644 --- a/play-services-api/src/main/java/com/google/android/gms/maps/GoogleMapOptions.java +++ b/play-services-api/src/main/java/com/google/android/gms/maps/GoogleMapOptions.java @@ -46,7 +46,7 @@ public final class GoogleMapOptions extends AutoSafeParcelable { @SafeParceled(11) private boolean rotateGesturesEnabled = true; @SafeParceled(12) - private boolean liteMode = false; + private int liteMode = 0; @SafeParceled(14) private boolean mapToobarEnabled = false; @SafeParceled(15) @@ -79,8 +79,9 @@ public final class GoogleMapOptions extends AutoSafeParcelable { return boundsForCamera; } - public Boolean getLiteMode() { - return liteMode; + public boolean getLiteMode() { + // Is encoded as `-1` if null, `0` if false, `1` if true. The default is false. + return liteMode == 1; } public Boolean getMapToolbarEnabled() { diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/AbstractGoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/AbstractGoogleMap.kt new file mode 100644 index 000000000..57f09515f --- /dev/null +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/AbstractGoogleMap.kt @@ -0,0 +1,144 @@ +package org.microg.gms.maps.mapbox + +import android.content.Context +import android.location.Location +import android.os.Bundle +import android.util.DisplayMetrics +import android.util.Log +import com.google.android.gms.dynamic.IObjectWrapper +import com.google.android.gms.dynamic.ObjectWrapper +import com.google.android.gms.maps.internal.* +import org.microg.gms.maps.MapsConstants +import org.microg.gms.maps.mapbox.model.AbstractMarker +import org.microg.gms.maps.mapbox.model.DefaultInfoWindowAdapter +import org.microg.gms.maps.mapbox.model.InfoWindow +import org.microg.gms.maps.mapbox.utils.MapContext + +fun getStyleUriByMapType(mapType: Int) = when (mapType) { + MapsConstants.MAP_TYPE_SATELLITE -> "mapbox://styles/microg/cjxgloted25ap1ct4uex7m6hi" + MapsConstants.MAP_TYPE_TERRAIN -> "mapbox://styles/mapbox/outdoors-v12" + MapsConstants.MAP_TYPE_HYBRID -> "mapbox://styles/microg/cjxgloted25ap1ct4uex7m6hi" + //MAP_TYPE_NONE, MAP_TYPE_NORMAL, + else -> "mapbox://styles/microg/cjui4020201oo1fmca7yuwbor" +} + +abstract class AbstractGoogleMap(context: Context) : IGoogleMapDelegate.Stub() { + + internal val mapContext = MapContext(context) + + val dpiFactor: Float + get() = mapContext.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT + + internal var currentInfoWindow: InfoWindow? = null + internal var infoWindowAdapter: IInfoWindowAdapter = DefaultInfoWindowAdapter(mapContext) + internal var onInfoWindowClickListener: IOnInfoWindowClickListener? = null + internal var onInfoWindowLongClickListener: IOnInfoWindowLongClickListener? = null + internal var onInfoWindowCloseListener: IOnInfoWindowCloseListener? = null + + internal var mapClickListener: IOnMapClickListener? = null + internal var mapLongClickListener: IOnMapLongClickListener? = null + internal var markerClickListener: IOnMarkerClickListener? = null + internal var circleClickListener: IOnCircleClickListener? = null + + + internal abstract fun showInfoWindow(marker: AbstractMarker): Boolean + + override fun setOnInfoWindowClickListener(listener: IOnInfoWindowClickListener?) { + onInfoWindowClickListener = listener + } + + override fun setInfoWindowLongClickListener(listener: IOnInfoWindowLongClickListener) { + onInfoWindowLongClickListener = listener + } + + override fun setInfoWindowCloseListener(listener: IOnInfoWindowCloseListener) { + onInfoWindowCloseListener = listener + } + + override fun setInfoWindowAdapter(adapter: IInfoWindowAdapter?) { + infoWindowAdapter = adapter ?: DefaultInfoWindowAdapter(mapContext) + } + + override fun setOnMapClickListener(listener: IOnMapClickListener?) { + mapClickListener = listener + } + + override fun setOnMapLongClickListener(listener: IOnMapLongClickListener?) { + mapLongClickListener = listener + } + + override fun setOnMarkerClickListener(listener: IOnMarkerClickListener?) { + markerClickListener = listener + } + + override fun setCircleClickListener(listener: IOnCircleClickListener?) { + circleClickListener = listener + } + + override fun getMyLocation(): Location? { + Log.d(TAG, "unimplemented Method: getMyLocation") + return null + } + + override fun setLocationSource(locationSource: ILocationSourceDelegate?) { + Log.d(TAG, "unimplemented Method: setLocationSource") + } + + override fun setOnMyLocationChangeListener(listener: IOnMyLocationChangeListener?) { + Log.d(TAG, "unimplemented Method: setOnMyLocationChangeListener") + } + + override fun setOnMyLocationButtonClickListener(listener: IOnMyLocationButtonClickListener?) { + Log.d(TAG, "unimplemented Method: setOnMyLocationButtonClickListener") + } + + override fun getTestingHelper(): IObjectWrapper { + Log.d(TAG, "unimplemented Method: getTestingHelper") + return ObjectWrapper.wrap(null) + } + + override fun isBuildingsEnabled(): Boolean { + Log.d(TAG, "unimplemented Method: isBuildingsEnabled") + return false + } + + override fun setBuildingsEnabled(buildings: Boolean) { + Log.d(TAG, "unimplemented Method: setBuildingsEnabled") + } + + override fun useViewLifecycleWhenInFragment(): Boolean { + Log.d(TAG, "unimplemented Method: useViewLifecycleWhenInFragment") + return false + } + + override fun onEnterAmbient(bundle: Bundle?) { + Log.d(TAG, "unimplemented Method: onEnterAmbient") + } + + override fun onExitAmbient() { + Log.d(TAG, "unimplemented Method: onExitAmbient") + } + + override fun isTrafficEnabled(): Boolean { + Log.d(TAG, "unimplemented Method: isTrafficEnabled") + return false + } + + override fun setTrafficEnabled(traffic: Boolean) { + Log.d(TAG, "unimplemented Method: setTrafficEnabled") + + } + + override fun isIndoorEnabled(): Boolean { + Log.d(TAG, "unimplemented Method: isIndoorEnabled") + return false + } + + override fun setIndoorEnabled(indoor: Boolean) { + Log.d(TAG, "unimplemented Method: setIndoorEnabled") + } + + companion object { + val TAG = "GmsMapAbstract" + } +} \ No newline at end of file diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/CameraBoundsWithSizeUpdate.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/CameraBoundsWithSizeUpdate.kt index c31bf2238..6d97b262f 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/CameraBoundsWithSizeUpdate.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/CameraBoundsWithSizeUpdate.kt @@ -17,16 +17,21 @@ package org.microg.gms.maps.mapbox import android.util.Log +import com.google.android.gms.maps.internal.IGoogleMapDelegate import com.mapbox.mapboxsdk.camera.CameraPosition import com.mapbox.mapboxsdk.camera.CameraUpdate import com.mapbox.mapboxsdk.geometry.LatLngBounds import com.mapbox.mapboxsdk.maps.MapboxMap import java.util.* -internal class CameraBoundsWithSizeUpdate(val bounds: LatLngBounds, val width: Int, val height: Int, val padding: IntArray) : CameraUpdate { +internal class CameraBoundsWithSizeUpdate(val bounds: LatLngBounds, val width: Int, val height: Int, val padding: IntArray) : LiteModeCameraUpdate, CameraUpdate { constructor(bounds: LatLngBounds, width: Int, height: Int, paddingLeft: Int, paddingTop: Int = paddingLeft, paddingRight: Int = paddingLeft, paddingBottom: Int = paddingTop) : this(bounds, width, height, intArrayOf(paddingLeft, paddingTop, paddingRight, paddingBottom)) {} + override fun getLiteModeCameraPosition(map: IGoogleMapDelegate) = null + + override fun getLiteModeCameraBounds() = bounds + override fun getCameraPosition(map: MapboxMap): CameraPosition? { val padding = this.padding.clone() diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/CameraUpdateFactory.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/CameraUpdateFactory.kt index 675429b90..d5cd86d49 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/CameraUpdateFactory.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/CameraUpdateFactory.kt @@ -17,11 +17,13 @@ package org.microg.gms.maps.mapbox import android.graphics.Point +import android.graphics.PointF import android.os.Parcel import android.util.Log import com.google.android.gms.dynamic.IObjectWrapper import com.google.android.gms.dynamic.ObjectWrapper import com.google.android.gms.maps.internal.ICameraUpdateFactoryDelegate +import com.google.android.gms.maps.internal.IGoogleMapDelegate import com.google.android.gms.maps.model.CameraPosition import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.LatLngBounds @@ -32,29 +34,40 @@ import org.microg.gms.maps.mapbox.utils.toMapbox class CameraUpdateFactoryImpl : ICameraUpdateFactoryDelegate.Stub() { - override fun zoomIn(): IObjectWrapper = ObjectWrapper.wrap(CameraUpdateFactory.zoomIn()) - override fun zoomOut(): IObjectWrapper = ObjectWrapper.wrap(CameraUpdateFactory.zoomOut()) + override fun zoomIn(): IObjectWrapper = ObjectWrapper.wrap(ZoomByCameraUpdate(1f)) + override fun zoomOut(): IObjectWrapper = ObjectWrapper.wrap(ZoomByCameraUpdate(-1f)) - override fun zoomTo(zoom: Float): IObjectWrapper = - ObjectWrapper.wrap(CameraUpdateFactory.zoomTo(zoom.toDouble() - 1.0)) + override fun zoomTo(zoom: Float): IObjectWrapper = ObjectWrapper.wrap(ZoomToCameraUpdate(zoom)) override fun zoomBy(zoomDelta: Float): IObjectWrapper = - ObjectWrapper.wrap(CameraUpdateFactory.zoomBy(zoomDelta.toDouble())) + ObjectWrapper.wrap(ZoomByCameraUpdate(zoomDelta)).also { + Log.d(TAG, "zoomBy") + } override fun zoomByWithFocus(zoomDelta: Float, x: Int, y: Int): IObjectWrapper = - ObjectWrapper.wrap(CameraUpdateFactory.zoomBy(zoomDelta.toDouble(), Point(x, y))) + ObjectWrapper.wrap(ZoomByWithFocusCameraUpdate(zoomDelta, x, y)).also { + Log.d(TAG, "zoomByWithFocus") + } override fun newCameraPosition(cameraPosition: CameraPosition): IObjectWrapper = - ObjectWrapper.wrap(CameraUpdateFactory.newCameraPosition(cameraPosition.toMapbox())) + ObjectWrapper.wrap(NewCameraPositionCameraUpdate(cameraPosition)).also { + Log.d(TAG, "newCameraPosition") + } override fun newLatLng(latLng: LatLng): IObjectWrapper = - ObjectWrapper.wrap(CameraUpdateFactory.newLatLng(latLng.toMapbox())) + ObjectWrapper.wrap(NewLatLngCameraUpdate(latLng)).also { + Log.d(TAG, "newLatLng") + } override fun newLatLngZoom(latLng: LatLng, zoom: Float): IObjectWrapper = - ObjectWrapper.wrap(CameraUpdateFactory.newLatLngZoom(latLng.toMapbox(), zoom.toDouble() - 1.0)) + ObjectWrapper.wrap(NewLatLngZoomCameraUpdate(latLng, zoom)).also { + Log.d(TAG, "newLatLngZoom") + } override fun newLatLngBounds(bounds: LatLngBounds, padding: Int): IObjectWrapper = - ObjectWrapper.wrap(CameraUpdateFactory.newLatLngBounds(bounds.toMapbox(), padding)) + ObjectWrapper.wrap(NewLatLngBoundsCameraUpdate(bounds, padding)).also { + Log.d(TAG, "newLatLngBounds") + } override fun scrollBy(x: Float, y: Float): IObjectWrapper { Log.d(TAG, "unimplemented Method: scrollBy") @@ -62,7 +75,9 @@ class CameraUpdateFactoryImpl : ICameraUpdateFactoryDelegate.Stub() { } override fun newLatLngBoundsWithSize(bounds: LatLngBounds, width: Int, height: Int, padding: Int): IObjectWrapper = - ObjectWrapper.wrap(CameraBoundsWithSizeUpdate(bounds.toMapbox(), width, height, padding)) + ObjectWrapper.wrap(CameraBoundsWithSizeUpdate(bounds.toMapbox(), width, height, padding)).also { + Log.d(TAG, "newLatLngBoundsWithSize") + } override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = if (super.onTransact(code, data, reply, flags)) { @@ -71,9 +86,11 @@ class CameraUpdateFactoryImpl : ICameraUpdateFactoryDelegate.Stub() { Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false } - private inner class NoCameraUpdate : CameraUpdate { + private inner class NoCameraUpdate : CameraUpdate, LiteModeCameraUpdate { override fun getCameraPosition(mapboxMap: MapboxMap): com.mapbox.mapboxsdk.camera.CameraPosition? = mapboxMap.cameraPosition + + override fun getLiteModeCameraPosition(map: IGoogleMapDelegate): CameraPosition = map.cameraPosition } companion object { @@ -81,4 +98,70 @@ class CameraUpdateFactoryImpl : ICameraUpdateFactoryDelegate.Stub() { } } +interface LiteModeCameraUpdate { + fun getLiteModeCameraPosition(map: IGoogleMapDelegate): CameraPosition? + + fun getLiteModeCameraBounds(): com.mapbox.mapboxsdk.geometry.LatLngBounds? = null +} + +class ZoomToCameraUpdate(private val zoom: Float) : LiteModeCameraUpdate, CameraUpdate { + override fun getLiteModeCameraPosition(map: IGoogleMapDelegate): CameraPosition = + CameraPosition.Builder(map.cameraPosition).zoom(zoom).build() + + override fun getCameraPosition(mapboxMap: MapboxMap): com.mapbox.mapboxsdk.camera.CameraPosition? = + CameraUpdateFactory.zoomTo(zoom.toDouble() - 1.0).getCameraPosition(mapboxMap) + +} + +class ZoomByCameraUpdate(private val delta: Float) : LiteModeCameraUpdate, CameraUpdate { + override fun getLiteModeCameraPosition(map: IGoogleMapDelegate): CameraPosition = + CameraPosition.Builder(map.cameraPosition).zoom(map.cameraPosition.zoom + delta).build() + + override fun getCameraPosition(mapboxMap: MapboxMap): com.mapbox.mapboxsdk.camera.CameraPosition? = + CameraUpdateFactory.zoomBy(delta.toDouble()).getCameraPosition(mapboxMap) + +} + +class ZoomByWithFocusCameraUpdate(private val delta: Float, private val x: Int, private val y: Int) : LiteModeCameraUpdate, + CameraUpdate { + override fun getLiteModeCameraPosition(map: IGoogleMapDelegate): CameraPosition = + CameraPosition.Builder(map.cameraPosition).zoom(map.cameraPosition.zoom + delta) + .target(map.projection.fromScreenLocation(ObjectWrapper.wrap(PointF(x.toFloat(), y.toFloat())))).build() + + override fun getCameraPosition(mapboxMap: MapboxMap): com.mapbox.mapboxsdk.camera.CameraPosition? = + CameraUpdateFactory.zoomBy(delta.toDouble(), Point(x, y)).getCameraPosition(mapboxMap) +} + +class NewCameraPositionCameraUpdate(private val cameraPosition: CameraPosition) : LiteModeCameraUpdate, CameraUpdate { + override fun getLiteModeCameraPosition(map: IGoogleMapDelegate): CameraPosition = this.cameraPosition + + override fun getCameraPosition(mapboxMap: MapboxMap): com.mapbox.mapboxsdk.camera.CameraPosition = + this.cameraPosition.toMapbox() +} + +class NewLatLngCameraUpdate(private val latLng: LatLng) : LiteModeCameraUpdate, CameraUpdate { + override fun getLiteModeCameraPosition(map: IGoogleMapDelegate): CameraPosition = + CameraPosition.Builder(map.cameraPosition).target(latLng).build() + + override fun getCameraPosition(mapboxMap: MapboxMap): com.mapbox.mapboxsdk.camera.CameraPosition? = + CameraUpdateFactory.newLatLng(latLng.toMapbox()).getCameraPosition(mapboxMap) +} + +class NewLatLngZoomCameraUpdate(private val latLng: LatLng, private val zoom: Float) : LiteModeCameraUpdate, CameraUpdate { + override fun getLiteModeCameraPosition(map: IGoogleMapDelegate): CameraPosition = + CameraPosition.Builder(map.cameraPosition).target(latLng).zoom(zoom).build() + + override fun getCameraPosition(mapboxMap: MapboxMap): com.mapbox.mapboxsdk.camera.CameraPosition? = + CameraUpdateFactory.newLatLngZoom(latLng.toMapbox(), zoom - 1.0).getCameraPosition(mapboxMap) +} + +class NewLatLngBoundsCameraUpdate(private val bounds: LatLngBounds, internal val padding: Int) : LiteModeCameraUpdate, + CameraUpdate { + + override fun getLiteModeCameraPosition(map: IGoogleMapDelegate): CameraPosition? = null + + override fun getLiteModeCameraBounds() = bounds.toMapbox() + override fun getCameraPosition(mapboxMap: MapboxMap): com.mapbox.mapboxsdk.camera.CameraPosition? = + CameraUpdateFactory.newLatLngBounds(bounds.toMapbox(), padding).getCameraPosition(mapboxMap) +} \ No newline at end of file diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index 297dc873a..7e33f0854 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -18,12 +18,9 @@ package org.microg.gms.maps.mapbox import android.annotation.SuppressLint import android.content.Context -import android.graphics.Point -import android.location.Location import android.os.* import androidx.annotation.IdRes import androidx.annotation.Keep -import android.util.DisplayMetrics import android.util.Log import android.view.Gravity import android.view.View @@ -54,14 +51,12 @@ import com.mapbox.mapboxsdk.plugins.annotation.Annotation import com.mapbox.mapboxsdk.style.layers.Property.LINE_CAP_ROUND import com.google.android.gms.dynamic.unwrap import com.mapbox.mapboxsdk.WellKnownTileServer -import org.microg.gms.maps.mapbox.model.DefaultInfoWindowAdapter import org.microg.gms.maps.mapbox.model.InfoWindow import org.microg.gms.maps.mapbox.model.getInfoWindowViewFor import com.mapbox.mapboxsdk.camera.CameraUpdateFactory import com.mapbox.mapboxsdk.maps.OnMapReadyCallback import org.microg.gms.maps.MapsConstants.* import org.microg.gms.maps.mapbox.model.* -import org.microg.gms.maps.mapbox.utils.MapContext import org.microg.gms.maps.mapbox.utils.MultiArchLoader import org.microg.gms.maps.mapbox.utils.toGms import org.microg.gms.maps.mapbox.utils.toMapbox @@ -78,13 +73,11 @@ fun runOnMainLooper(method: () -> Unit) { } } -class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) : IGoogleMapDelegate.Stub() { +class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractGoogleMap(context) { val view: FrameLayout var map: MapboxMap? = null private set - val dpiFactor: Float - get() = context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT private var mapView: MapView? = null private var created = false @@ -99,18 +92,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) private var cameraMoveCanceledListener: IOnCameraMoveCanceledListener? = null private var cameraMoveStartedListener: IOnCameraMoveStartedListener? = null private var cameraIdleListener: IOnCameraIdleListener? = null - private var mapClickListener: IOnMapClickListener? = null - private var mapLongClickListener: IOnMapLongClickListener? = null - private var markerClickListener: IOnMarkerClickListener? = null private var markerDragListener: IOnMarkerDragListener? = null - private var circleClickListener: IOnCircleClickListener? = null - - private var infoWindowAdapter: IInfoWindowAdapter = DefaultInfoWindowAdapter(MapContext(context)) - internal var onInfoWindowClickListener: IOnInfoWindowClickListener? = null - internal var onInfoWindowLongClickListener: IOnInfoWindowLongClickListener? = null - internal var onInfoWindowCloseListener: IOnInfoWindowCloseListener? = null - - var currentInfoWindow: InfoWindow? = null var lineManager: LineManager? = null val pendingLines = mutableSetOf>() @@ -134,7 +116,6 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) var locationEnabled: Boolean = false init { - val mapContext = MapContext(context) BitmapDescriptorFactoryImpl.initialize(mapContext.resources, context.resources) LibraryLoader.setLibraryLoader(MultiArchLoader(mapContext, context)) runOnMainLooper { @@ -290,6 +271,13 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } else { fill.update(fillManager) } + + val lineManager = lineManager + if (lineManager == null) { + pendingLines.addAll(fill.strokes) + } else { + for (stroke in fill.strokes) stroke.update(lineManager) + } } return fill } @@ -373,13 +361,11 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } // TODO: Serve map styles locally - when (storedMapType) { - MAP_TYPE_SATELLITE -> map?.setStyle(Style.Builder().fromUri("mapbox://styles/microg/cjxgloted25ap1ct4uex7m6hi"), update) - MAP_TYPE_TERRAIN -> map?.setStyle(Style.Builder().fromUri("mapbox://styles/mapbox/outdoors-v12"), update) - MAP_TYPE_HYBRID -> map?.setStyle(Style.Builder().fromUri("mapbox://styles/microg/cjxgloted25ap1ct4uex7m6hi"), update) - //MAP_TYPE_NONE, MAP_TYPE_NORMAL, - else -> map?.setStyle(Style.Builder().fromUrl("mapbox://styles/microg/cjui4020201oo1fmca7yuwbor"), update) - } + map?.setStyle( + Style.Builder().fromUri( + getStyleUriByMapType(storedMapType) + ), update + ) map?.let { BitmapDescriptorFactoryImpl.registerMap(it) } @@ -389,26 +375,6 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) it.uiSettings.isLogoEnabled = watermark } - override fun isTrafficEnabled(): Boolean { - Log.d(TAG, "unimplemented Method: isTrafficEnabled") - return false - } - - override fun setTrafficEnabled(traffic: Boolean) { - Log.d(TAG, "unimplemented Method: setTrafficEnabled") - - } - - override fun isIndoorEnabled(): Boolean { - Log.d(TAG, "unimplemented Method: isIndoorEnabled") - return false - } - - override fun setIndoorEnabled(indoor: Boolean) { - Log.d(TAG, "unimplemented Method: setIndoorEnabled") - - } - override fun isMyLocationEnabled(): Boolean { return locationEnabled } @@ -426,19 +392,9 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) Log.w(TAG, e) locationEnabled = false } - Unit } } - override fun getMyLocation(): Location? { - Log.d(TAG, "unimplemented Method: getMyLocation") - return null - } - - override fun setLocationSource(locationSource: ILocationSourceDelegate?) { - Log.d(TAG, "unimplemented Method: setLocationSource") - } - override fun setContentDescription(desc: String?) { mapView?.contentDescription = desc } @@ -449,85 +405,23 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) initializedCallbackList.add(it.getMapReadyCallback()) } - override fun getProjection(): IProjectionDelegate? = map?.projection?.let { + override fun getProjection(): IProjectionDelegate = map?.projection?.let { val experiment = try { map?.cameraPosition?.tilt == 0.0 && map?.cameraPosition?.bearing == 0.0 } catch (e: Exception) { Log.w(TAG, e); false } ProjectionImpl(it, experiment) - } ?: object : IProjectionDelegate.Stub() { // dummy projection if map not initialized - override fun fromScreenLocation(obj: IObjectWrapper?): LatLng { - Log.d(TAG, "Map not initialized when calling getProjection(). Cannot calculate fromScreenLocation") - return LatLng(0.0, 0.0) - } - - override fun toScreenLocation(latLng: LatLng?): IObjectWrapper { - Log.d(TAG, "Map not initialized when calling getProjection(). Cannot calculate toScreenLocation") - return ObjectWrapper.wrap(Point(0, 0)) - } - - override fun getVisibleRegion(): VisibleRegion { - Log.d(TAG, "Map not initialized when calling getProjection(). Cannot calculate getVisibleRegion") - return VisibleRegion(LatLngBounds(LatLng(0.0, 0.0), LatLng(0.0, 0.0))) - } - } + } ?: DummyProjection() override fun setOnCameraChangeListener(listener: IOnCameraChangeListener?) { cameraChangeListener = listener } - override fun setOnMapClickListener(listener: IOnMapClickListener?) { - mapClickListener = listener - } - - override fun setOnMapLongClickListener(listener: IOnMapLongClickListener?) { - mapLongClickListener = listener - } - - override fun setOnMarkerClickListener(listener: IOnMarkerClickListener?) { - markerClickListener = listener - } - override fun setOnMarkerDragListener(listener: IOnMarkerDragListener?) { markerDragListener = listener } - override fun setCircleClickListener(listener: IOnCircleClickListener?) { - circleClickListener = listener - } - - override fun setOnInfoWindowClickListener(listener: IOnInfoWindowClickListener?) { - onInfoWindowClickListener = listener - } - - override fun setInfoWindowLongClickListener(listener: IOnInfoWindowLongClickListener) { - onInfoWindowLongClickListener = listener - } - - override fun setInfoWindowCloseListener(listener: IOnInfoWindowCloseListener) { - onInfoWindowCloseListener = listener - } - - override fun setInfoWindowAdapter(adapter: IInfoWindowAdapter?) { - infoWindowAdapter = adapter ?: DefaultInfoWindowAdapter(MapContext(context)) - } - - override fun getTestingHelper(): IObjectWrapper? { - Log.d(TAG, "unimplemented Method: getTestingHelper") - return null - } - - override fun setOnMyLocationChangeListener(listener: IOnMyLocationChangeListener?) { - Log.d(TAG, "unimplemented Method: setOnMyLocationChangeListener") - - } - - override fun setOnMyLocationButtonClickListener(listener: IOnMyLocationButtonClickListener?) { - Log.d(TAG, "unimplemented Method: setOnMyLocationButtonClickListener") - - } - override fun snapshot(callback: ISnapshotReadyCallback, bitmap: IObjectWrapper?) { val map = map if (map == null) { @@ -556,15 +450,6 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) map.uiSettings.setAttributionMargins(left + ninetyTwoDp, top + fourDp, right + fourDp, bottom + fourDp) } - override fun isBuildingsEnabled(): Boolean { - Log.d(TAG, "unimplemented Method: isBuildingsEnabled") - return false - } - - override fun setBuildingsEnabled(buildings: Boolean) { - Log.d(TAG, "unimplemented Method: setBuildingsEnabled") - } - override fun setOnMapLoadedCallback(callback: IOnMapLoadedCallback?) { if (callback != null) { synchronized(mapLock) { @@ -604,7 +489,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) override fun onCreate(savedInstanceState: Bundle?) { if (!created) { Log.d(TAG, "create"); - val mapView = MapView(MapContext(context)) + val mapView = MapView(mapContext) this.mapView = mapView view.addView(mapView) mapView.onCreate(savedInstanceState?.toMapbox()) @@ -786,7 +671,6 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) pendingMarkers.forEach { it.update(symbolManager) } pendingMarkers.clear() - val mapContext = MapContext(context) map.locationComponent.apply { activateLocationComponent(LocationComponentActivationOptions.builder(mapContext, it) .useSpecializedLocationLayer(true) @@ -813,8 +697,8 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } } - internal fun showInfoWindow(marker: MarkerImpl): Boolean { - infoWindowAdapter.getInfoWindowViewFor(marker, MapContext(context))?.let { infoView -> + override fun showInfoWindow(marker: AbstractMarker): Boolean { + infoWindowAdapter.getInfoWindowViewFor(marker, mapContext)?.let { infoView -> currentInfoWindow?.close() currentInfoWindow = InfoWindow(infoView, this, marker).also { infoWindow -> mapView?.let { infoWindow.open(it) } @@ -824,11 +708,6 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) return false } - override fun useViewLifecycleWhenInFragment(): Boolean { - Log.d(TAG, "unimplemented Method: useViewLifecycleWhenInFragment") - return false - } - override fun onResume() = mapView?.onResume() ?: Unit override fun onPause() = mapView?.onPause() ?: Unit override fun onDestroy() { @@ -872,13 +751,6 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) mapView?.onStop() } - override fun onEnterAmbient(bundle: Bundle?) { - Log.d(TAG, "unimplemented Method: onEnterAmbient") - } - - override fun onExitAmbient() { - Log.d(TAG, "unimplemented Method: onExitAmbient") - } override fun onLowMemory() = mapView?.onLowMemory() ?: Unit override fun onSaveInstanceState(outState: Bundle) { diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/LiteGoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/LiteGoogleMap.kt new file mode 100644 index 000000000..c7499947a --- /dev/null +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/LiteGoogleMap.kt @@ -0,0 +1,662 @@ +package org.microg.gms.maps.mapbox + +import android.Manifest +import android.content.ActivityNotFoundException +import android.content.Context +import android.content.Intent +import android.content.Intent.ACTION_VIEW +import android.content.pm.PackageManager +import android.graphics.PointF +import android.location.Location +import android.net.Uri +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.util.Log +import android.view.View +import android.view.ViewGroup.LayoutParams.MATCH_PARENT +import android.widget.FrameLayout +import android.widget.ImageView +import androidx.annotation.UiThread +import androidx.core.app.ActivityCompat +import com.google.android.gms.dynamic.IObjectWrapper +import com.google.android.gms.dynamic.ObjectWrapper +import com.google.android.gms.dynamic.unwrap +import com.google.android.gms.maps.GoogleMapOptions +import com.google.android.gms.maps.internal.* +import com.google.android.gms.maps.model.* +import com.google.android.gms.maps.model.internal.* +import com.mapbox.mapboxsdk.Mapbox +import com.mapbox.mapboxsdk.WellKnownTileServer +import com.mapbox.mapboxsdk.location.engine.* +import com.mapbox.mapboxsdk.maps.Style +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions +import com.mapbox.mapboxsdk.snapshotter.MapSnapshot +import com.mapbox.mapboxsdk.snapshotter.MapSnapshotter +import com.mapbox.mapboxsdk.style.layers.* +import com.mapbox.mapboxsdk.style.sources.GeoJsonSource +import com.mapbox.turf.TurfConstants.UNIT_METERS +import com.mapbox.turf.TurfMeasurement +import org.microg.gms.maps.mapbox.model.* +import org.microg.gms.maps.mapbox.utils.toGms +import org.microg.gms.maps.mapbox.utils.toMapbox +import org.microg.gms.maps.mapbox.utils.toPoint +import java.util.concurrent.atomic.AtomicBoolean +import kotlin.math.max +import kotlin.math.roundToInt + +// From com.mapbox.mapboxsdk.location.LocationComponent +const val DEFAULT_INTERVAL_MILLIS = 1000L +const val DEFAULT_FASTEST_INTERVAL_MILLIS = 1000L + +class MetaSnapshot( + val snapshot: MapSnapshot, + val cameraPosition: CameraPosition, + val cameraBounds: com.mapbox.mapboxsdk.geometry.LatLngBounds?, + val width: Int, + val height: Int, + val paddingRight: Int, + val paddingTop: Int, + val dpi: Float +) { + fun latLngForPixelFixed(point: PointF) = snapshot.latLngForPixel( + PointF( + point.x / dpi, point.y / dpi + ) + ) +} + +class LiteGoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractGoogleMap(context) { + + internal val view: FrameLayout = FrameLayout(mapContext) + val map: ImageView + + private var created = false + + private var cameraPosition: CameraPosition = options.camera + private var cameraBounds: com.mapbox.mapboxsdk.geometry.LatLngBounds? = null + + private var mapType: Int = options.mapType + + private var currentSnapshotter: MapSnapshotter? = null + + private var lastSnapshot: MetaSnapshot? = null + + private var lastTouchPosition = PointF(0f, 0f) + + private val afterNextDrawCallback = mutableListOf<() -> Unit>() + private var cameraChangeListener: IOnCameraChangeListener? = null + + private var myLocationEnabled = false + private var myLocation: Location? = null + private var locationEngineProvider: LocationEngine = LocationEngineProvider.getBestLocationEngine(mapContext) + private val locationListener = object : LocationEngineCallback { + override fun onSuccess(result: LocationEngineResult?) { + this@LiteGoogleMapImpl.myLocation = result?.lastLocation + postUpdateSnapshot() + } + + override fun onFailure(exception: Exception) { + // same behavior as MapLibre's LocationComponent + Log.e(TAG, "Failed to obtain location update", exception) + } + } + + internal val markers: MutableList = mutableListOf() + internal val polygons: MutableList = mutableListOf() + internal val polylines: MutableList = mutableListOf() + internal val circles: MutableList = mutableListOf() + + private var nextObjectId = 0 + + private var showWatermark = true + + private val updatePosted = AtomicBoolean(false) + + init { + map = ImageView(mapContext).apply { + layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT) + } + + view.addView(map) + + view.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ -> + postUpdateSnapshot() + currentInfoWindow?.update() + } + + BitmapDescriptorFactoryImpl.initialize(mapContext.resources, context.resources) + + // noinspection ClickableViewAccessibility; touch listener only has side effects + map.setOnTouchListener { _, event -> + lastTouchPosition = PointF(event.x + map.paddingLeft, event.y + map.paddingTop) + false + } + + map.setOnClickListener { + + // Test if clickable + if ((view.parent as View?)?.isClickable == false) return@setOnClickListener + + lastSnapshot?.let { meta -> + // Calculate marker hitboxes + for (marker in markers.filter { it.isVisible }) { + + marker.getIconDimensions()?.let { iconDimensions -> // consider only markers with icon + val anchorPoint = meta.snapshot.pixelForLatLng(marker.position.toMapbox()) + + val leftX = anchorPoint.x - marker.anchor[0] * iconDimensions[0] + val topY = anchorPoint.y - marker.anchor[1] * iconDimensions[1] + + if (lastTouchPosition.x >= leftX && lastTouchPosition.x <= leftX + iconDimensions[0] + && lastTouchPosition.y >= topY && lastTouchPosition.y <= topY + iconDimensions[1]) { + // Marker was clicked + if (markerClickListener?.onMarkerClick(marker) == true) { + currentInfoWindow?.close() + currentInfoWindow = null + return@setOnClickListener + } else if (showInfoWindow(marker)) { + return@setOnClickListener + } + } + } + } + + currentInfoWindow?.close() + currentInfoWindow = null + + // Test if circle was clicked + for (circle in circles.filter { it.isVisible && it.isClickable }) { + Log.d(TAG, "last touch ${lastTouchPosition.x}, ${lastTouchPosition.y}, turf ${TurfMeasurement.distance( + circle.center.toPoint(), + meta.latLngForPixelFixed(lastTouchPosition).toPoint(), + UNIT_METERS + )}, radius ${circle.radiusInMeters}") + if (TurfMeasurement.distance( + circle.center.toPoint(), + meta.latLngForPixelFixed(lastTouchPosition).toPoint(), + UNIT_METERS + ) <= circle.radiusInMeters) { + // Circle was clicked + circleClickListener?.onCircleClick(circle) + return@setOnClickListener + } + } + + val clickedPosition = meta.latLngForPixelFixed(lastTouchPosition) + val clickListenerConsumedClick = mapClickListener?.let { + it.onMapClick(clickedPosition.toGms()) + true + } ?: false + + if (clickListenerConsumedClick) return@setOnClickListener + + // else open external map at clicked location + val intent = + Intent(ACTION_VIEW, Uri.parse("geo:${clickedPosition.latitude},${clickedPosition.longitude}")) + + try { + context.startActivity(intent) + } catch (e: ActivityNotFoundException) { + Log.e(TAG, "No compatible mapping application installed. Not handling click.") + } + } + + + } + map.setOnLongClickListener { + mapLongClickListener?.onMapLongClick( + lastSnapshot?.latLngForPixelFixed(lastTouchPosition)?.toGms() ?: LatLng(0.0, 0.0) + ) + mapLongClickListener != null + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + if (!created) { + + Mapbox.getInstance(mapContext, BuildConfig.MAPBOX_KEY, WellKnownTileServer.Mapbox) + + if (savedInstanceState?.containsKey(BUNDLE_CAMERA_POSITION) == true) { + cameraPosition = savedInstanceState.getParcelable(BUNDLE_CAMERA_POSITION)!! + cameraBounds = savedInstanceState.getParcelable(BUNDLE_CAMERA_BOUNDS) + } + + postUpdateSnapshot() + + created = true + } + } + + internal fun postUpdateSnapshot() { + if (updatePosted.compareAndSet(false, true)) { + Handler(Looper.getMainLooper()).post { + updatePosted.set(false) + updateSnapshot() + } + } + } + + @UiThread + private fun updateSnapshot() { + + val cameraPosition = cameraPosition + val dpi = dpiFactor + + val cameraBounds = cameraBounds + + val pixelWidth = map.width + val pixelHeight = map.height + + val styleBuilder = Style.Builder().fromUri(getStyleUriByMapType(mapType)) + + // Add visible polygons (before polylines, so that they are drawn below their strokes) + for (polygon in polygons.filter { it.isVisible }) { + styleBuilder.withLayer( + FillLayer("l${polygon.id}", polygon.id).withProperties( + PropertyFactory.fillColor(polygon.fillColor) + ) + ).withSource( + GeoJsonSource(polygon.id, polygon.annotationOptions.geometry) + ) + } + + // Add visible polylines + for (polyline in polylines.filter { it.isVisible }) { + styleBuilder.withLayer( + LineLayer("l${polyline.id}", polyline.id).withProperties( + PropertyFactory.lineWidth(polyline.width), + PropertyFactory.lineColor(polyline.color), + PropertyFactory.lineCap(Property.LINE_CAP_ROUND) + ) + ).withSource( + GeoJsonSource(polyline.id, polyline.annotationOptions.geometry) + ) + } + + // Add circles + for (circle in circles.filter { it.isVisible }) { + styleBuilder.withLayer(FillLayer("l${circle.id}c", circle.id).withProperties( + PropertyFactory.fillColor(circle.fillColor) + )).withSource(GeoJsonSource(circle.id, circle.annotationOptions.geometry)) + + styleBuilder.withLayer(LineLayer("l${circle.id}s", "${circle.id}s").withProperties( + PropertyFactory.lineWidth(circle.strokeWidth), + PropertyFactory.lineColor(circle.strokeColor), + PropertyFactory.lineCap(Property.LINE_CAP_ROUND) + )).withSource(GeoJsonSource("${circle.id}s", circle.line.annotationOptions.geometry)) + } + + // Add markers + BitmapDescriptorFactoryImpl.put(styleBuilder) + for (marker in markers.filter { it.isVisible }) { + val layer = SymbolLayer("l${marker.id}", marker.id).withProperties( + PropertyFactory.symbolSortKey(marker.zIndex), + PropertyFactory.iconAllowOverlap(true) + ) + marker.icon?.applyTo(layer, marker.anchor, dpi) + styleBuilder.withLayer(layer).withSource( + GeoJsonSource(marker.id, marker.annotationOptions.geometry) + ) + } + + // Add location overlay + if (myLocationEnabled) myLocation?.let { + val indicator = mapContext.getDrawable(R.drawable.location_dot)!! + styleBuilder.withImage("locationIndicator", indicator) + val layer = SymbolLayer("location", "locationSource").withProperties( + PropertyFactory.iconAllowOverlap(true), + PropertyFactory.iconImage("locationIndicator"), + PropertyFactory.iconAnchor(Property.ICON_ANCHOR_TOP_LEFT), + PropertyFactory.iconOffset(arrayOf( + 0.5f * indicator.minimumWidth / dpi, 0.5f * indicator.minimumHeight / dpi + )) + ) + styleBuilder.withLayer(layer).withSource( + GeoJsonSource( + "locationSource", + SymbolOptions().withLatLng(com.mapbox.mapboxsdk.geometry.LatLng(it.latitude, it.longitude)).geometry + ) + ) + } + + val dpiWidth = max(pixelWidth / dpi, 1f).roundToInt() + val dpiHeight = max(pixelHeight / dpi, 1f).roundToInt() + + val snapshotter = MapSnapshotter( + mapContext, MapSnapshotter.Options(dpiWidth, dpiHeight) + .withCameraPosition(this@LiteGoogleMapImpl.cameraPosition.toMapbox()) + .apply { + // if camera bounds are set, overwrite camera position + cameraBounds?.let { withRegion(it) } + } + .withStyleBuilder(styleBuilder) + .withLogo(showWatermark) + .withPixelRatio(dpi) + ) + + synchronized(this) { + this.currentSnapshotter?.cancel() + this.currentSnapshotter = snapshotter + } + + snapshotter.start { + + val cameraPositionChanged = cameraPosition != lastSnapshot?.cameraPosition || (cameraBounds != lastSnapshot?.cameraBounds) + + lastSnapshot = MetaSnapshot( + it, cameraPosition, cameraBounds, pixelWidth, pixelHeight, view.paddingRight, view.paddingTop, dpi + ) + map.setImageBitmap(it.bitmap) + + for (callback in afterNextDrawCallback) callback() + afterNextDrawCallback.clear() + + if (cameraPositionChanged) { + // Notify apps that new projection is now available + cameraChangeListener?.onCameraChange(cameraPosition) + } + + currentInfoWindow?.update() + + synchronized(this) { + this.currentSnapshotter = null + } + + } + } + + fun getMapAsync(callback: IOnMapReadyCallback) { + if (lastSnapshot == null) { + Log.d(TAG, "Invoking callback instantly, as a snapshot is ready") + callback.onMapReady(this) + } else { + Log.d(TAG, "Delay callback invocation, as snapshot has not been rendered yet") + afterNextDrawCallback.add { callback.onMapReady(this) } + } + } + + override fun getCameraPosition(): CameraPosition = cameraPosition + + override fun getMaxZoomLevel() = 21f + + override fun getMinZoomLevel() = 1f + + override fun moveCamera(cameraUpdate: IObjectWrapper?): Unit = cameraUpdate.unwrap()?.let { + cameraPosition = it.getLiteModeCameraPosition(this) ?: cameraPosition + cameraBounds = it.getLiteModeCameraBounds() + + postUpdateSnapshot() + } ?: Unit + + override fun animateCamera(cameraUpdate: IObjectWrapper?) = moveCamera(cameraUpdate) + + override fun animateCameraWithCallback(cameraUpdate: IObjectWrapper?, callback: ICancelableCallback?) { + moveCamera(cameraUpdate) + Log.d(TAG, "animateCameraWithCallback: animation not possible in lite mode, invoking callback instantly") + callback?.onFinish() + } + + override fun animateCameraWithDurationAndCallback( + cameraUpdate: IObjectWrapper?, duration: Int, callback: ICancelableCallback? + ) = animateCameraWithCallback(cameraUpdate, callback) + + override fun stopAnimation() { + Log.d(TAG, "stopAnimation: animation not possible in lite mode") + } + + override fun addPolyline(options: PolylineOptions): IPolylineDelegate { + return LitePolylineImpl(this, "polyline${nextObjectId++}", options).also { polylines.add(it) } + } + + override fun addPolygon(options: PolygonOptions): IPolygonDelegate { + return LitePolygonImpl( + "polygon${nextObjectId++}", options, this + ).also { + polygons.add(it) + polylines.addAll(it.strokes) + postUpdateSnapshot() + } + } + + override fun addMarker(options: MarkerOptions): IMarkerDelegate { + return LiteMarkerImpl("marker${nextObjectId++}", options, this).also { + markers.add(it) + postUpdateSnapshot() + } + } + + override fun addGroundOverlay(options: GroundOverlayOptions?): IGroundOverlayDelegate? { + Log.d(TAG, "addGroundOverlay: not supported in lite mode") + return null + } + + override fun addTileOverlay(options: TileOverlayOptions?): ITileOverlayDelegate? { + Log.d(TAG, "addTileOverlay: not supported in lite mode") + return null + } + + override fun clear() { + polylines.clear() + polygons.clear() + markers.clear() + circles.clear() + postUpdateSnapshot() + } + + override fun getMapType(): Int { + return mapType + } + + override fun setMapType(type: Int) { + mapType = type + postUpdateSnapshot() + } + + override fun isTrafficEnabled(): Boolean { + Log.d(TAG, "isTrafficEnabled: traffic not supported in lite mode") + return false + } + + override fun setTrafficEnabled(traffic: Boolean) { + Log.d(TAG, "setTrafficEnabled: traffic not supported in lite mode") + } + + override fun isIndoorEnabled(): Boolean { + Log.d(TAG, "isIndoorEnabled: indoor not supported in lite mode") + return false + } + + override fun setIndoorEnabled(indoor: Boolean) { + Log.d(TAG, "setIndoorEnabled: indoor not supported in lite mode") + } + + override fun isMyLocationEnabled(): Boolean = myLocationEnabled + + override fun setMyLocationEnabled(myLocation: Boolean) { + if (!myLocationEnabled && myLocation) { + activateLocationProvider() + } else if (myLocationEnabled && !myLocation) { + deactivateLocationProvider() + } // else situation is unchanged + myLocationEnabled = myLocation + } + + private fun activateLocationProvider() { + // Activate only if sufficient permissions + if (ActivityCompat.checkSelfPermission( + mapContext, Manifest.permission.ACCESS_FINE_LOCATION + ) == PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission( + mapContext, Manifest.permission.ACCESS_COARSE_LOCATION + ) == PackageManager.PERMISSION_GRANTED + ) { + locationEngineProvider.requestLocationUpdates( + LocationEngineRequest.Builder(DEFAULT_INTERVAL_MILLIS) + .setFastestInterval(DEFAULT_FASTEST_INTERVAL_MILLIS) + .setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY) + .build(), locationListener, Looper.getMainLooper() + ) + + } else { + Log.w(TAG, "Called setMyLocationEnabled(true) without sufficient permissions. Not showing location.") + } + } + + private fun deactivateLocationProvider() { + locationEngineProvider.removeLocationUpdates(locationListener) + } + + override fun getUiSettings(): IUiSettingsDelegate { + Log.d(TAG, "UI settings have no effect") + return UiSettingsCache() + } + + /** + * Gets a projection snapshot. This means that, in accordance to the docs, the projection object + * will represent the map as it is seen at the point in time that the projection is queried, and + * not updated later on. + */ + override fun getProjection(): IProjectionDelegate = lastSnapshot?.let { LiteProjection(it) } ?: DummyProjection() + + override fun setOnCameraChangeListener(listener: IOnCameraChangeListener?) { + cameraChangeListener = listener + } + + override fun setOnMarkerDragListener(listener: IOnMarkerDragListener?) { + Log.d(TAG, "setOnMarkerDragListener: marker drag is not supported in lite mode") + } + + override fun addCircle(options: CircleOptions): ICircleDelegate { + return LiteCircleImpl(this, "circle${nextObjectId++}", options).also { circles.add(it) } + } + + override fun snapshot(callback: ISnapshotReadyCallback?, bitmap: IObjectWrapper?) { + val lastSnapshot = lastSnapshot + if (lastSnapshot == null) { + afterNextDrawCallback.add { + callback?.onBitmapWrappedReady(ObjectWrapper.wrap(this@LiteGoogleMapImpl.lastSnapshot!!.snapshot.bitmap)) + } + } else { + callback?.onBitmapWrappedReady(ObjectWrapper.wrap(lastSnapshot.snapshot.bitmap)) + } + } + + override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) { + view.setPadding(left, top, right, bottom) + postUpdateSnapshot() + } + + override fun isBuildingsEnabled(): Boolean { + Log.d(TAG, "isBuildingsEnabled: never enabled in light mode") + return false + } + + override fun setBuildingsEnabled(buildings: Boolean) { + Log.d(TAG, "setBuildingsEnabled: cannot be enabled in light mode") + } + + override fun setOnMapLoadedCallback(callback: IOnMapLoadedCallback?) = callback?.let { onMapLoadedCallback -> + if (lastSnapshot != null) { + Log.d(TAG, "Invoking map loaded callback instantly, as a snapshot is ready") + onMapLoadedCallback.onMapLoaded() + } + else { + Log.d(TAG, "Delaying map loaded callback, as snapshot has not been taken yet") + afterNextDrawCallback.add { onMapLoadedCallback.onMapLoaded() } + } + Unit + } ?: Unit + + override fun setWatermarkEnabled(watermark: Boolean) { + showWatermark = watermark + } + + override fun showInfoWindow(marker: AbstractMarker): Boolean { + infoWindowAdapter.getInfoWindowViewFor(marker, mapContext)?.let { infoView -> + currentInfoWindow?.close() + currentInfoWindow = InfoWindow(infoView, this, marker).also { infoWindow -> + infoWindow.open(view) + } + return true + } + return false + } + + override fun onResume() { + if (myLocationEnabled) activateLocationProvider() + } + + override fun onPause() { + synchronized(this) { + currentSnapshotter?.cancel() + currentSnapshotter = null + } + deactivateLocationProvider() + } + + override fun onDestroy() { + view.removeView(map) + } + + override fun onLowMemory() { + } + + override fun onSaveInstanceState(outState: Bundle) { + outState.putParcelable(BUNDLE_CAMERA_POSITION, cameraPosition) + outState.putParcelable(BUNDLE_CAMERA_BOUNDS, cameraBounds) + } + + override fun setContentDescription(desc: String?) { + view.contentDescription = desc + } + + override fun setMapStyle(options: MapStyleOptions?): Boolean { + Log.d(TAG, "setMapStyle options: " + options?.getJson()) + return true + } + + override fun setMinZoomPreference(minZoom: Float) { + Log.d(TAG, "setMinZoomPreference: no interactivity in lite mode") + } + + override fun setMaxZoomPreference(maxZoom: Float) { + Log.d(TAG, "setMaxZoomPreference: no interactivity in lite mode") + } + + override fun resetMinMaxZoomPreference() { + Log.d(TAG, "resetMinMaxZoomPreference: no interactivity in lite mode") + } + + override fun setLatLngBoundsForCameraTarget(bounds: LatLngBounds?) { + Log.d(TAG, "setLatLngBoundsForCameraTarget: no interactivity in lite mode") + } + + override fun setCameraMoveStartedListener(listener: IOnCameraMoveStartedListener?) { + Log.d(TAG, "setCameraMoveStartedListener: event not supported in lite mode") + } + + override fun setCameraMoveListener(listener: IOnCameraMoveListener?) { + Log.d(TAG, "setCameraMoveListener: event not supported in lite mode") + + } + + override fun setCameraMoveCanceledListener(listener: IOnCameraMoveCanceledListener?) { + Log.d(TAG, "setCameraMoveCanceledListener: event not supported in lite mode") + } + + override fun setCameraIdleListener(listener: IOnCameraIdleListener?) { + Log.d(TAG, "setCameraIdleListener: event not supported in lite mode") + } + + override fun onStart() { + } + + override fun onStop() { + } + + companion object { + private val TAG = "GmsMapLite" + private val BUNDLE_CAMERA_POSITION = "camera" + private val BUNDLE_CAMERA_BOUNDS = "cameraBounds" + } +} \ No newline at end of file diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/MapFragment.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/MapFragment.kt index daf4bfb92..69135ab29 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/MapFragment.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/MapFragment.kt @@ -32,12 +32,18 @@ import com.google.android.gms.maps.internal.IOnMapReadyCallback class MapFragmentImpl(private val activity: Activity) : IMapFragmentDelegate.Stub() { - private var map: GoogleMapImpl? = null + private var map: IGoogleMapDelegate? = null private var options: GoogleMapOptions? = null override fun onInflate(activity: IObjectWrapper, options: GoogleMapOptions, savedInstanceState: Bundle?) { this.options = options - map?.options = options + map?.apply { + if (this is GoogleMapImpl) { + this.options = options + } else if (this is LiteGoogleMapImpl) { + this.options = options + } + } } override fun onCreate(savedInstanceState: Bundle?) { @@ -47,7 +53,11 @@ class MapFragmentImpl(private val activity: Activity) : IMapFragmentDelegate.Stu if (options == null) { options = GoogleMapOptions() } - map = GoogleMapImpl(activity, options ?: GoogleMapOptions()) + if (options?.liteMode == true) { + map = LiteGoogleMapImpl(activity, options ?: GoogleMapOptions()) + } else { + map = GoogleMapImpl(activity, options ?: GoogleMapOptions()) + } } override fun onCreateView(layoutInflater: IObjectWrapper, container: IObjectWrapper, savedInstanceState: Bundle?): IObjectWrapper { @@ -56,13 +66,25 @@ class MapFragmentImpl(private val activity: Activity) : IMapFragmentDelegate.Stu } Log.d(TAG, "onCreateView: ${options?.camera?.target}") if (map == null) { - map = GoogleMapImpl(activity, options ?: GoogleMapOptions()) + map = if (options?.liteMode == true) { + LiteGoogleMapImpl(activity, options ?: GoogleMapOptions()) + } else { + GoogleMapImpl(activity, options ?: GoogleMapOptions()) + } + } + map!!.apply { + onCreate(savedInstanceState) + + val view = when (this) { + is GoogleMapImpl -> this.view + is LiteGoogleMapImpl -> this.view + else -> null + } + + val parent = view?.parent as ViewGroup? + parent?.removeView(view) + return ObjectWrapper.wrap(view) } - map!!.onCreate(savedInstanceState) - val view = map!!.view - val parent = view.parent as ViewGroup? - parent?.removeView(view) - return ObjectWrapper.wrap(view) } override fun getMap(): IGoogleMapDelegate? = map @@ -74,7 +96,10 @@ class MapFragmentImpl(private val activity: Activity) : IMapFragmentDelegate.Stu override fun onPause() = map?.onPause() ?: Unit override fun onLowMemory() = map?.onLowMemory() ?: Unit override fun isReady(): Boolean = this.map != null - override fun getMapAsync(callback: IOnMapReadyCallback) = map?.getMapAsync(callback) ?: Unit + override fun getMapAsync(callback: IOnMapReadyCallback) = map?.let { + if (it is GoogleMapImpl) it.getMapAsync(callback) + else if (it is LiteGoogleMapImpl) it.getMapAsync(callback) + } ?: Unit override fun onDestroyView() { map?.onDestroy() diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/MapView.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/MapView.kt index bef3cd83c..4ce82b13e 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/MapView.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/MapView.kt @@ -30,12 +30,17 @@ import com.google.android.gms.maps.internal.IOnMapReadyCallback class MapViewImpl(private val context: Context, options: GoogleMapOptions?) : IMapViewDelegate.Stub() { private val options: GoogleMapOptions = options ?: GoogleMapOptions() - private var map: GoogleMapImpl? = null + private var map: IGoogleMapDelegate? = null override fun onCreate(savedInstanceState: Bundle?) { Log.d(TAG, "onCreate: ${options?.camera?.target}") - map = GoogleMapImpl(context, options) - map!!.onCreate(savedInstanceState) + map = if (options.liteMode) { + LiteGoogleMapImpl(context, options) + } else { + GoogleMapImpl(context, options) + }.apply { + this.onCreate(savedInstanceState) + } } override fun getMap(): IGoogleMapDelegate? = map @@ -53,8 +58,23 @@ class MapViewImpl(private val context: Context, options: GoogleMapOptions?) : IM override fun onLowMemory() = map?.onLowMemory() ?: Unit override fun onSaveInstanceState(outState: Bundle) = map?.onSaveInstanceState(outState) ?: Unit - override fun getView(): IObjectWrapper = ObjectWrapper.wrap(map?.view) - override fun getMapAsync(callback: IOnMapReadyCallback) = map?.getMapAsync(callback) ?: Unit + override fun getView(): IObjectWrapper = ObjectWrapper.wrap( + map?.let { + when (it) { + is GoogleMapImpl -> it.view + is LiteGoogleMapImpl -> it.view + else -> null + } + } + ) + + override fun getMapAsync(callback: IOnMapReadyCallback) = map?.let { + when (it) { + is GoogleMapImpl -> it.getMapAsync(callback) + is LiteGoogleMapImpl -> it.getMapAsync(callback) + else -> null + } + } ?: Unit override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = if (super.onTransact(code, data, reply, flags)) { diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Projection.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Projection.kt index d4ed42f91..0077c3e88 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Projection.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Projection.kt @@ -26,6 +26,7 @@ import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.VisibleRegion import com.mapbox.mapboxsdk.maps.Projection import com.google.android.gms.dynamic.unwrap +import com.google.android.gms.maps.model.LatLngBounds import org.microg.gms.maps.mapbox.utils.toGms import org.microg.gms.maps.mapbox.utils.toMapbox import kotlin.math.roundToInt @@ -78,3 +79,48 @@ class ProjectionImpl(private val projection: Projection, private val withoutTilt private val TAG = "GmsMapProjection" } } + +class LiteProjection(private val snapshot: MetaSnapshot) : IProjectionDelegate.Stub() { + + private fun fromScreenLocationAfterPadding(point: Point?): LatLng = + point?.let { snapshot.latLngForPixelFixed(PointF(point)).toGms() } ?: LatLng(0.0, 0.0) + + override fun fromScreenLocation(obj: IObjectWrapper?): LatLng = fromScreenLocationAfterPadding(obj.unwrap()?.let { + Point((it.x - snapshot.paddingRight), (it.y - snapshot.paddingRight)) + }) + + override fun toScreenLocation(latLng: LatLng?): IObjectWrapper = + ObjectWrapper.wrap(snapshot.snapshot.pixelForLatLng(latLng?.toMapbox()).let { + Point(it.x.roundToInt() + snapshot.paddingRight, it.y.roundToInt() + snapshot.paddingTop) + }) + + override fun getVisibleRegion(): VisibleRegion { + val nearLeft = fromScreenLocationAfterPadding(Point(0, snapshot.height)) + val nearRight = fromScreenLocationAfterPadding(Point(snapshot.width, snapshot.height)) + val farLeft = fromScreenLocationAfterPadding(Point(0, 0)) + val farRight = fromScreenLocationAfterPadding(Point(snapshot.width, 0)) + + return VisibleRegion(nearLeft, nearRight, farLeft, farRight, LatLngBounds(nearLeft, farRight)) + } +} + +class DummyProjection : IProjectionDelegate.Stub() { + override fun fromScreenLocation(obj: IObjectWrapper?): LatLng { + Log.d(TAG, "Map not initialized when calling getProjection(). Cannot calculate fromScreenLocation") + return LatLng(0.0, 0.0) + } + + override fun toScreenLocation(latLng: LatLng?): IObjectWrapper { + Log.d(TAG, "Map not initialized when calling getProjection(). Cannot calculate toScreenLocation") + return ObjectWrapper.wrap(Point(0, 0)) + } + + override fun getVisibleRegion(): VisibleRegion { + Log.d(TAG, "Map not initialized when calling getProjection(). Cannot calculate getVisibleRegion") + return VisibleRegion(LatLngBounds(LatLng(0.0, 0.0), LatLng(0.0, 0.0))) + } + + companion object { + private val TAG = "GmsMapDummyProjection" + } +} \ No newline at end of file diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/BitmapDescriptor.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/BitmapDescriptor.kt index f0dc0f882..48b16f754 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/BitmapDescriptor.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/BitmapDescriptor.kt @@ -22,6 +22,8 @@ import android.util.Log import com.mapbox.mapboxsdk.plugins.annotation.Symbol import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions import com.mapbox.mapboxsdk.style.layers.Property.ICON_ANCHOR_TOP_LEFT +import com.mapbox.mapboxsdk.style.layers.PropertyFactory +import com.mapbox.mapboxsdk.style.layers.SymbolLayer import com.mapbox.mapboxsdk.utils.ColorUtils open class BitmapDescriptorImpl(private val id: String, internal val size: FloatArray) { @@ -34,6 +36,14 @@ open class BitmapDescriptorImpl(private val id: String, internal val size: Float symbol.iconOffset = PointF(-anchor[0] * size[0] / dpiFactor, -anchor[1] * size[1] / dpiFactor) symbol.iconImage = id } + + open fun applyTo(symbolLayer: SymbolLayer, anchor: FloatArray, dpiFactor: Float) { + symbolLayer.withProperties( + PropertyFactory.iconAnchor(ICON_ANCHOR_TOP_LEFT), + PropertyFactory.iconOffset(arrayOf(-anchor[0] * size[0] / dpiFactor, -anchor[1] * size[1] / dpiFactor)), + PropertyFactory.iconImage(id) + ) + } } class ColorBitmapDescriptorImpl(id: String, size: FloatArray, val hue: Float) : BitmapDescriptorImpl(id, size) { diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/BitmapDescriptorFactory.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/BitmapDescriptorFactory.kt index f4f517481..465230041 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/BitmapDescriptorFactory.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/BitmapDescriptorFactory.kt @@ -18,14 +18,13 @@ package org.microg.gms.maps.mapbox.model import android.content.res.Resources import android.graphics.* -import android.os.Handler -import android.os.Looper import android.os.Parcel import android.util.Log import com.google.android.gms.dynamic.IObjectWrapper import com.google.android.gms.dynamic.ObjectWrapper import com.google.android.gms.maps.model.internal.IBitmapDescriptorFactoryDelegate import com.mapbox.mapboxsdk.maps.MapboxMap +import com.mapbox.mapboxsdk.maps.Style import org.microg.gms.maps.mapbox.R import org.microg.gms.maps.mapbox.runOnMainLooper @@ -57,6 +56,14 @@ object BitmapDescriptorFactoryImpl : IBitmapDescriptorFactoryDelegate.Stub() { // TODO: cleanup bitmaps? } + fun put(style: Style.Builder) { + synchronized(bitmaps) { + for (bitmap in bitmaps) { + style.withImage(bitmap.key, bitmap.value) + } + } + } + fun bitmapSize(id: String): FloatArray = bitmaps[id]?.let { floatArrayOf(it.width.toFloat(), it.height.toFloat()) } ?: floatArrayOf(0f, 0f) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt index d0aa04dab..bbb6aaab2 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt @@ -28,10 +28,13 @@ import com.mapbox.geojson.Point import com.mapbox.mapboxsdk.plugins.annotation.* import com.mapbox.mapboxsdk.utils.ColorUtils import com.mapbox.turf.TurfConstants +import com.mapbox.turf.TurfConstants.UNIT_METERS import com.mapbox.turf.TurfMeasurement import com.mapbox.turf.TurfMeta import com.mapbox.turf.TurfTransformation import org.microg.gms.maps.mapbox.GoogleMapImpl +import org.microg.gms.maps.mapbox.LiteGoogleMapImpl +import org.microg.gms.maps.mapbox.utils.toPoint import com.google.android.gms.maps.model.CircleOptions as GmsCircleOptions val NORTH_POLE: Point = Point.fromLngLat(0.0, 90.0) @@ -42,15 +45,18 @@ val SOUTH_POLE: Point = Point.fromLngLat(0.0, -90.0) */ const val CIRCLE_POLYGON_STEPS = 256 -class CircleImpl(private val map: GoogleMapImpl, private val id: String, options: GmsCircleOptions) : ICircleDelegate.Stub(), Markup { - private var center: LatLng = options.center - private var radius: Double = options.radius // in meters - private var strokeWidth: Float = options.strokeWidth - private var strokeColor: Int = options.strokeColor - private var fillColor: Int = options.fillColor - private var visible: Boolean = options.isVisible - private var clickable: Boolean = options.isClickable - private var tag: Any? = null +abstract class AbstractCircle( + private val id: String, options: GmsCircleOptions, private val dpiFactor: Function0 +) : ICircleDelegate.Stub() { + + internal var center: LatLng = options.center + internal var radiusInMeters: Double = options.radius // unlike MapLibre's circles, which only work with pixel radii + internal var strokeWidth: Float = options.strokeWidth + internal var strokeColor: Int = options.strokeColor + internal var fillColor: Int = options.fillColor + internal var visible: Boolean = options.isVisible + internal var clickable: Boolean = options.isClickable + internal var tag: Any? = null internal val line: Markup = object : Markup { override var annotation: Line? = null @@ -60,16 +66,14 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options LineString.fromLngLats( makeOutlineLatLngs() ) - ).withLineWidth(strokeWidth / map.dpiFactor) + ).withLineWidth(strokeWidth / dpiFactor()) .withLineColor(ColorUtils.colorToRgbaString(strokeColor)) .withLineOpacity(if (visible) 1f else 0f) - override val removed: Boolean = false + override var removed: Boolean = false } - override var annotation: Fill? = null - override var removed: Boolean = false - override val annotationOptions: FillOptions + val annotationOptions: FillOptions get() = FillOptions() .withGeometry(makePolygon()) @@ -77,23 +81,25 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options .withFillOutlineColor(ColorUtils.colorToRgbaString(strokeColor)) .withFillOpacity(if (visible && !wrapsAroundPoles()) 1f else 0f) - private fun makePolygon() = TurfTransformation.circle( - Point.fromLngLat(center.longitude, center.latitude), radius, CIRCLE_POLYGON_STEPS, TurfConstants.UNIT_METERS + internal abstract fun update() + + internal fun makePolygon() = TurfTransformation.circle( + Point.fromLngLat(center.longitude, center.latitude), radiusInMeters, CIRCLE_POLYGON_STEPS, TurfConstants.UNIT_METERS ) /** - * Google's "map renderer is unable to draw the circle fill if - * the circle encompasses either the North or South pole". + * Google's "map renderer is unable to draw the circle fill if the circle encompasses + * either the North or South pole" (though it does so incorrectly anyway) */ - private fun wrapsAroundPoles() = Point.fromLngLat(center.longitude, center.latitude).let { + internal fun wrapsAroundPoles() = center.toPoint().let { TurfMeasurement.distance( - it, NORTH_POLE - ) * 1000 < radius || TurfMeasurement.distance( - it, SOUTH_POLE - ) * 1000 < radius + it, NORTH_POLE, UNIT_METERS + ) < radiusInMeters || TurfMeasurement.distance( + it, SOUTH_POLE, UNIT_METERS + ) < radiusInMeters } - private fun makeOutlineLatLngs(): MutableList { + internal fun makeOutlineLatLngs(): MutableList { val pointList = TurfMeta.coordAll( makePolygon(), wrapsAroundPoles() ) @@ -101,9 +107,9 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options // We modify our lines such to match the way Mapbox / MapLibre draws them. // This results in a small gap somewhere in the line, but avoids an incorrect horizontal line. - val centerPoint = Point.fromLngLat(center.longitude, center.latitude) + val centerPoint = center.toPoint() - if (!centerPoint.equals(NORTH_POLE) && TurfMeasurement.distance(centerPoint, NORTH_POLE) * 1000 < radius) { + if (!centerPoint.equals(NORTH_POLE) && TurfMeasurement.distance(centerPoint, NORTH_POLE, UNIT_METERS) < radiusInMeters) { // Wraps around North Pole for (i in 0 until pointList.size) { // We want to have the north-most points at the start and end @@ -117,7 +123,7 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options } } - if (!centerPoint.equals(SOUTH_POLE) && TurfMeasurement.distance(centerPoint, SOUTH_POLE) * 1000 < radius) { + if (!centerPoint.equals(SOUTH_POLE) && TurfMeasurement.distance(centerPoint, SOUTH_POLE, UNIT_METERS) < radiusInMeters) { // Wraps around South Pole for (i in 0 until pointList.size) { // We want to have the south-most points at the start and end @@ -135,67 +141,40 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options return pointList } - private fun updateLatLngs() { - val polygon = makePolygon() - - // Extracts points from generated polygon in expected format - annotation?.latLngs = FillOptions().withGeometry(polygon).latLngs - - line.annotation?.latLngs = makeOutlineLatLngs().map { point -> - com.mapbox.mapboxsdk.geometry.LatLng( - point.latitude(), - point.longitude() - ) - } - - if (wrapsAroundPoles()) { - annotation?.fillOpacity = 0f - } - } - - override fun remove() { - removed = true - map.fillManager?.let { update(it) } - } - override fun getId(): String = id override fun setCenter(center: LatLng) { this.center = center - updateLatLngs() - map.fillManager?.let { update(it) } + update() + } override fun getCenter(): LatLng = center override fun setRadius(radius: Double) { - this.radius = radius - updateLatLngs() - map.fillManager?.let { update(it) } + this.radiusInMeters = radius + update() } - override fun getRadius(): Double = radius + override fun getRadius(): Double = radiusInMeters override fun setStrokeWidth(width: Float) { this.strokeWidth = width - line.annotation?.lineWidth = width / map.dpiFactor - map.lineManager?.let { line.update(it) } + update() } override fun getStrokeWidth(): Float = strokeWidth override fun setStrokeColor(color: Int) { this.strokeColor = color - line.annotation?.setLineColor(color) - map.lineManager?.let { line.update(it) } + update() } override fun getStrokeColor(): Int = strokeColor override fun setFillColor(color: Int) { this.fillColor = color - annotation?.setFillColor(color) - map.fillManager?.let { update(it) } + update() } override fun getFillColor(): Int = fillColor @@ -211,8 +190,7 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options override fun setVisible(visible: Boolean) { this.visible = visible - annotation?.fillOpacity = if (visible && !wrapsAroundPoles()) 1f else 0f - map.fillManager?.let { update(it) } + update() } override fun isVisible(): Boolean = visible @@ -229,20 +207,6 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options return clickable } - override fun update(manager: AnnotationManager<*, Fill, FillOptions, *, *, *>) { - synchronized(this) { - val id = annotation?.id - if (removed && id != null) { - map.circles.remove(id) - } - super.update(manager) - val annotation = annotation - if (annotation != null && id == null) { - map.circles[annotation.id] = this - } - } - } - override fun setStrokePattern(pattern: IObjectWrapper?) { Log.d(TAG, "unimplemented method: set stroke pattern") } @@ -274,13 +238,84 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options } override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = - if (super.onTransact(code, data, reply, flags)) { - true - } else { - Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false + if (super.onTransact(code, data, reply, flags)) { + true + } else { + Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false + } + + companion object { + val TAG = "GmsMapAbstractCircle" + } +} + +class CircleImpl(private val map: GoogleMapImpl, private val id: String, options: GmsCircleOptions) : + AbstractCircle(id, options, { map.dpiFactor }), Markup { + + override var annotation: Fill? = null + override var removed: Boolean = false + + override fun update() { + val polygon = makePolygon() + + // Extracts points from generated polygon in expected format + annotation?.let { + it.latLngs = FillOptions().withGeometry(polygon).latLngs + it.setFillColor(fillColor) + it.fillOpacity = if (visible && !wrapsAroundPoles()) 1f else 0f + } + + line.annotation?.let { + it.latLngs = makeOutlineLatLngs().map { point -> + com.mapbox.mapboxsdk.geometry.LatLng( + point.latitude(), + point.longitude() + ) } + it.lineWidth = strokeWidth / map.dpiFactor + it.setLineColor(strokeColor) + } + + map.fillManager?.let { update(it) } + map.lineManager?.let { line.update(it) } + } + + override fun remove() { + removed = true + line.removed = true + map.fillManager?.let { update(it) } + map.lineManager?.let { line.update(it) } + } + + + override fun update(manager: AnnotationManager<*, Fill, FillOptions, *, *, *>) { + synchronized(this) { + val id = annotation?.id + if (removed && id != null) { + map.circles.remove(id) + } + super.update(manager) + val annotation = annotation + if (annotation != null && id == null) { + map.circles[annotation.id] = this + } + } + } + companion object { val TAG = "GmsMapCircle" } +} + +class LiteCircleImpl(private val map: LiteGoogleMapImpl, id: String, options: GmsCircleOptions) : + AbstractCircle(id, options, { map.dpiFactor }) { + override fun update() { + map.postUpdateSnapshot() + } + + override fun remove() { + map.circles.remove(this) + } + } \ No newline at end of file diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt index c5f00abbd..91b41f117 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt @@ -1,5 +1,6 @@ package org.microg.gms.maps.mapbox.model +import android.graphics.Point import android.graphics.PointF import android.view.LayoutInflater import android.view.View @@ -13,7 +14,7 @@ import com.google.android.gms.dynamic.unwrap import com.google.android.gms.maps.internal.IInfoWindowAdapter import com.google.android.gms.maps.model.internal.IMarkerDelegate import com.mapbox.android.gestures.Utils -import com.mapbox.mapboxsdk.maps.MapView +import org.microg.gms.maps.mapbox.AbstractGoogleMap import org.microg.gms.maps.mapbox.GoogleMapImpl import org.microg.gms.maps.mapbox.R import org.microg.gms.maps.mapbox.utils.MapContext @@ -60,7 +61,7 @@ fun IInfoWindowAdapter.getInfoWindowViewFor(marker: IMarkerDelegate, mapContext: } class InfoWindow internal constructor( - private val view: View, private val map: GoogleMapImpl, internal val marker: MarkerImpl + private val view: View, private val map: AbstractGoogleMap, internal val marker: AbstractMarker ) { private var coordinates: PointF = PointF(0f, 0f) var isVisible = false @@ -75,7 +76,7 @@ class InfoWindow internal constructor( } } - fun open(mapView: MapView) { + fun open(mapView: FrameLayout) { val layoutParams: FrameLayout.LayoutParams = FrameLayout.LayoutParams( FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT ) @@ -108,8 +109,15 @@ class InfoWindow internal constructor( * Updates the position of the displayed view. */ fun update() { - map.map?.projection?.toScreenLocation(marker.position.toMapbox())?.let { - coordinates = it + + if (map is GoogleMapImpl) { + map.map?.projection?.toScreenLocation(marker.position.toMapbox())?.let { + coordinates = it + } + } else { + map.projection.toScreenLocation(marker.position)?.let { + coordinates = PointF(it.unwrap()!!) + } } val iconDimensions = marker.getIconDimensions() @@ -117,9 +125,9 @@ class InfoWindow internal constructor( val height = iconDimensions?.get(1) ?: 0f view.x = - coordinates.x - view.measuredWidth / 2f + sin(Math.toRadians(marker.rotation.toDouble())).toFloat() * width * marker.getInfoWindowAnchor()[0] + coordinates.x - view.measuredWidth / 2f + sin(Math.toRadians(marker.rotation.toDouble())).toFloat() * width * marker.infoWindowAnchor[0] view.y = coordinates.y - view.measuredHeight - max( - height * cos(Math.toRadians(marker.rotation.toDouble())).toFloat() * marker.getInfoWindowAnchor()[1], 0f + height * cos(Math.toRadians(marker.rotation.toDouble())).toFloat() * marker.infoWindowAnchor[1], 0f ) } } diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt index 0d11c4c12..a1423b6ca 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt @@ -27,45 +27,167 @@ import com.mapbox.mapboxsdk.plugins.annotation.AnnotationManager import com.mapbox.mapboxsdk.plugins.annotation.Symbol import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions import com.google.android.gms.dynamic.unwrap +import org.microg.gms.maps.mapbox.AbstractGoogleMap import org.microg.gms.maps.mapbox.GoogleMapImpl +import org.microg.gms.maps.mapbox.LiteGoogleMapImpl import org.microg.gms.maps.mapbox.utils.toMapbox -class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options: MarkerOptions) : IMarkerDelegate.Stub(), Markup { - private var position: LatLng = options.position - private var visible: Boolean = options.isVisible - private var rotation: Float = options.rotation - private var anchor: FloatArray = floatArrayOf(options.anchorU, options.anchorV) - private var infoWindowAnchor: FloatArray? = null - private var icon: BitmapDescriptorImpl? = options.icon?.remoteObject.unwrap() - private var alpha: Float = options.alpha - private var title: String? = options.title - private var snippet: String? = options.snippet - private var zIndex: Float = options.zIndex - private var draggable: Boolean = options.isDraggable - private var tag: IObjectWrapper? = null - - private var infoWindowShown = false - - override var annotation: Symbol? = null - override var removed: Boolean = false - override val annotationOptions: SymbolOptions +abstract class AbstractMarker( + private val id: String, options: MarkerOptions, private val map: AbstractGoogleMap +) : IMarkerDelegate.Stub() { + + internal var position: LatLng = options.position + internal var visible: Boolean = options.isVisible + internal var anchor: FloatArray = floatArrayOf(options.anchorU, options.anchorV) + internal var infoWindowAnchor: FloatArray = floatArrayOf(0.5f, 1f) + internal var icon: BitmapDescriptorImpl? = options.icon?.remoteObject.unwrap() + internal var alpha: Float = options.alpha + internal var title: String? = options.title + internal var snippet: String? = options.snippet + internal var zIndex: Float = options.zIndex + internal var tag: IObjectWrapper? = null + internal open var draggable = false + + val annotationOptions: SymbolOptions get() { val symbolOptions = SymbolOptions() - .withIconOpacity(if (visible) alpha else 0f) - .withIconRotate(rotation) - .withSymbolSortKey(zIndex) - .withDraggable(draggable) + .withIconOpacity(if (visible) alpha else 0f) + .withIconRotate(rotation) + .withSymbolSortKey(zIndex) + .withDraggable(draggable) position.let { symbolOptions.withLatLng(it.toMapbox()) } icon?.applyTo(symbolOptions, anchor, map.dpiFactor) return symbolOptions } + internal abstract fun update() + + override fun getId(): String = id + + override fun setPosition(position: LatLng?) { + this.position = position ?: return + update() + } + + override fun getPosition(): LatLng = position + + override fun setIcon(obj: IObjectWrapper?) { + obj.unwrap()?.let { icon -> + this.icon = icon + update() + } + } + + override fun setVisible(visible: Boolean) { + this.visible = visible + update() + } + + override fun setTitle(title: String?) { + this.title = title + update() + } + + override fun getTitle(): String? = title + + override fun getSnippet(): String? = snippet + + override fun isVisible(): Boolean = visible + + override fun setAnchor(x: Float, y: Float) { + anchor = floatArrayOf(x, y) + update() + } + + override fun setAlpha(alpha: Float) { + this.alpha = alpha + update() + } + + override fun getAlpha(): Float = alpha + + override fun setZIndex(zIndex: Float) { + this.zIndex = zIndex + update() + } + + override fun getZIndex(): Float = zIndex + + fun getIconDimensions(): FloatArray? { + return icon?.size + } + + override fun showInfoWindow() { + if (isInfoWindowShown) { + // Per docs, don't call `onWindowClose` if info window is re-opened programmatically + map.currentInfoWindow?.close(silent = true) + } + map.showInfoWindow(this) + } + + override fun hideInfoWindow() { + if (isInfoWindowShown) { + map.currentInfoWindow?.close() + map.currentInfoWindow = null + } + } + + override fun isInfoWindowShown(): Boolean { + return map.currentInfoWindow?.marker == this + } + + override fun setTag(obj: IObjectWrapper?) { + this.tag = obj + } + + override fun getTag(): IObjectWrapper? = tag ?: ObjectWrapper.wrap(null) + + override fun setSnippet(snippet: String?) { + this.snippet = snippet + } + + override fun equalsRemote(other: IMarkerDelegate?): Boolean = equals(other) + + override fun hashCodeRemote(): Int = hashCode() + + override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = + if (super.onTransact(code, data, reply, flags)) { + true + } else { + Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false + } + + companion object { + private val TAG = "GmsMapAbstractMarker" + } +} + +class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options: MarkerOptions) : + AbstractMarker(id, options, map), Markup { + + internal var rotation: Float = options.rotation + override var draggable: Boolean = options.isDraggable + + override var annotation: Symbol? = null + override var removed: Boolean = false + override fun remove() { removed = true map.symbolManager?.let { update(it) } } + override fun update() { + annotation?.let { + it.latLng = position.toMapbox() + it.isDraggable = draggable + it.iconOpacity = if (visible) alpha else 0f + it.symbolSortKey = zIndex + icon?.applyTo(it, anchor, map.dpiFactor) + } + map.symbolManager?.let { update(it) } + } + override fun update(manager: AnnotationManager<*, Symbol, SymbolOptions, *, *, *>) { synchronized(this) { val id = annotation?.id @@ -80,12 +202,8 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options } } - override fun getId(): String = id - override fun setPosition(position: LatLng?) { - this.position = position ?: return - annotation?.latLng = position.toMapbox() - map.symbolManager?.let { update(it) } + super.setPosition(position) map.currentInfoWindow?.update() } @@ -98,69 +216,33 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options map.currentInfoWindow?.update() } - override fun getPosition(): LatLng = position - override fun setTitle(title: String?) { - this.title = title + super.setTitle(title) map.currentInfoWindow?.let { if (it.marker == this) it.close() } } - override fun getTitle(): String? = title - override fun setSnippet(snippet: String?) { - this.snippet = snippet + super.setSnippet(snippet) map.currentInfoWindow?.let { if (it.marker == this) it.close() } } - override fun getSnippet(): String? = snippet - override fun setDraggable(draggable: Boolean) { this.draggable = draggable - annotation?.isDraggable = draggable map.symbolManager?.let { update(it) } } override fun isDraggable(): Boolean = draggable - override fun showInfoWindow() { - if (isInfoWindowShown) { - // Per docs, don't call `onWindowClose` if info window is re-opened programmatically - map.currentInfoWindow?.close(silent = true) - } - map.showInfoWindow(this) - } - - override fun hideInfoWindow() { - if (isInfoWindowShown) { - map.currentInfoWindow?.close() - map.currentInfoWindow = null - } - } - - override fun isInfoWindowShown(): Boolean { - return map.currentInfoWindow?.marker == this - } - - override fun setVisible(visible: Boolean) { - this.visible = visible - annotation?.iconOpacity = if (visible) alpha else 0f - map.symbolManager?.let { update(it) } - } - - override fun isVisible(): Boolean = visible - override fun equals(other: Any?): Boolean { if (this === other) return true if (other is IMarkerDelegate) return other.id == id return false } - override fun equalsRemote(other: IMarkerDelegate?): Boolean = equals(other) - override fun hashCode(): Int { return id.hashCode() } @@ -169,23 +251,9 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options return "$id ($title)" } - override fun hashCodeRemote(): Int = hashCode() - - override fun setIcon(obj: IObjectWrapper?) { - obj.unwrap()?.let { icon -> - this.icon = icon - annotation?.let { icon.applyTo(it, anchor, map.dpiFactor) } - } - map.symbolManager?.let { update(it) } - } - override fun setAnchor(x: Float, y: Float) { - anchor = floatArrayOf(x, y) - annotation?.let { icon?.applyTo(it, anchor, map.dpiFactor) } - map.symbolManager?.let { update(it) } - if (infoWindowAnchor == null) { - map.currentInfoWindow?.update() - } + super.setAnchor(x, y) + map.currentInfoWindow?.update() } override fun setFlat(flat: Boolean) { @@ -211,42 +279,55 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options map.currentInfoWindow?.update() } - internal fun getInfoWindowAnchor() = infoWindowAnchor ?: floatArrayOf(0.5f, 1f) + companion object { + private val TAG = "GmsMapMarker" + } +} - override fun setAlpha(alpha: Float) { - this.alpha = alpha - annotation?.iconOpacity = if (visible) alpha else 0f - map.symbolManager?.let { update(it) } +class LiteMarkerImpl(id: String, options: MarkerOptions, private val map: LiteGoogleMapImpl) : + AbstractMarker(id, options, map) { + override fun remove() { + map.markers.remove(this) + map.postUpdateSnapshot() } - override fun getAlpha(): Float = alpha + override fun update() { + map.postUpdateSnapshot() + } - override fun setZIndex(zIndex: Float) { - this.zIndex = zIndex - annotation?.symbolSortKey = zIndex - map.symbolManager?.let { update(it) } + override fun setDraggable(drag: Boolean) { + Log.d(TAG, "setDraggable: not available in lite mode") } - override fun getZIndex(): Float = zIndex + override fun isDraggable(): Boolean { + Log.d(TAG, "isDraggable: markers are never draggable in lite mode") + return false + } - override fun setTag(obj: IObjectWrapper?) { - this.tag = obj + override fun setFlat(flat: Boolean) { + Log.d(TAG, "setFlat: not available in lite mode") } - override fun getTag(): IObjectWrapper = tag ?: ObjectWrapper.wrap(null) + override fun isFlat(): Boolean { + Log.d(TAG, "isFlat: markers in lite mode can never be flat") + return false + } - override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = - if (super.onTransact(code, data, reply, flags)) { - true - } else { - Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false - } + override fun setRotation(rotation: Float) { + Log.d(TAG, "setRotation: not available in lite mode") + } - fun getIconDimensions(): FloatArray? { - return icon?.size + override fun getRotation(): Float { + Log.d(TAG, "setRotation: markers in lite mode can never be rotated") + return 0f + } + + override fun setInfoWindowAnchor(x: Float, y: Float) { + infoWindowAnchor = floatArrayOf(x, y) + map.currentInfoWindow?.update() } companion object { - private val TAG = "GmsMapMarker" + private val TAG = "GmsMapMarkerLite" } -} +} \ No newline at end of file diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Markup.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Markup.kt index c737afccd..179c5a0b0 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Markup.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Markup.kt @@ -24,7 +24,7 @@ import com.mapbox.mapboxsdk.plugins.annotation.Options interface Markup, S : Options> { var annotation: T? val annotationOptions: S - val removed: Boolean + var removed: Boolean fun update(manager: AnnotationManager<*, T, S, *, *, *>) { synchronized(this) { diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polygon.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polygon.kt index c0de5468e..f6f700538 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polygon.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polygon.kt @@ -7,68 +7,63 @@ package org.microg.gms.maps.mapbox.model import android.os.Parcel import android.util.Log +import androidx.annotation.CallSuper import com.google.android.gms.dynamic.IObjectWrapper +import com.google.android.gms.dynamic.ObjectWrapper import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.PatternItem import com.google.android.gms.maps.model.PolygonOptions import com.google.android.gms.maps.model.PolylineOptions import com.google.android.gms.maps.model.internal.IPolygonDelegate -import com.mapbox.mapboxsdk.plugins.annotation.AnnotationManager import com.mapbox.mapboxsdk.plugins.annotation.Fill import com.mapbox.mapboxsdk.plugins.annotation.FillOptions import com.mapbox.mapboxsdk.utils.ColorUtils import org.microg.gms.maps.mapbox.GoogleMapImpl +import org.microg.gms.maps.mapbox.LiteGoogleMapImpl import org.microg.gms.maps.mapbox.utils.toMapbox import org.microg.gms.utils.warnOnTransactionIssues -class PolygonImpl(private val map: GoogleMapImpl, private val id: String, options: PolygonOptions) : IPolygonDelegate.Stub(), Markup { - private var points = ArrayList(options.points.orEmpty()) - private var holes: List> = ArrayList(options.holes.map { ArrayList(it.orEmpty()) }) - private var fillColor = options.fillColor - private var strokeColor = options.strokeColor - private var strokeWidth = options.strokeWidth - private var strokeJointType = options.strokeJointType - private var strokePattern = ArrayList(options.strokePattern.orEmpty()) - private var visible: Boolean = options.isVisible - private var clickable: Boolean = options.isClickable - private var tag: IObjectWrapper? = null - - private var strokes = (listOf(PolylineImpl(map, "$id-stroke-main", PolylineOptions().color(strokeColor).width(strokeWidth).addAll(points))) - + holes.mapIndexed { idx, it -> PolylineImpl(map, "$id-stroke-hole-$idx", PolylineOptions().color(strokeColor).width(strokeWidth).addAll(it)) }).toMutableList() - - override var annotation: Fill? = null - override var removed: Boolean = false - override val annotationOptions: FillOptions +abstract class AbstractPolygon(private val id: String, options: PolygonOptions) : IPolygonDelegate.Stub() { + internal var points = ArrayList(options.points.orEmpty()) + internal var holes: List> = ArrayList(options.holes.map { ArrayList(it.orEmpty()) }) + internal var fillColor = options.fillColor + internal var strokeColor = options.strokeColor + internal var strokeWidth = options.strokeWidth + internal var strokeJointType = options.strokeJointType + internal var strokePattern = ArrayList(options.strokePattern.orEmpty()) + internal var visible: Boolean = options.isVisible + internal var clickable: Boolean = options.isClickable + internal var tag: IObjectWrapper? = null + + val annotationOptions: FillOptions get() = FillOptions() - .withLatLngs(mutableListOf(points.map { it.toMapbox() }).plus(holes.map { it.map { it.toMapbox() } })) - .withFillColor(ColorUtils.colorToRgbaString(fillColor)) - .withFillOpacity(if (visible) 1f else 0f) + .withLatLngs(mutableListOf(points.map { it.toMapbox() }).plus(holes.map { it.map { it.toMapbox() } })) + .withFillColor(ColorUtils.colorToRgbaString(fillColor)) + .withFillOpacity(if (visible) 1f else 0f) - override fun remove() { - removed = true - map.fillManager?.let { update(it) } - strokes.forEach { it.remove() } - } + internal abstract val strokes: MutableList + + internal abstract fun update() - override fun update(manager: AnnotationManager<*, Fill, FillOptions, *, *, *>) { - super.update(manager) - map.lineManager?.let { lineManager -> strokes.forEach { it.update(lineManager) } } + @CallSuper + override fun remove() { + for (stroke in strokes) stroke.remove() } override fun getId(): String = id override fun setPoints(points: List) { this.points = ArrayList(points) - annotation?.latLngs = mutableListOf(points.map { it.toMapbox() }).plus(holes.map { it.map { it.toMapbox() } }) - map.fillManager?.let { update(it) } - strokes[0].points = points + strokes[0].setPoints(points) + update() } override fun getPoints(): List = points + internal abstract fun addPolyline(id: String, options: PolylineOptions) + override fun setHoles(holes: List?) { this.holes = if (holes == null) emptyList() else ArrayList(holes.mapNotNull { if (it is List<*>) it.mapNotNull { if (it is LatLng) it else null }.let { if (it.isNotEmpty()) it else null } else null }) - annotation?.latLngs = mutableListOf(points.map { it.toMapbox() }).plus(this.holes.map { it.map { it.toMapbox() } }) while (strokes.size > this.holes.size + 1) { val last = strokes.last() last.remove() @@ -77,34 +72,40 @@ class PolygonImpl(private val map: GoogleMapImpl, private val id: String, option strokes.forEachIndexed { idx, it -> if (idx > 0) it.points = this.holes[idx - 1] } if (this.holes.size + 1 > strokes.size) { try { - strokes.addAll(this.holes.subList(strokes.size, this.holes.size - 1).mapIndexed { idx, it -> PolylineImpl(map, "$id-stroke-hole-${strokes.size + idx}", PolylineOptions().color(strokeColor).width(strokeWidth).addAll(it)) }) + this.holes.subList(strokes.size, this.holes.size - 1).mapIndexed { idx, it -> + addPolyline( + "$id-stroke-hole-${strokes.size + idx}", + PolylineOptions().color(strokeColor).width(strokeWidth).addAll(it) + ) + } } catch (e: Exception) { Log.w(TAG, e) } } - map.fillManager?.let { update(it) } } - override fun getHoles(): List = holes + override fun getHoles(): List> = holes + override fun setStrokeWidth(width: Float) { - this.strokeWidth = width - strokes.forEach { it.width = width } + strokeWidth = width + strokes.forEach { it.setWidth(width) } + update() } override fun getStrokeWidth(): Float = strokeWidth override fun setStrokeColor(color: Int) { - this.strokeColor = color - strokes.forEach { it.color = color } + strokeColor = color + strokes.forEach { it.setColor(color) } + update() } override fun getStrokeColor(): Int = strokeColor override fun setFillColor(color: Int) { - this.fillColor = color - annotation?.setFillColor(color) - map.fillManager?.let { update(it) } + fillColor = color + update() } override fun getFillColor(): Int = fillColor @@ -119,9 +120,8 @@ class PolygonImpl(private val map: GoogleMapImpl, private val id: String, option } override fun setVisible(visible: Boolean) { - this.visible = visible - annotation?.fillOpacity = if (visible) 1f else 0f - map.fillManager?.let { update(it) } + isVisible = visible + update() } override fun isVisible(): Boolean = visible @@ -135,22 +135,20 @@ class PolygonImpl(private val map: GoogleMapImpl, private val id: String, option return false } - override fun equalsRemote(other: IPolygonDelegate?): Boolean = equals(other) - - override fun hashCodeRemote(): Int = hashCode() - override fun setClickable(click: Boolean) { clickable = click } override fun setStrokeJointType(type: Int) { strokeJointType = type + update() } override fun getStrokeJointType(): Int = strokeJointType override fun setStrokePattern(items: MutableList?) { strokePattern = ArrayList(items.orEmpty()) + update() } override fun getStrokePattern(): MutableList = strokePattern @@ -159,21 +157,67 @@ class PolygonImpl(private val map: GoogleMapImpl, private val id: String, option tag = obj } - override fun getTag(): IObjectWrapper? = tag + override fun getTag(): IObjectWrapper = tag ?: ObjectWrapper.wrap(null) + + override fun equalsRemote(other: IPolygonDelegate?): Boolean = equals(other) + + override fun hashCodeRemote(): Int = hashCode() override fun hashCode(): Int { return id.hashCode() } + override fun equals(other: Any?): Boolean { + if (other is AbstractPolygon) { + return other.id == id + } + return false + } + override fun toString(): String { return id } - override fun equals(other: Any?): Boolean { - if (other is PolygonImpl) { - return other.id == id + companion object { + private val TAG = "GmsMapAbstractPolygon" + } +} + +class PolygonImpl(private val map: GoogleMapImpl, id: String, options: PolygonOptions) : + AbstractPolygon(id, options), Markup { + + + override val strokes = (listOf( + PolylineImpl( + map, "$id-stroke-main", PolylineOptions().color(strokeColor).width(strokeWidth).addAll(points) + ) + ) + holes.mapIndexed { idx, it -> + PolylineImpl( + map, "$id-stroke-hole-$idx", PolylineOptions().color(strokeColor).width(strokeWidth).addAll(it) + ) + }).toMutableList() + + override var annotation: Fill? = null + override var removed: Boolean = false + + override fun remove() { + removed = true + map.fillManager?.let { update(it) } + super.remove() + } + + override fun update() { + annotation?.let { + it.latLngs = mutableListOf(points.map { it.toMapbox() }).plus(holes.map { it.map { it.toMapbox() } }) + it.setFillColor(fillColor) + it.fillOpacity = if (visible) 1f else 0f + it.latLngs = mutableListOf(points.map { it.toMapbox() }).plus(this.holes.map { it.map { it.toMapbox() } }) } - return false + map.fillManager?.let { update(it) } + } + + override fun addPolyline(id: String, options: PolylineOptions) { + strokes.add(PolylineImpl(map, id, options)) } override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = warnOnTransactionIssues(code, reply, flags) { super.onTransact(code, data, reply, flags) } @@ -182,3 +226,31 @@ class PolygonImpl(private val map: GoogleMapImpl, private val id: String, option private val TAG = "GmsMapPolygon" } } + +class LitePolygonImpl(id: String, options: PolygonOptions, private val map: LiteGoogleMapImpl) : AbstractPolygon(id, options) { + + override val strokes: MutableList = (listOf( + LitePolylineImpl( + map, "$id-stroke-main", PolylineOptions().color(strokeColor).width(strokeWidth).addAll(points) + ) + ) + holes.mapIndexed { idx, it -> + LitePolylineImpl( + map, "$id-stroke-hole-$idx", PolylineOptions().color(strokeColor).width(strokeWidth).addAll(it) + ) + }).toMutableList() + + + override fun remove() { + super.remove() + map.polygons.remove(this) + map.postUpdateSnapshot() + } + + override fun update() { + map.postUpdateSnapshot() + } + + override fun addPolyline(id: String, options: PolylineOptions) { + strokes.add(LitePolylineImpl(map, id, options)) + } +} \ No newline at end of file diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polyline.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polyline.kt index f9a8f91b9..2e16ddb16 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polyline.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polyline.kt @@ -24,51 +24,44 @@ import com.mapbox.mapboxsdk.plugins.annotation.Line import com.mapbox.mapboxsdk.plugins.annotation.LineOptions import com.mapbox.mapboxsdk.utils.ColorUtils import org.microg.gms.maps.mapbox.GoogleMapImpl +import org.microg.gms.maps.mapbox.LiteGoogleMapImpl import org.microg.gms.maps.mapbox.utils.toMapbox import com.google.android.gms.maps.model.PolylineOptions as GmsLineOptions -class PolylineImpl(private val map: GoogleMapImpl, private val id: String, options: GmsLineOptions) : IPolylineDelegate.Stub(), Markup { - private var points = ArrayList(options.points) - private var width = options.width - private var color = options.color - private var visible: Boolean = options.isVisible +abstract class AbstractPolylineImpl(private val id: String, options: GmsLineOptions, private val dpiFactor: Function0) : IPolylineDelegate.Stub() { + internal var points: List = ArrayList(options.points) + internal var width = options.width + internal var color = options.color + internal var visible: Boolean = options.isVisible - override var annotation: Line? = null - override var removed: Boolean = false - override val annotationOptions: LineOptions + val annotationOptions: LineOptions get() = LineOptions() - .withLatLngs(points.map { it.toMapbox() }) - .withLineWidth(width / map.dpiFactor) - .withLineColor(ColorUtils.colorToRgbaString(color)) - .withLineOpacity(if (visible) 1f else 0f) + .withLatLngs(points.map { it.toMapbox() }) + .withLineWidth(width / dpiFactor.invoke()) + .withLineColor(ColorUtils.colorToRgbaString(color)) + .withLineOpacity(if (visible) 1f else 0f) - override fun remove() { - removed = true - map.lineManager?.let { update(it) } - } + internal abstract fun update() override fun getId(): String = id override fun setPoints(points: List) { this.points = ArrayList(points) - annotation?.latLngs = points.map { it.toMapbox() } - map.lineManager?.let { update(it) } + update() } override fun getPoints(): List = points override fun setWidth(width: Float) { this.width = width - annotation?.lineWidth = width / map.dpiFactor - map.lineManager?.let { update(it) } + update() } override fun getWidth(): Float = width override fun setColor(color: Int) { this.color = color - annotation?.setLineColor(color) - map.lineManager?.let { update(it) } + update() } override fun getColor(): Int = color @@ -84,8 +77,7 @@ class PolylineImpl(private val map: GoogleMapImpl, private val id: String, optio override fun setVisible(visible: Boolean) { this.visible = visible - annotation?.lineOpacity = if (visible) 1f else 0f - map.lineManager?.let { update(it) } + update() } override fun isVisible(): Boolean = visible @@ -107,25 +99,63 @@ class PolylineImpl(private val map: GoogleMapImpl, private val id: String, optio return id.hashCode() } - override fun toString(): String { - return id - } - override fun equals(other: Any?): Boolean { - if (other is PolylineImpl) { + if (other is AbstractPolylineImpl) { return other.id == id } return false } + override fun toString(): String { + return id + } + override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = - if (super.onTransact(code, data, reply, flags)) { - true - } else { - Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false - } + if (super.onTransact(code, data, reply, flags)) { + true + } else { + Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false + } + + companion object { + const val TAG = "GmsPolylineAbstract" + } +} + +class PolylineImpl(private val map: GoogleMapImpl, id: String, options: GmsLineOptions) : + AbstractPolylineImpl(id, options, { map.dpiFactor }), Markup { + + override var annotation: Line? = null + override var removed: Boolean = false + + override fun remove() { + removed = true + map.lineManager?.let { update(it) } + } + + override fun update() { + annotation?.apply { + latLngs = points.map { it.toMapbox() } + lineWidth = width / map.dpiFactor + setLineColor(color) + lineOpacity = if (visible) 1f else 0f + } + map.lineManager?.let { update(it) } + } companion object { private val TAG = "GmsMapPolyline" } -} \ No newline at end of file +} + +class LitePolylineImpl(private val map: LiteGoogleMapImpl, id: String, options: GmsLineOptions) : + AbstractPolylineImpl(id, options, { map.dpiFactor }) { + override fun remove() { + map.polylines.remove(this) + map.postUpdateSnapshot() + } + + override fun update() { + map.postUpdateSnapshot() + } +} diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/typeConverter.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/typeConverter.kt index 9664aea6f..aefa0d1cb 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/typeConverter.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/typeConverter.kt @@ -18,6 +18,7 @@ package org.microg.gms.maps.mapbox.utils import android.os.Bundle import com.google.android.gms.maps.internal.ICancelableCallback +import com.mapbox.geojson.Point import com.mapbox.mapboxsdk.camera.CameraPosition import com.mapbox.mapboxsdk.geometry.LatLng import com.mapbox.mapboxsdk.geometry.LatLngBounds @@ -31,6 +32,8 @@ import com.google.android.gms.maps.model.VisibleRegion as GmsVisibleRegion fun GmsLatLng.toMapbox(): LatLng = LatLng(latitude, longitude) +fun GmsLatLng.toPoint() = Point.fromLngLat(latitude, longitude) + fun GmsLatLngBounds.toMapbox(): LatLngBounds = LatLngBounds.from(this.northeast.latitude, this.northeast.longitude, this.southwest.latitude, this.southwest.longitude) @@ -68,6 +71,8 @@ fun Bundle.toMapbox(): Bundle { fun LatLng.toGms(): GmsLatLng = GmsLatLng(latitude, longitude) +fun LatLng.toPoint(): Point = Point.fromLngLat(latitude, longitude) + fun LatLngBounds.toGms(): GmsLatLngBounds = GmsLatLngBounds(southWest.toGms(), northEast.toGms()) fun CameraPosition.toGms(): GmsCameraPosition = diff --git a/play-services-maps-core-mapbox/src/main/res/drawable/location_dot.xml b/play-services-maps-core-mapbox/src/main/res/drawable/location_dot.xml new file mode 100644 index 000000000..af953b62b --- /dev/null +++ b/play-services-maps-core-mapbox/src/main/res/drawable/location_dot.xml @@ -0,0 +1,5 @@ + + + + -- GitLab From 0150ff2e5f250a7b01849478aae86d3fa223547d Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Mon, 13 Mar 2023 17:32:30 +0100 Subject: [PATCH 34/38] Fix builds after merge Custom colors not yet enabled for lite mode maps due to problems --- .../microg/gms/maps/mapbox/LiteGoogleMap.kt | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/LiteGoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/LiteGoogleMap.kt index c7499947a..bdb332539 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/LiteGoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/LiteGoogleMap.kt @@ -37,6 +37,7 @@ import com.mapbox.mapboxsdk.style.layers.* import com.mapbox.mapboxsdk.style.sources.GeoJsonSource import com.mapbox.turf.TurfConstants.UNIT_METERS import com.mapbox.turf.TurfMeasurement +import org.microg.gms.maps.MapsConstants import org.microg.gms.maps.mapbox.model.* import org.microg.gms.maps.mapbox.utils.toGms import org.microg.gms.maps.mapbox.utils.toMapbox @@ -77,6 +78,7 @@ class LiteGoogleMapImpl(context: Context, var options: GoogleMapOptions) : Abstr private var cameraBounds: com.mapbox.mapboxsdk.geometry.LatLngBounds? = null private var mapType: Int = options.mapType + private var mapStyle: MapStyleOptions? = null private var currentSnapshotter: MapSnapshotter? = null @@ -89,7 +91,7 @@ class LiteGoogleMapImpl(context: Context, var options: GoogleMapOptions) : Abstr private var myLocationEnabled = false private var myLocation: Location? = null - private var locationEngineProvider: LocationEngine = LocationEngineProvider.getBestLocationEngine(mapContext) + private var locationEngineProvider: LocationEngine = LocationEngineDefault.getDefaultLocationEngine(mapContext) private val locationListener = object : LocationEngineCallback { override fun onSuccess(result: LocationEngineResult?) { this@LiteGoogleMapImpl.myLocation = result?.lastLocation @@ -249,6 +251,7 @@ class LiteGoogleMapImpl(context: Context, var options: GoogleMapOptions) : Abstr val pixelHeight = map.height val styleBuilder = Style.Builder().fromUri(getStyleUriByMapType(mapType)) + // TODO should be getStyle(mapContext, mapType, mapStyle) // Add visible polygons (before polylines, so that they are drawn below their strokes) for (polygon in polygons.filter { it.isVisible }) { @@ -340,7 +343,7 @@ class LiteGoogleMapImpl(context: Context, var options: GoogleMapOptions) : Abstr this.currentSnapshotter = snapshotter } - snapshotter.start { + snapshotter.start({ val cameraPositionChanged = cameraPosition != lastSnapshot?.cameraPosition || (cameraBounds != lastSnapshot?.cameraBounds) @@ -363,7 +366,7 @@ class LiteGoogleMapImpl(context: Context, var options: GoogleMapOptions) : Abstr this.currentSnapshotter = null } - } + }, null) } fun getMapAsync(callback: IOnMapReadyCallback) { @@ -612,6 +615,8 @@ class LiteGoogleMapImpl(context: Context, var options: GoogleMapOptions) : Abstr override fun setMapStyle(options: MapStyleOptions?): Boolean { Log.d(TAG, "setMapStyle options: " + options?.getJson()) + mapStyle = options + return true } @@ -659,4 +664,13 @@ class LiteGoogleMapImpl(context: Context, var options: GoogleMapOptions) : Abstr private val BUNDLE_CAMERA_POSITION = "camera" private val BUNDLE_CAMERA_BOUNDS = "cameraBounds" } -} \ No newline at end of file +} + +// TODO custom colors +fun getStyleUriByMapType(mapType: Int) = when (mapType) { + MapsConstants.MAP_TYPE_SATELLITE -> "mapbox://styles/microg/cjxgloted25ap1ct4uex7m6hi" + MapsConstants.MAP_TYPE_TERRAIN -> "mapbox://styles/mapbox/outdoors-v12" + MapsConstants.MAP_TYPE_HYBRID -> "mapbox://styles/microg/cjxgloted25ap1ct4uex7m6hi" + //MAP_TYPE_NONE, MAP_TYPE_NORMAL, + else -> "mapbox://styles/microg/cjui4020201oo1fmca7yuwbor" +} -- GitLab From 0e7e84c5e45769d567440ea5dbf1a00cd6eabf93 Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Mon, 13 Mar 2023 17:00:31 +0100 Subject: [PATCH 35/38] Merge branch '913-circles' into epic67-maps --- .../gms/maps/internal/IGoogleMapDelegate.aidl | 7 +- .../internal/ILocationSourceDelegate.aidl | 4 + .../IOnIndoorStateChangeListener.aidl | 6 ++ .../internal/IOnLocationChangeListener.aidl | 7 ++ .../google/android/gms/maps/model/Cap.aidl | 3 + .../google/android/gms/maps/model/Dash.aidl | 3 + .../google/android/gms/maps/model/Dot.aidl | 3 + .../google/android/gms/maps/model/Gap.aidl | 3 + .../android/gms/maps/model/StyleSpan.aidl | 3 + .../maps/model/internal/ICircleDelegate.aidl | 5 +- .../internal/IIndoorBuildingDelegate.aidl | 10 +++ .../model/internal/IIndoorLevelDelegate.aidl | 9 ++ .../maps/model/internal/IPolygonDelegate.aidl | 1 + .../model/internal/IPolylineDelegate.aidl | 49 +++++++---- .../google/android/gms/maps/model/Cap.java | 21 +++++ .../android/gms/maps/model/CircleOptions.java | 25 ++++++ .../android/gms/maps/model/PatternItem.java | 22 ++++- .../gms/maps/model/PolylineOptions.java | 59 ++++++++----- .../android/gms/maps/model/StampStyle.java | 18 ++++ .../android/gms/maps/model/StrokeStyle.java | 23 +++++ .../android/gms/maps/model/StyleSpan.java | 25 ++++++ .../org/microg/gms/maps/mapbox/GoogleMap.kt | 67 +++++++++++++-- .../org/microg/gms/maps/mapbox/Pattern.kt | 83 +++++++++++++++++++ .../microg/gms/maps/mapbox/model/Circle.kt | 30 +++++-- .../microg/gms/maps/mapbox/model/Polygon.kt | 2 + .../microg/gms/maps/mapbox/model/Polyline.kt | 31 +++++++ .../gms/maps/mapbox/utils/MapContext.kt | 4 +- .../gms/maps/vtm/markup/CircleImpl.java | 9 +- .../gms/maps/vtm/markup/PolygonImpl.java | 5 ++ .../gms/maps/vtm/markup/PolylineImpl.java | 43 ++++++++++ 30 files changed, 518 insertions(+), 62 deletions(-) create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnIndoorStateChangeListener.aidl create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnLocationChangeListener.aidl create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/model/Cap.aidl create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/model/Dash.aidl create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/model/Dot.aidl create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/model/Gap.aidl create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/model/StyleSpan.aidl create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IIndoorBuildingDelegate.aidl create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IIndoorLevelDelegate.aidl create mode 100644 play-services-api/src/main/java/com/google/android/gms/maps/model/Cap.java create mode 100644 play-services-api/src/main/java/com/google/android/gms/maps/model/StampStyle.java create mode 100644 play-services-api/src/main/java/com/google/android/gms/maps/model/StrokeStyle.java create mode 100644 play-services-api/src/main/java/com/google/android/gms/maps/model/StyleSpan.java create mode 100644 play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl index bcb27314f..6759dbbd9 100644 --- a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl @@ -34,11 +34,12 @@ import com.google.android.gms.maps.model.MapStyleOptions; import com.google.android.gms.maps.model.PolygonOptions; import com.google.android.gms.maps.model.PolylineOptions; import com.google.android.gms.maps.model.TileOverlayOptions; -import com.google.android.gms.maps.model.internal.IPolylineDelegate; -import com.google.android.gms.maps.model.internal.IPolygonDelegate; -import com.google.android.gms.maps.model.internal.IMarkerDelegate; import com.google.android.gms.maps.model.internal.ICircleDelegate; import com.google.android.gms.maps.model.internal.IGroundOverlayDelegate; +import com.google.android.gms.maps.model.internal.IIndoorBuildingDelegate; +import com.google.android.gms.maps.model.internal.IMarkerDelegate; +import com.google.android.gms.maps.model.internal.IPolygonDelegate; +import com.google.android.gms.maps.model.internal.IPolylineDelegate; import com.google.android.gms.maps.model.internal.ITileOverlayDelegate; interface IGoogleMapDelegate { diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/ILocationSourceDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/ILocationSourceDelegate.aidl index 203ec69f1..3f1ed56fb 100644 --- a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/ILocationSourceDelegate.aidl +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/ILocationSourceDelegate.aidl @@ -1,4 +1,8 @@ package com.google.android.gms.maps.internal; +import com.google.android.gms.maps.internal.IOnLocationChangeListener; + interface ILocationSourceDelegate { + void activate(IOnLocationChangeListener listener) = 0; + void deactivate() = 1; } diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnIndoorStateChangeListener.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnIndoorStateChangeListener.aidl new file mode 100644 index 000000000..c224c58e2 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnIndoorStateChangeListener.aidl @@ -0,0 +1,6 @@ +package com.google.android.gms.maps.internal; + +interface IOnIndoorStateChangeListener { + void onIndoorBuildingFocused() = 0; + void onIndoorLevelActivated() = 1; +} diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnLocationChangeListener.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnLocationChangeListener.aidl new file mode 100644 index 000000000..7d3897dcf --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnLocationChangeListener.aidl @@ -0,0 +1,7 @@ +package com.google.android.gms.maps.internal; + +import android.location.Location; + +interface IOnLocationChangeListener { + void onLocationChanged(in Location location) = 1; +} diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Cap.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Cap.aidl new file mode 100644 index 000000000..802366f61 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Cap.aidl @@ -0,0 +1,3 @@ +package com.google.android.gms.maps.model; + +parcelable Cap; diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Dash.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Dash.aidl new file mode 100644 index 000000000..256aedac9 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Dash.aidl @@ -0,0 +1,3 @@ +package com.google.android.gms.maps.model; + +parcelable Dash; diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Dot.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Dot.aidl new file mode 100644 index 000000000..c8aa8afb0 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Dot.aidl @@ -0,0 +1,3 @@ +package com.google.android.gms.maps.model; + +parcelable Dot; diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Gap.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Gap.aidl new file mode 100644 index 000000000..fd4fde3ae --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/Gap.aidl @@ -0,0 +1,3 @@ +package com.google.android.gms.maps.model; + +parcelable Gap; diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/StyleSpan.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/StyleSpan.aidl new file mode 100644 index 000000000..3dd85466b --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/StyleSpan.aidl @@ -0,0 +1,3 @@ +package com.google.android.gms.maps.model; + +parcelable StyleSpan; diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl index 8f2277e9e..0a2c088af 100644 --- a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/ICircleDelegate.aidl @@ -2,6 +2,7 @@ package com.google.android.gms.maps.model.internal; import com.google.android.gms.dynamic.IObjectWrapper; import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.PatternItem; interface ICircleDelegate { void remove(); @@ -24,8 +25,8 @@ interface ICircleDelegate { int hashCodeRemote(); void setClickable(boolean clickable); boolean isClickable(); - void setStrokePattern(IObjectWrapper object); - IObjectWrapper getStrokePattern(); + void setStrokePattern(in List items); + List getStrokePattern(); void setTag(IObjectWrapper object); IObjectWrapper getTag(); } diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IIndoorBuildingDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IIndoorBuildingDelegate.aidl new file mode 100644 index 000000000..3ec555d78 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IIndoorBuildingDelegate.aidl @@ -0,0 +1,10 @@ +package com.google.android.gms.maps.model.internal; + +interface IIndoorBuildingDelegate { + int getActiveLevelIndex() = 0; + int getDefaultLevelIndex() = 1; + List getLevels() = 2; // IIndoorLevelDelegate's + boolean isUnderground() = 3; + boolean equalsRemote(IIndoorBuildingDelegate other) = 4; + int hashCodeRemote() = 5; +} diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IIndoorLevelDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IIndoorLevelDelegate.aidl new file mode 100644 index 000000000..8c48348e0 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IIndoorLevelDelegate.aidl @@ -0,0 +1,9 @@ +package com.google.android.gms.maps.model.internal; + +interface IIndoorLevelDelegate { + String getName() = 0; + String getShortName() = 1; + void activate() = 2; + boolean equalsRemote(IIndoorLevelDelegate other) = 3; + int hashCodeRemote() = 4; +} diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IPolygonDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IPolygonDelegate.aidl index 79292fc7a..ef1d273ab 100644 --- a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IPolygonDelegate.aidl +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IPolygonDelegate.aidl @@ -31,6 +31,7 @@ interface IPolygonDelegate { boolean equalsRemote(IPolygonDelegate other) = 18; int hashCodeRemote() = 19; void setClickable(boolean click) = 20; + boolean isClickable() = 21; void setStrokeJointType(int type) = 22; int getStrokeJointType() = 23; void setStrokePattern(in List items) = 24; diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IPolylineDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IPolylineDelegate.aidl index ebbb336bf..0e957b2ca 100644 --- a/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IPolylineDelegate.aidl +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/model/internal/IPolylineDelegate.aidl @@ -1,22 +1,39 @@ package com.google.android.gms.maps.model.internal; +import com.google.android.gms.dynamic.IObjectWrapper; import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.PatternItem; +import com.google.android.gms.maps.model.StyleSpan; interface IPolylineDelegate { - void remove(); - String getId(); - void setPoints(in List points); - List getPoints(); - void setWidth(float width); - float getWidth(); - void setColor(int color); - int getColor(); - void setZIndex(float zIndex); - float getZIndex(); - void setVisible(boolean visible); - boolean isVisible(); - void setGeodesic(boolean geod); - boolean isGeodesic(); - boolean equalsRemote(IPolylineDelegate other); - int hashCodeRemote(); + void remove() = 0; + String getId() = 1; + void setPoints(in List points) = 2; + List getPoints() = 3; + void setWidth(float width) = 4; + float getWidth() = 5; + void setColor(int color) = 6; + int getColor() = 7; + void setZIndex(float zIndex) = 8; + float getZIndex() = 9; + void setVisible(boolean visible) = 10; + boolean isVisible() = 11; + void setGeodesic(boolean geod) = 12; + boolean isGeodesic() = 13; + boolean equalsRemote(IPolylineDelegate other) = 14; + int hashCodeRemote() = 15; + void setClickable(boolean clickable) = 16; + boolean isClickable() = 17; + //void setStartCap(Cap startCap) = 18; + //Cap getStartCap() = 19; + //void setEndCap(Cap endCap) = 20; + //Cap getEndCap() = 21; + void setJointType(int jointType) = 22; + int getJointType() = 23; + void setPattern(in List pattern) = 24; + List getPattern() = 25; + void setTag(IObjectWrapper tag) = 26; + IObjectWrapper getTag() = 27; + //void setSpans(in List spans) = 28; + //List getSpans() = 29 } diff --git a/play-services-api/src/main/java/com/google/android/gms/maps/model/Cap.java b/play-services-api/src/main/java/com/google/android/gms/maps/model/Cap.java new file mode 100644 index 000000000..d5d38d1f7 --- /dev/null +++ b/play-services-api/src/main/java/com/google/android/gms/maps/model/Cap.java @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2022 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.maps.model; + +import android.os.IBinder; + +import org.microg.safeparcel.AutoSafeParcelable; + +public class Cap extends AutoSafeParcelable { + @Field(2) + private int type; + @Field(3) + private IBinder bitmap; + private BitmapDescriptor bitmapDescriptor; + @Field(4) + private float bitmapRefWidth; + public static final Creator CREATOR = new AutoCreator<>(Cap.class); +} diff --git a/play-services-api/src/main/java/com/google/android/gms/maps/model/CircleOptions.java b/play-services-api/src/main/java/com/google/android/gms/maps/model/CircleOptions.java index cb14f525d..63ff492a7 100644 --- a/play-services-api/src/main/java/com/google/android/gms/maps/model/CircleOptions.java +++ b/play-services-api/src/main/java/com/google/android/gms/maps/model/CircleOptions.java @@ -22,6 +22,10 @@ import org.microg.gms.common.PublicApi; import org.microg.safeparcel.AutoSafeParcelable; import org.microg.safeparcel.SafeParceled; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + /** * Defines options for a Circle. */ @@ -45,6 +49,8 @@ public class CircleOptions extends AutoSafeParcelable { private boolean visible = true; @SafeParceled(9) private boolean clickable = false; + @SafeParceled(10) + private List strokePattern = null; /** * Creates circle options. @@ -239,5 +245,24 @@ public class CircleOptions extends AutoSafeParcelable { return this; } + /** + * Specifies a stroke pattern for the circle's outline. The default stroke pattern is solid, represented by {@code null}. + * + * @return this {@link CircleOptions} object with a new stroke pattern set. + */ + public CircleOptions strokePattern(List pattern) { + this.strokePattern = pattern; + return this; + } + + /** + * Gets the stroke pattern set in this {@link CircleOptions} object for the circle's outline. + * + * @return the stroke pattern of the circle's outline. + */ + public List getStrokePattern() { + return strokePattern; + } + public static Creator CREATOR = new AutoCreator(CircleOptions.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/maps/model/PatternItem.java b/play-services-api/src/main/java/com/google/android/gms/maps/model/PatternItem.java index c964cb86c..1278df94d 100644 --- a/play-services-api/src/main/java/com/google/android/gms/maps/model/PatternItem.java +++ b/play-services-api/src/main/java/com/google/android/gms/maps/model/PatternItem.java @@ -8,6 +8,8 @@ package com.google.android.gms.maps.model; +import android.os.Parcel; + import org.microg.gms.common.PublicApi; import org.microg.safeparcel.AutoSafeParcelable; @@ -21,6 +23,9 @@ public class PatternItem extends AutoSafeParcelable { @Field(3) private Float length; + private PatternItem() { + } + @PublicApi(exclude = true) PatternItem(int type, Float length) { this.type = type; @@ -32,5 +37,20 @@ public class PatternItem extends AutoSafeParcelable { return "[PatternItem: type=" + type + " length=" + length + "]"; } - public static final Creator CREATOR = new AutoCreator<>(PatternItem.class); + public static final Creator CREATOR = new AutoCreator(PatternItem.class) { + @Override + public PatternItem createFromParcel(Parcel parcel) { + PatternItem item = super.createFromParcel(parcel); + switch (item.type) { + case 0: + return new Dash(item.length); + case 1: + return new Dot(); + case 2: + return new Gap(item.length); + default: + return item; + } + } + }; } diff --git a/play-services-api/src/main/java/com/google/android/gms/maps/model/PolylineOptions.java b/play-services-api/src/main/java/com/google/android/gms/maps/model/PolylineOptions.java index d9a9dc5b4..5e2cda9b1 100644 --- a/play-services-api/src/main/java/com/google/android/gms/maps/model/PolylineOptions.java +++ b/play-services-api/src/main/java/com/google/android/gms/maps/model/PolylineOptions.java @@ -1,17 +1,6 @@ /* - * Copyright (C) 2013-2017 microG Project Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * SPDX-FileCopyrightText: 2015 microG Project Team + * SPDX-License-Identifier: Apache-2.0 */ package com.google.android.gms.maps.model; @@ -20,7 +9,6 @@ import android.graphics.Color; import org.microg.gms.common.PublicApi; import org.microg.safeparcel.AutoSafeParcelable; -import org.microg.safeparcel.SafeParceled; import java.util.ArrayList; import java.util.List; @@ -31,20 +19,32 @@ import java.util.List; */ @PublicApi public class PolylineOptions extends AutoSafeParcelable { - @SafeParceled(1) + @Field(1) private int versionCode = 1; - @SafeParceled(value = 2, subClass = LatLng.class) + @Field(value = 2, subClass = LatLng.class) private List points = new ArrayList(); - @SafeParceled(3) + @Field(3) private float width = 10; - @SafeParceled(4) + @Field(4) private int color = Color.BLACK; - @SafeParceled(5) + @Field(5) private float zIndex = 0; - @SafeParceled(6) + @Field(6) private boolean visible = true; - @SafeParceled(7) + @Field(7) private boolean geodesic = false; + @Field(8) + private boolean clickable = false; + @Field(9) + private Cap startCap; + @Field(10) + private Cap endCap; + @Field(11) + private int jointType = JointType.DEFAULT; + @Field(value = 12, subClass = PatternItem.class) + private List pattern = null; + @Field(value = 13, subClass = StyleSpan.class) + private List spans = null; public PolylineOptions() { } @@ -68,6 +68,11 @@ public class PolylineOptions extends AutoSafeParcelable { return this; } + public PolylineOptions clickable(boolean clickable) { + this.clickable = clickable; + return this; + } + public PolylineOptions color(int color) { this.color = color; return this; @@ -82,6 +87,14 @@ public class PolylineOptions extends AutoSafeParcelable { return color; } + public int getJointType() { + return jointType; + } + + public List getPattern() { + return pattern; + } + public List getPoints() { return points; } @@ -102,6 +115,10 @@ public class PolylineOptions extends AutoSafeParcelable { return visible; } + public boolean isClickable() { + return clickable; + } + public PolylineOptions visible(boolean visible) { this.visible = visible; return this; diff --git a/play-services-api/src/main/java/com/google/android/gms/maps/model/StampStyle.java b/play-services-api/src/main/java/com/google/android/gms/maps/model/StampStyle.java new file mode 100644 index 000000000..a0cf3aaff --- /dev/null +++ b/play-services-api/src/main/java/com/google/android/gms/maps/model/StampStyle.java @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2022 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.maps.model; + +import android.os.IBinder; + +import org.microg.safeparcel.AutoSafeParcelable; + +public class StampStyle extends AutoSafeParcelable { + @Field(2) + private IBinder stamp; + private BitmapDescriptor stampDescriptor; + + public static final Creator CREATOR = new AutoCreator<>(StampStyle.class); +} diff --git a/play-services-api/src/main/java/com/google/android/gms/maps/model/StrokeStyle.java b/play-services-api/src/main/java/com/google/android/gms/maps/model/StrokeStyle.java new file mode 100644 index 000000000..edc91583a --- /dev/null +++ b/play-services-api/src/main/java/com/google/android/gms/maps/model/StrokeStyle.java @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2022 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.maps.model; + +import org.microg.safeparcel.AutoSafeParcelable; + +public class StrokeStyle extends AutoSafeParcelable { + @Field(2) + private float width; + @Field(3) + private int color; + @Field(4) + private int toColor; + @Field(5) + private boolean isVisible; + @Field(6) + private StampStyle stamp; + + public static final Creator CREATOR = new AutoCreator<>(StrokeStyle.class); +} diff --git a/play-services-api/src/main/java/com/google/android/gms/maps/model/StyleSpan.java b/play-services-api/src/main/java/com/google/android/gms/maps/model/StyleSpan.java new file mode 100644 index 000000000..19e210141 --- /dev/null +++ b/play-services-api/src/main/java/com/google/android/gms/maps/model/StyleSpan.java @@ -0,0 +1,25 @@ +/* + * SPDX-FileCopyrightText: 2022 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.maps.model; + +import org.microg.safeparcel.AutoSafeParcelable; + +public class StyleSpan extends AutoSafeParcelable { + @Field(2) + private StrokeStyle style; + @Field(3) + private double segments; + + public double getSegments() { + return segments; + } + + public StrokeStyle getStyle() { + return style; + } + + public static final Creator CREATOR = new AutoCreator<>(StyleSpan.class); +} diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index 1b9cfd97f..bcb0b4ceb 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -18,6 +18,8 @@ package org.microg.gms.maps.mapbox import android.annotation.SuppressLint import android.content.Context +import android.graphics.Bitmap +import android.location.Location import android.os.* import androidx.annotation.IdRes import androidx.annotation.Keep @@ -55,6 +57,8 @@ import org.microg.gms.maps.mapbox.model.InfoWindow import org.microg.gms.maps.mapbox.model.getInfoWindowViewFor import com.mapbox.mapboxsdk.camera.CameraUpdateFactory import com.mapbox.mapboxsdk.maps.OnMapReadyCallback +import com.mapbox.mapboxsdk.location.engine.LocationEngineCallback +import com.mapbox.mapboxsdk.location.engine.LocationEngineResult import org.microg.gms.maps.MapsConstants.* import org.microg.gms.maps.mapbox.model.* import org.microg.gms.maps.mapbox.utils.MultiArchLoader @@ -93,6 +97,19 @@ class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractG private var cameraMoveStartedListener: IOnCameraMoveStartedListener? = null private var cameraIdleListener: IOnCameraIdleListener? = null private var markerDragListener: IOnMarkerDragListener? = null + private var myLocationChangeListener: IOnMyLocationChangeListener? = null + + private val locationEngineCallback = object : LocationEngineCallback { + override fun onSuccess(result: LocationEngineResult?) { + result?.lastLocation?.let { location -> + Log.d(TAG, "myLocationChanged: $location") + myLocationChangeListener?.onMyLocationChanged(ObjectWrapper.wrap(location)) + } + } + override fun onFailure(e: Exception) { + Log.w(TAG, e) + } + } var lineManager: LineManager? = null val pendingLines = mutableSetOf>() @@ -108,6 +125,8 @@ class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractG val markers = mutableMapOf() var markerId = 0L + val pendingBitmaps = mutableMapOf() + var groundId = 0L var tileId = 0L @@ -125,6 +144,7 @@ class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractG val fakeWatermark = View(mapContext) + fakeWatermark.tag = "GoogleWatermark" fakeWatermark.layoutParams = object : RelativeLayout.LayoutParams(0, 0) { @SuppressLint("RtlHardcoded") override fun addRule(verb: Int, subject: Int) { @@ -307,7 +327,7 @@ class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractG return TileOverlayImpl(this, "t${tileId++}", options) } - override fun addCircle(options: CircleOptions): ICircleDelegate? { + override fun addCircle(options: CircleOptions): ICircleDelegate { val circle = CircleImpl(this, "c${fillId++}", options) synchronized(this) { val fillManager = fillManager @@ -322,6 +342,12 @@ class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractG } else { circle.line.update(lineManager) } + circle.strokePattern?.let { + addBitmap( + it.getName(circle.strokeColor, circle.strokeWidth), + it.makeBitmap(circle.strokeColor, circle.strokeWidth) + ) + } } return circle } @@ -387,6 +413,15 @@ class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractG try { if (locationComponent.isLocationComponentActivated) { locationComponent.isLocationComponentEnabled = myLocation + if (myLocation) { + locationComponent.locationEngine?.requestLocationUpdates( + locationComponent.locationEngineRequest, + locationEngineCallback, + null + ) + } else { + locationComponent.locationEngine?.removeLocationUpdates(locationEngineCallback) + } } } catch (e: SecurityException) { Log.w(TAG, e) @@ -395,6 +430,12 @@ class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractG } } + override fun getMyLocation(): Location? { + synchronized(mapLock) { + return map?.locationComponent?.lastKnownLocation + } + } + override fun setContentDescription(desc: String?) { mapView?.contentDescription = desc } @@ -671,6 +712,9 @@ class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractG pendingMarkers.forEach { it.update(symbolManager) } pendingMarkers.clear() + pendingBitmaps.forEach { map -> it.addImage(map.key, map.value) } + pendingBitmaps.clear() + map.locationComponent.apply { activateLocationComponent(LocationComponentActivationOptions.builder(mapContext, it) .useSpecializedLocationLayer(true) @@ -680,13 +724,9 @@ class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractG renderMode = RenderMode.COMPASS } + setMyLocationEnabled(locationEnabled) + synchronized(mapLock) { - try { - map.locationComponent.isLocationComponentEnabled = locationEnabled - } catch (e: SecurityException) { - Log.w(TAG, e) - locationEnabled = false - } loaded = true if (loadedCallback != null) { Log.d(TAG, "Invoking callback delayed, as map is loaded") @@ -708,6 +748,17 @@ class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractG return false } + internal fun addBitmap(name: String, bitmap: Bitmap) { + val map = map + if (map != null) { + map.getStyle { + it.addImage(name, bitmap) + } + } else { + pendingBitmaps[name] = bitmap + } + } + override fun onResume() = mapView?.onResume() ?: Unit override fun onPause() = mapView?.onPause() ?: Unit override fun onDestroy() { @@ -751,8 +802,8 @@ class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractG mapView?.onStop() } - override fun onLowMemory() = mapView?.onLowMemory() ?: Unit + override fun onSaveInstanceState(outState: Bundle) { val newBundle = Bundle() mapView?.onSaveInstanceState(newBundle) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt new file mode 100644 index 000000000..646a0906a --- /dev/null +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt @@ -0,0 +1,83 @@ +package org.microg.gms.maps.mapbox + +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.Paint +import com.google.android.gms.maps.model.Dash +import com.google.android.gms.maps.model.Dot +import com.google.android.gms.maps.model.Gap +import com.google.android.gms.maps.model.PatternItem + +fun PatternItem.getName(): String = when (this) { + is Dash -> "dash${this.length}" + is Gap -> "gap${this.length}" + is Dot -> "dot" + else -> this.javaClass.name +} + +/** + * Name of pattern, to identify it after it is added to map + */ +fun MutableList.getName(color: Int, strokeWidth: Float) = joinToString("-") { + it.getName() +} + "-${color}-width${strokeWidth}" + +/** + * Gets width that a bitmap for this pattern item would have if the pattern's bitmap + * were to be drawn with respect to aspect ratio onto a canvas with height 1. + */ +fun PatternItem.getWidth(strokeWidth: Float): Float = when (this) { + is Dash -> this.length + is Gap -> this.length + is Dot -> strokeWidth + else -> 1f +} + +/** + * Gets width that a bitmap for this pattern would have if it were to be drawn + * with respect to aspect ratio onto a canvas with height 1. + */ +fun MutableList.getWidth(strokeWidth: Float) = map { it.getWidth(strokeWidth) }.sum() + +fun MutableList.makeBitmap(color: Int, strokeWidth: Float): Bitmap = makeBitmap(Paint().apply { + setColor(color) + style = Paint.Style.FILL +}, strokeWidth) + + +fun MutableList.makeBitmap(paint: Paint, strokeWidth: Float): Bitmap { + + // Pattern aspect ratio is not respected by renderer + val width = getWidth(strokeWidth).toInt() + val height = strokeWidth.toInt() // avoids squished image bugs + + val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) + val canvas = Canvas(bitmap) + + var drawCursor = 0f + for (item in this) { + when (item) { + is Dash -> canvas.drawRect( + drawCursor, + 0f, + drawCursor + item.length, + strokeWidth, + paint + ) + + // is Gap -> do nothing, only move cursor + + is Dot -> canvas.drawOval( + drawCursor, + 0f, + drawCursor + item.getWidth(strokeWidth), + strokeWidth, + paint + ) + } + + drawCursor += item.getWidth(strokeWidth) + } + + return bitmap +} diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt index bbb6aaab2..2ff823667 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt @@ -22,6 +22,7 @@ import com.google.android.gms.dynamic.IObjectWrapper import com.google.android.gms.dynamic.ObjectWrapper import com.google.android.gms.dynamic.unwrap import com.google.android.gms.maps.model.LatLng +import com.google.android.gms.maps.model.PatternItem import com.google.android.gms.maps.model.internal.ICircleDelegate import com.mapbox.geojson.LineString import com.mapbox.geojson.Point @@ -35,6 +36,8 @@ import com.mapbox.turf.TurfTransformation import org.microg.gms.maps.mapbox.GoogleMapImpl import org.microg.gms.maps.mapbox.LiteGoogleMapImpl import org.microg.gms.maps.mapbox.utils.toPoint +import org.microg.gms.maps.mapbox.getName +import org.microg.gms.maps.mapbox.makeBitmap import com.google.android.gms.maps.model.CircleOptions as GmsCircleOptions val NORTH_POLE: Point = Point.fromLngLat(0.0, 90.0) @@ -56,6 +59,7 @@ abstract class AbstractCircle( internal var fillColor: Int = options.fillColor internal var visible: Boolean = options.isVisible internal var clickable: Boolean = options.isClickable + internal var strokePattern: MutableList? = options.strokePattern internal var tag: Any? = null internal val line: Markup = object : Markup { @@ -69,6 +73,11 @@ abstract class AbstractCircle( ).withLineWidth(strokeWidth / dpiFactor()) .withLineColor(ColorUtils.colorToRgbaString(strokeColor)) .withLineOpacity(if (visible) 1f else 0f) + .apply { + strokePattern?.let { + withLinePattern(it.getName(strokeColor, strokeWidth)) + } + } override var removed: Boolean = false } @@ -78,7 +87,6 @@ abstract class AbstractCircle( FillOptions() .withGeometry(makePolygon()) .withFillColor(ColorUtils.colorToRgbaString(fillColor)) - .withFillOutlineColor(ColorUtils.colorToRgbaString(strokeColor)) .withFillOpacity(if (visible && !wrapsAroundPoles()) 1f else 0f) internal abstract fun update() @@ -207,13 +215,14 @@ abstract class AbstractCircle( return clickable } - override fun setStrokePattern(pattern: IObjectWrapper?) { - Log.d(TAG, "unimplemented method: set stroke pattern") + override fun setStrokePattern(pattern: MutableList?) { + this.strokePattern = pattern + update() } - override fun getStrokePattern(): IObjectWrapper { - Log.d(TAG, "unimplemented method: getStrokePattern") - return ObjectWrapper.wrap(null) + + override fun getStrokePattern(): MutableList? { + return strokePattern } override fun setTag(o: IObjectWrapper) { @@ -274,6 +283,15 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options } it.lineWidth = strokeWidth / map.dpiFactor + + line.annotation?.linePattern = null + strokePattern?.let { pattern -> + val bitmapName = pattern.getName(strokeColor, strokeWidth) + map.addBitmap(bitmapName, pattern.makeBitmap(strokeColor, strokeWidth)) + line.annotation?.linePattern = bitmapName + } + map.lineManager?.let { line.update(it) } + it.setLineColor(strokeColor) } diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polygon.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polygon.kt index f6f700538..cfa95f629 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polygon.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polygon.kt @@ -139,6 +139,8 @@ abstract class AbstractPolygon(private val id: String, options: PolygonOptions) clickable = click } + override fun isClickable(): Boolean = clickable + override fun setStrokeJointType(type: Int) { strokeJointType = type update() diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polyline.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polyline.kt index 2e16ddb16..1e762402a 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polyline.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Polyline.kt @@ -18,7 +18,10 @@ package org.microg.gms.maps.mapbox.model import android.os.Parcel import android.util.Log +import com.google.android.gms.dynamic.IObjectWrapper +import com.google.android.gms.dynamic.ObjectWrapper import com.google.android.gms.maps.model.LatLng +import com.google.android.gms.maps.model.PatternItem import com.google.android.gms.maps.model.internal.IPolylineDelegate import com.mapbox.mapboxsdk.plugins.annotation.Line import com.mapbox.mapboxsdk.plugins.annotation.LineOptions @@ -31,8 +34,12 @@ import com.google.android.gms.maps.model.PolylineOptions as GmsLineOptions abstract class AbstractPolylineImpl(private val id: String, options: GmsLineOptions, private val dpiFactor: Function0) : IPolylineDelegate.Stub() { internal var points: List = ArrayList(options.points) internal var width = options.width + internal var jointType = options.jointType + internal var pattern = ArrayList(options.pattern.orEmpty()) internal var color = options.color internal var visible: Boolean = options.isVisible + internal var clickable: Boolean = options.isClickable + internal var tag: IObjectWrapper? = null val annotationOptions: LineOptions get() = LineOptions() @@ -95,6 +102,30 @@ abstract class AbstractPolylineImpl(private val id: String, options: GmsLineOpti override fun hashCodeRemote(): Int = hashCode() + override fun setClickable(clickable: Boolean) { + this.clickable = clickable + } + + override fun isClickable(): Boolean = clickable + + override fun setJointType(jointType: Int) { + this.jointType = jointType + } + + override fun getJointType(): Int = jointType + + override fun setPattern(pattern: MutableList?) { + this.pattern = ArrayList(pattern.orEmpty()) + } + + override fun getPattern(): MutableList = pattern + + override fun setTag(tag: IObjectWrapper?) { + this.tag = tag + } + + override fun getTag(): IObjectWrapper = tag ?: ObjectWrapper.wrap(null) + override fun hashCode(): Int { return id.hashCode() } diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/MapContext.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/MapContext.kt index 2b00202a4..a8ce14125 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/MapContext.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/MapContext.kt @@ -24,7 +24,7 @@ import android.view.LayoutInflater import org.microg.gms.common.Constants import java.io.File -class MapContext(private val context: Context) : ContextWrapper(context.createPackageContext(Constants.GMS_PACKAGE_NAME, Context.CONTEXT_INCLUDE_CODE and Context.CONTEXT_IGNORE_SECURITY)) { +class MapContext(private val context: Context) : ContextWrapper(context.createPackageContext(Constants.GMS_PACKAGE_NAME, Context.CONTEXT_INCLUDE_CODE or Context.CONTEXT_IGNORE_SECURITY)) { private var layoutInflater: LayoutInflater? = null private val appContext: Context get() = context.applicationContext ?: context @@ -77,4 +77,4 @@ class MapContext(private val context: Context) : ContextWrapper(context.createPa companion object { val TAG = "GmsMapContext" } -} \ No newline at end of file +} diff --git a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java index 9fe9a05ff..8a30cd21e 100644 --- a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java +++ b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/CircleImpl.java @@ -23,6 +23,7 @@ import com.google.android.gms.dynamic.IObjectWrapper; import com.google.android.gms.dynamic.ObjectWrapper; import com.google.android.gms.maps.model.CircleOptions; import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.PatternItem; import com.google.android.gms.maps.model.internal.ICircleDelegate; import org.microg.gms.maps.vtm.GmsMapsTypeHelper; @@ -31,6 +32,8 @@ import org.oscim.layers.vector.geometries.Drawable; import org.oscim.layers.vector.geometries.Style; import org.oscim.map.Map; +import java.util.List; + public class CircleImpl extends ICircleDelegate.Stub implements DrawableMarkup { private static final String TAG = "GmsMapCircle"; @@ -155,14 +158,14 @@ public class CircleImpl extends ICircleDelegate.Stub implements DrawableMarkup { } @Override - public void setStrokePattern(IObjectWrapper object) throws RemoteException { + public void setStrokePattern(List object) throws RemoteException { Log.d(TAG, "unimplemented method: setStrokePattern"); } @Override - public IObjectWrapper getStrokePattern() throws RemoteException { + public List getStrokePattern() throws RemoteException { Log.d(TAG, "unimplemented method: getStrokePattern"); - return ObjectWrapper.wrap(null); + return null; } @Override diff --git a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/PolygonImpl.java b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/PolygonImpl.java index cb1a55f53..23bcfc83c 100644 --- a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/PolygonImpl.java +++ b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/PolygonImpl.java @@ -205,6 +205,11 @@ public class PolygonImpl extends IPolygonDelegate.Stub implements DrawableMarkup } + @Override + public boolean isClickable() throws RemoteException { + return false; + } + @Override public void setStrokeJointType(int type) throws RemoteException { diff --git a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/PolylineImpl.java b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/PolylineImpl.java index b2ff4c2f3..7e098596e 100644 --- a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/PolylineImpl.java +++ b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/markup/PolylineImpl.java @@ -19,7 +19,9 @@ package org.microg.gms.maps.vtm.markup; import android.os.RemoteException; import android.util.Log; +import com.google.android.gms.dynamic.IObjectWrapper; import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.PatternItem; import com.google.android.gms.maps.model.PolylineOptions; import com.google.android.gms.maps.model.internal.IPolylineDelegate; @@ -157,6 +159,47 @@ public class PolylineImpl extends IPolylineDelegate.Stub implements DrawableMark return id.hashCode(); } + // Not implemented + @Override + public void setClickable(boolean clickable) throws RemoteException { + + } + + @Override + public boolean isClickable() throws RemoteException { + return false; + } + + @Override + public void setJointType(int jointType) throws RemoteException { + + } + + @Override + public int getJointType() throws RemoteException { + return 0; + } + + @Override + public void setPattern(List pattern) throws RemoteException { + + } + + @Override + public List getPattern() throws RemoteException { + return null; + } + + @Override + public void setTag(IObjectWrapper tag) throws RemoteException { + + } + + @Override + public IObjectWrapper getTag() throws RemoteException { + return null; + } + @Override public Drawable getDrawable(Map map) { if (!isVisible() || removed) return null; -- GitLab From a66d4f26ea22fd4c1655df409921b20cec1405ea Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Mon, 13 Mar 2023 22:35:55 +0100 Subject: [PATCH 36/38] Fix circle outline pattern not un-setting when removed --- .../src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt | 8 ++++---- .../kotlin/org/microg/gms/maps/mapbox/model/Circle.kt | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt index 646a0906a..9cfd084a7 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt @@ -18,7 +18,7 @@ fun PatternItem.getName(): String = when (this) { /** * Name of pattern, to identify it after it is added to map */ -fun MutableList.getName(color: Int, strokeWidth: Float) = joinToString("-") { +fun List.getName(color: Int, strokeWidth: Float) = joinToString("-") { it.getName() } + "-${color}-width${strokeWidth}" @@ -37,15 +37,15 @@ fun PatternItem.getWidth(strokeWidth: Float): Float = when (this) { * Gets width that a bitmap for this pattern would have if it were to be drawn * with respect to aspect ratio onto a canvas with height 1. */ -fun MutableList.getWidth(strokeWidth: Float) = map { it.getWidth(strokeWidth) }.sum() +fun List.getWidth(strokeWidth: Float) = map { it.getWidth(strokeWidth) }.sum() -fun MutableList.makeBitmap(color: Int, strokeWidth: Float): Bitmap = makeBitmap(Paint().apply { +fun List.makeBitmap(color: Int, strokeWidth: Float): Bitmap = makeBitmap(Paint().apply { setColor(color) style = Paint.Style.FILL }, strokeWidth) -fun MutableList.makeBitmap(paint: Paint, strokeWidth: Float): Bitmap { +fun List.makeBitmap(paint: Paint, strokeWidth: Float): Bitmap { // Pattern aspect ratio is not respected by renderer val width = getWidth(strokeWidth).toInt() diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt index 2ff823667..93f3c1d32 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Circle.kt @@ -21,6 +21,7 @@ import android.util.Log import com.google.android.gms.dynamic.IObjectWrapper import com.google.android.gms.dynamic.ObjectWrapper import com.google.android.gms.dynamic.unwrap +import com.google.android.gms.maps.model.Dash import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.PatternItem import com.google.android.gms.maps.model.internal.ICircleDelegate @@ -284,8 +285,7 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options it.lineWidth = strokeWidth / map.dpiFactor - line.annotation?.linePattern = null - strokePattern?.let { pattern -> + (strokePattern ?: listOf(Dash(1f))).let { pattern -> val bitmapName = pattern.getName(strokeColor, strokeWidth) map.addBitmap(bitmapName, pattern.makeBitmap(strokeColor, strokeWidth)) line.annotation?.linePattern = bitmapName -- GitLab From e895d25a2c5659e1d54255f31d9a56d4f63b782d Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Mon, 13 Mar 2023 21:57:07 +0100 Subject: [PATCH 37/38] Circle stroke outline in lite mode --- .../kotlin/org/microg/gms/maps/mapbox/LiteGoogleMap.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/LiteGoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/LiteGoogleMap.kt index bdb332539..4b9dde3b6 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/LiteGoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/LiteGoogleMap.kt @@ -286,8 +286,14 @@ class LiteGoogleMapImpl(context: Context, var options: GoogleMapOptions) : Abstr styleBuilder.withLayer(LineLayer("l${circle.id}s", "${circle.id}s").withProperties( PropertyFactory.lineWidth(circle.strokeWidth), PropertyFactory.lineColor(circle.strokeColor), - PropertyFactory.lineCap(Property.LINE_CAP_ROUND) - )).withSource(GeoJsonSource("${circle.id}s", circle.line.annotationOptions.geometry)) + PropertyFactory.lineCap(Property.LINE_CAP_ROUND), + ).apply { + circle.strokePattern?.let { + val name = it.getName(circle.strokeColor, circle.strokeWidth) + withProperties(PropertyFactory.linePattern(name)) + styleBuilder.withImage(name, it.makeBitmap(circle.strokeColor, circle.strokeWidth)) + } + }).withSource(GeoJsonSource("${circle.id}s", circle.line.annotationOptions.geometry)) } // Add markers -- GitLab From f18100c14e80a3b973a85afc27da2785fb7464ef Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Tue, 14 Mar 2023 12:26:43 +0100 Subject: [PATCH 38/38] Unskew circle stroke pattern in lite mode Increase dot width by dpi factor. Also increase bitmap height by dpi factor. --- .../microg/gms/maps/mapbox/LiteGoogleMap.kt | 4 +-- .../org/microg/gms/maps/mapbox/Pattern.kt | 30 +++++++++---------- .../android/gms/maps/model/PatternItem.java | 2 +- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/LiteGoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/LiteGoogleMap.kt index 4b9dde3b6..c5ad88440 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/LiteGoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/LiteGoogleMap.kt @@ -289,9 +289,9 @@ class LiteGoogleMapImpl(context: Context, var options: GoogleMapOptions) : Abstr PropertyFactory.lineCap(Property.LINE_CAP_ROUND), ).apply { circle.strokePattern?.let { - val name = it.getName(circle.strokeColor, circle.strokeWidth) + val name = it.getName(circle.strokeColor, circle.strokeWidth, dpi) withProperties(PropertyFactory.linePattern(name)) - styleBuilder.withImage(name, it.makeBitmap(circle.strokeColor, circle.strokeWidth)) + styleBuilder.withImage(name, it.makeBitmap(circle.strokeColor, circle.strokeWidth, dpi)) } }).withSource(GeoJsonSource("${circle.id}s", circle.line.annotationOptions.geometry)) } diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt index 9cfd084a7..0214f9ca5 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Pattern.kt @@ -18,18 +18,18 @@ fun PatternItem.getName(): String = when (this) { /** * Name of pattern, to identify it after it is added to map */ -fun List.getName(color: Int, strokeWidth: Float) = joinToString("-") { +fun List.getName(color: Int, strokeWidth: Float, skew: Float = 1f) = joinToString("-") { it.getName() -} + "-${color}-width${strokeWidth}" +} + "-${color}-width${strokeWidth}-skew${skew}" /** * Gets width that a bitmap for this pattern item would have if the pattern's bitmap * were to be drawn with respect to aspect ratio onto a canvas with height 1. */ -fun PatternItem.getWidth(strokeWidth: Float): Float = when (this) { +fun PatternItem.getWidth(strokeWidth: Float, skew: Float): Float = when (this) { is Dash -> this.length is Gap -> this.length - is Dot -> strokeWidth + is Dot -> strokeWidth * skew else -> 1f } @@ -37,19 +37,19 @@ fun PatternItem.getWidth(strokeWidth: Float): Float = when (this) { * Gets width that a bitmap for this pattern would have if it were to be drawn * with respect to aspect ratio onto a canvas with height 1. */ -fun List.getWidth(strokeWidth: Float) = map { it.getWidth(strokeWidth) }.sum() +fun List.getWidth(strokeWidth: Float, skew: Float) = map { it.getWidth(strokeWidth, skew) }.sum() -fun List.makeBitmap(color: Int, strokeWidth: Float): Bitmap = makeBitmap(Paint().apply { +fun List.makeBitmap(color: Int, strokeWidth: Float, skew: Float = 1f): Bitmap = makeBitmap(Paint().apply { setColor(color) style = Paint.Style.FILL -}, strokeWidth) +}, strokeWidth, skew) -fun List.makeBitmap(paint: Paint, strokeWidth: Float): Bitmap { +fun List.makeBitmap(paint: Paint, strokeWidth: Float, skew: Float): Bitmap { // Pattern aspect ratio is not respected by renderer - val width = getWidth(strokeWidth).toInt() - val height = strokeWidth.toInt() // avoids squished image bugs + val width = getWidth(strokeWidth, skew).toInt() + val height = (strokeWidth * skew).toInt() // avoids squished image bugs val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) val canvas = Canvas(bitmap) @@ -60,8 +60,8 @@ fun List.makeBitmap(paint: Paint, strokeWidth: Float): Bitmap { is Dash -> canvas.drawRect( drawCursor, 0f, - drawCursor + item.length, - strokeWidth, + drawCursor + item.getWidth(strokeWidth, skew), + strokeWidth * skew, paint ) @@ -70,13 +70,13 @@ fun List.makeBitmap(paint: Paint, strokeWidth: Float): Bitmap { is Dot -> canvas.drawOval( drawCursor, 0f, - drawCursor + item.getWidth(strokeWidth), - strokeWidth, + drawCursor + item.getWidth(strokeWidth, skew), + strokeWidth * skew, paint ) } - drawCursor += item.getWidth(strokeWidth) + drawCursor += item.getWidth(strokeWidth, skew) } return bitmap diff --git a/play-services-maps/src/main/java/com/google/android/gms/maps/model/PatternItem.java b/play-services-maps/src/main/java/com/google/android/gms/maps/model/PatternItem.java index 6f8e3f7ab..1278df94d 100644 --- a/play-services-maps/src/main/java/com/google/android/gms/maps/model/PatternItem.java +++ b/play-services-maps/src/main/java/com/google/android/gms/maps/model/PatternItem.java @@ -21,7 +21,7 @@ public class PatternItem extends AutoSafeParcelable { @Field(2) private int type; @Field(3) - private float length; + private Float length; private PatternItem() { } -- GitLab