Skip to content

Commit

Permalink
[android-auto] Compatibility with v11 Maps SDK. (#2131)
Browse files Browse the repository at this point in the history
* We decided to use the same versioning for AA extension after v11.1.0 Maps SDK release.
  • Loading branch information
pengdev authored Jan 19, 2024
1 parent 4602c0a commit 844b955
Show file tree
Hide file tree
Showing 16 changed files with 137 additions and 119 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Mapbox welcomes participation and contributions from everyone.

# 11.1.0 January 17, 2024
## Features ✨ and improvements 🏁
* From v11.1.0, Mapbox Android Auto Extension for Android is released as a separate module following the same release cadence with the main SDK, please refer to [this guide](extension-androidauto/README.md) to get started with Android Auto, and [v0.5.0 changelog](extension-androidauto/CHANGELOG-v0.5.0.md) for previous changelogs.
* Define minCompileSdkVersion=31 for Maps SDK libraries.
* Introduce `FillExtrusionLayer.fillExtrusionEmissiveStrength`, `HillshadeLayer.hillshadeEmissiveStrength` and `RasterLayer.rasterEmissiveStrength` properties.
* Introduce `RasterLayer.rasterArrayBand` property.
Expand Down
6 changes: 3 additions & 3 deletions android-auto-app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ dependencies {
implementation(project(":extension-androidauto"))
implementation(libs.googleCarAppLibrary)

// Please review the compatibility guide. This app is showcasing the latest features.
// https://github.com/mapbox/mapbox-maps-android/tree/main/extension-androidauto#compatibility-with-maps-sdk-v10
implementation("com.mapbox.maps:android:10.10.0-beta.1")
// Please review the compatibility guide. This app is showcasing the latest features with latest Maps SDK main branch.
// https://github.com/mapbox/mapbox-maps-android/tree/main/extension-androidauto#compatibility-with-maps-sdk-v11
implementation(project(":sdk"))

implementation(libs.kotlin)
implementation(libs.androidx.appCompat)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.mapbox.maps.dsl.cameraOptions
import com.mapbox.maps.extension.androidauto.DefaultMapboxCarMapGestureHandler
import com.mapbox.maps.extension.androidauto.MapboxCarMapObserver
import com.mapbox.maps.extension.androidauto.MapboxCarMapSurface
import com.mapbox.maps.plugin.PuckBearing
import com.mapbox.maps.plugin.animation.camera
import com.mapbox.maps.plugin.locationcomponent.OnIndicatorBearingChangedListener
import com.mapbox.maps.plugin.locationcomponent.OnIndicatorPositionChangedListener
Expand All @@ -29,7 +30,7 @@ class CarCameraController : MapboxCarMapObserver {
private val changePositionListener = OnIndicatorPositionChangedListener { point ->
lastGpsLocation = point
if (isTrackingPuck) {
surface?.mapSurface?.getMapboxMap()?.setCamera(
surface?.mapSurface?.mapboxMap?.setCamera(
cameraOptions {
center(point)
padding(insets)
Expand All @@ -40,7 +41,7 @@ class CarCameraController : MapboxCarMapObserver {

private val changeBearingListener = OnIndicatorBearingChangedListener { bearing ->
if (isTrackingPuck) {
surface?.mapSurface?.getMapboxMap()?.setCamera(
surface?.mapSurface?.mapboxMap?.setCamera(
cameraOptions {
bearing(bearing)
}
Expand All @@ -66,7 +67,7 @@ class CarCameraController : MapboxCarMapObserver {
override fun onAttached(mapboxCarMapSurface: MapboxCarMapSurface) {
super.onAttached(mapboxCarMapSurface)
this.surface = mapboxCarMapSurface
mapboxCarMapSurface.mapSurface.getMapboxMap().setCamera(
mapboxCarMapSurface.mapSurface.mapboxMap.setCamera(
cameraOptions {
pitch(previousCameraState?.pitch ?: INITIAL_PITCH)
zoom(previousCameraState?.zoom ?: INITIAL_ZOOM)
Expand All @@ -75,15 +76,16 @@ class CarCameraController : MapboxCarMapObserver {
)
with(mapboxCarMapSurface.mapSurface.location) {
// Show a 3D location puck
locationPuck = CarLocationPuck.duckLocationPuckLowZoom
locationPuck = CarLocationPuck.duckLocationPuckConstantSize
enabled = true
puckBearing = PuckBearing.HEADING
addOnIndicatorPositionChangedListener(changePositionListener)
addOnIndicatorBearingChangedListener(changeBearingListener)
}
}

override fun onDetached(mapboxCarMapSurface: MapboxCarMapSurface) {
previousCameraState = mapboxCarMapSurface.mapSurface.getMapboxMap().cameraState
previousCameraState = mapboxCarMapSurface.mapSurface.mapboxMap.cameraState
with(mapboxCarMapSurface.mapSurface.location) {
removeOnIndicatorPositionChangedListener(changePositionListener)
removeOnIndicatorBearingChangedListener(changeBearingListener)
Expand Down Expand Up @@ -119,7 +121,7 @@ class CarCameraController : MapboxCarMapObserver {

private fun scaleEaseBy(delta: Double) {
val mapSurface = surface?.mapSurface
val fromZoom = mapSurface?.getMapboxMap()?.cameraState?.zoom ?: return
val fromZoom = mapSurface?.mapboxMap?.cameraState?.zoom ?: return
val toZoom = (fromZoom + delta).coerceIn(MIN_ZOOM_OUT, MAX_ZOOM_IN)
mapSurface.camera.easeTo(cameraOptions { zoom(toZoom) })
}
Expand All @@ -143,7 +145,7 @@ class CarCameraController : MapboxCarMapObserver {
/**
* When zooming the camera by a delta, this will prevent the camera from zooming further.
*/
private const val MIN_ZOOM_OUT = 6.0
private const val MIN_ZOOM_OUT = 0.0

/**
* When zooming the camera by a delta, this will prevent the camera from zooming further.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.mapbox.maps.testapp.auto.car

import android.annotation.SuppressLint
import androidx.car.app.CarContext
import com.mapbox.maps.ImageHolder
import com.mapbox.maps.R
import com.mapbox.maps.extension.style.expressions.dsl.generated.literal
import com.mapbox.maps.plugin.LocationPuck2D
import com.mapbox.maps.plugin.LocationPuck3D
import com.mapbox.maps.plugin.ModelScaleMode

/**
* Provides car location puck definitions.
Expand All @@ -14,28 +14,30 @@ internal object CarLocationPuck {
/**
* 3D location puck with the real world size.
*/
val duckLocationPuckHighZoom = LocationPuck3D(
val duckLocationPuckRealWorld = LocationPuck3D(
modelUri = "https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/Duck/glTF-Embedded/Duck.gltf",
modelScaleExpression = literal(listOf(10, 10, 10)).toJson(),
modelScale = listOf(20f, 20f, 20f),
modelScaleMode = ModelScaleMode.MAP,
modelRotation = listOf(0f, 0f, -90f)
)

/**
* 3D location puck with a constant size across zoom levels.
*/
val duckLocationPuckLowZoom = LocationPuck3D(
val duckLocationPuckConstantSize = LocationPuck3D(
modelUri = "https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/Duck/glTF-Embedded/Duck.gltf",
modelScale = listOf(0.2f, 0.2f, 0.2f),
modelScale = listOf(20f, 20f, 20f),
modelScaleMode = ModelScaleMode.VIEWPORT,
modelRotation = listOf(0f, 0f, -90f)
)

/**
* Classic 2D location puck with blue dot and arrow.
*/
@SuppressLint("UseCompatLoadingForDrawables")
fun classicLocationPuck2D(carContext: CarContext) = LocationPuck2D(
topImage = carContext.getDrawable(R.drawable.mapbox_user_icon),
bearingImage = carContext.getDrawable(R.drawable.mapbox_user_bearing_icon),
shadowImage = carContext.getDrawable(R.drawable.mapbox_user_stroke_icon)
val classicLocationPuck2D = LocationPuck2D(
topImage = ImageHolder.Companion.from(R.drawable.mapbox_user_icon),
bearingImage = ImageHolder.Companion.from(R.drawable.mapbox_user_bearing_icon),
shadowImage = ImageHolder.Companion.from(R.drawable.mapbox_user_stroke_icon)
)
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package com.mapbox.maps.testapp.auto.car

import androidx.car.app.CarContext
import com.mapbox.bindgen.Value
import com.mapbox.maps.Style
import com.mapbox.maps.extension.androidauto.MapboxCarMapObserver
import com.mapbox.maps.extension.androidauto.MapboxCarMapSurface
import com.mapbox.maps.extension.style.layers.generated.skyLayer
import com.mapbox.maps.extension.style.layers.properties.generated.SkyType
import com.mapbox.maps.extension.style.sources.generated.rasterDemSource
import com.mapbox.maps.extension.style.style
import com.mapbox.maps.extension.style.terrain.generated.terrain
import com.mapbox.maps.logE

/**
* Example showing how you can add a sky layer that has a sun direction,
Expand All @@ -27,35 +24,28 @@ class CarMapShowcase : MapboxCarMapObserver {
this.mapboxCarMapSurface = null
}

fun mapStyleUri(carContext: CarContext): String {
return if (carContext.isDarkMode) Style.TRAFFIC_NIGHT else Style.TRAFFIC_DAY
}

fun loadMapStyle(carContext: CarContext) {
// https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#paint-sky-sky-atmosphere-sun
// Position of the sun center [a azimuthal angle, p polar angle].
// Azimuthal is degrees from north, where 0.0 is north.
// Polar is degrees from overhead, where 0.0 is overhead.
val sunDirection = if (carContext.isDarkMode) listOf(-50.0, 90.2) else listOf(0.0, 0.0)

mapboxCarMapSurface?.mapSurface?.getMapboxMap()?.loadStyle(
styleExtension = style(mapStyleUri(carContext)) {
+rasterDemSource(DEM_SOURCE) {
url(TERRAIN_URL_TILE_RESOURCE)
tileSize(514)
}
+terrain(DEM_SOURCE)
+skyLayer(SKY_LAYER) {
skyType(SkyType.ATMOSPHERE)
skyAtmosphereSun(sunDirection)
}
val lightPreset = if (carContext.isDarkMode) LightPresets.NIGHT else LightPresets.DAY

mapboxCarMapSurface?.mapSurface?.mapboxMap?.loadStyle(Style.STANDARD) { style ->
style.setStyleImportConfigProperty(
"basemap",
"lightPreset",
Value.valueOf(lightPreset.toString().lowercase())
).error?.let {
logE(TAG, it)
}
)
}
}

private enum class LightPresets {
DAY,
DAWN,
DUSK,
NIGHT
}

companion object {
private const val SKY_LAYER = "sky"
private const val DEM_SOURCE = "mapbox-dem"
private const val TERRAIN_URL_TILE_RESOURCE = "mapbox://mapbox.mapbox-terrain-dem-v1"
private const val TAG = "CarMapShowcase"
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.mapbox.maps.testapp.auto.car

import com.mapbox.common.Cancelable
import com.mapbox.maps.MapboxExperimental
import com.mapbox.maps.extension.androidauto.MapboxCarMapObserver
import com.mapbox.maps.extension.androidauto.MapboxCarMapSurface
import com.mapbox.maps.extension.androidauto.widgets.CompassWidget
import com.mapbox.maps.extension.androidauto.widgets.LogoWidget
import com.mapbox.maps.plugin.delegates.listeners.OnCameraChangeListener

/**
* Note that the Widgets are only available when using android auto extension together with the
Expand All @@ -15,7 +15,7 @@ import com.mapbox.maps.plugin.delegates.listeners.OnCameraChangeListener
class CarMapWidgets : MapboxCarMapObserver {
private lateinit var logoWidget: LogoWidget
private lateinit var compassWidget: CompassWidget
private lateinit var onCameraChangeListener: OnCameraChangeListener
private var cancellable: Cancelable? = null
override fun onAttached(mapboxCarMapSurface: MapboxCarMapSurface) {
super.onAttached(mapboxCarMapSurface)
with(mapboxCarMapSurface) {
Expand All @@ -25,17 +25,19 @@ class CarMapWidgets : MapboxCarMapObserver {
marginX = 26f,
marginY = 120f,
)
onCameraChangeListener = OnCameraChangeListener { compassWidget.setRotation(-mapSurface.getMapboxMap().cameraState.bearing.toFloat()) }
mapSurface.addWidget(logoWidget)
mapSurface.addWidget(compassWidget)
mapSurface.getMapboxMap().addOnCameraChangeListener(onCameraChangeListener)
cancellable = mapSurface.mapboxMap.subscribeCameraChanged {
compassWidget.setRotation(-mapSurface.mapboxMap.cameraState.bearing.toFloat())
}
}
}

override fun onDetached(mapboxCarMapSurface: MapboxCarMapSurface) {
super.onDetached(mapboxCarMapSurface)
with(mapboxCarMapSurface) {
mapSurface.getMapboxMap().removeOnCameraChangeListener(onCameraChangeListener)
cancellable?.cancel()
cancellable = null
mapSurface.removeWidget(logoWidget)
mapSurface.removeWidget(compassWidget)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@
import com.mapbox.maps.MapInitOptions;
import com.mapbox.maps.MapSurface;
import com.mapbox.maps.MapboxExperimental;
import com.mapbox.maps.ResourceOptions;
import com.mapbox.maps.ScreenCoordinate;
import com.mapbox.maps.extension.androidauto.CarMapSurfaceOwner;
import com.mapbox.maps.extension.androidauto.MapboxCarMap;
import com.mapbox.maps.extension.androidauto.DefaultMapboxCarMapGestureHandler;
import com.mapbox.maps.extension.androidauto.MapboxCarMap;
import com.mapbox.maps.extension.androidauto.MapboxCarMapEx;
import com.mapbox.maps.extension.androidauto.MapboxCarMapGestureHandler;
import com.mapbox.maps.extension.androidauto.MapboxCarMapObserver;
Expand Down Expand Up @@ -114,11 +112,7 @@ private void sessionInstaller(Session session) {
.onCreated(observer1, observer2)
.onStarted(observer1, observer2)
.onResumed(observer1, observer2)
.install(carContext1 -> new MapInitOptions(
carContext1,
new ResourceOptions.Builder()
.build())
);
.install(MapInitOptions::new);
}

private void screenInstaller(Screen screen, MapboxCarMap mapboxCarMap) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

Mapbox welcomes participation and contributions from everyone.

# main
## Features ✨ and improvements 🏁
# Please refer to [release notes](../CHANGELOG.md) in the main SDK for the latest Android Auto Extension related changes.

# 0.5.0 November 16, 2022

Expand Down
69 changes: 42 additions & 27 deletions extension-androidauto/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,8 @@ allprojects {
// In your build.gradle, add the extension with your other dependencies.
dependencies {
implementation 'com.mapbox.extension:maps-androidauto:0.1.0'
// Pick your versions of Android Mapbox Map SDK
// Note that Android Auto extenison is compatibile with Maps SDK v10.0+, however some Android Auto features like Widgets requires Map SDK v10.4.0+
// See the detailed feature compatibility table below
implementation 'com.mapbox.maps:android:10.4.0'
// Note that the Mapbox Android Auto Extension depends on the entire Mapbox Maps SDK, it will bring the whole Mapbox Maps SDK with the same version as transitive dependency.
implementation 'com.mapbox.extension:maps-androidauto:11.1.0'
}
```

Expand Down Expand Up @@ -153,25 +149,44 @@ AnimationThreadController.useMainThread()

It is highly recommended to use background thread for animators just when it is absolutely necessary - when Xiaomi device is used and the map is running in background. You could refer to our official [example](../android-auto-app/src/main/java/com/mapbox/maps/testapp/auto/car/CarAnimationThreadController.kt) how to implement that.

## Compatibility with Maps SDK v11

From v11.1.0, Mapbox Android Auto Extension for Android is released as a separate module following the same release cadence with the main SDK and have a api dependency. The features list can be found below:

| Features | Supported? |
|----------------------------|------------|
| Xiaomi animations | ✅ |
| Logo Widget | ✅ |
| Compass Widget | ✅ |
| Map rendering | ✅ |
| Runtime styling | ✅ |
| Camera animation | ✅ |
| Viewport plugin | ✅ |
| Location Component plugin | ✅ |
| Gestures(scroll and scale) | ✅ |
| Annotation plugin | ✅ |
| View annotation plugin | ❌ |
| Scale bar plugin | ❌ |
| Attribution | ❌ |

## Compatibility with Maps SDK v10
The Android Auto extension is released separately from the Android Maps SDK v10 and has a compileOnly dependency. When using the Android Auto extension you need to include a compatible Maps SDK. The feature compatibility checklist can be found below.

Below is the full feature compatibility table:

Features | Supported? | Compatible Maps SDK version
------------- | ------------- | -------------
Xiaomi animations | ✅ | v10.9+
Logo Widget | ✅ | v10.4+
Compass Widget | ✅ | v10.4+
Map rendering | ✅ | v10.0+
Runtime styling | ✅ | v10.0+
Camera animation | ✅ | v10.0+
Viewport plugin | ✅ | v10.0+
Location Component plugin | ✅ | v10.0+
Gestures(scroll and scale) | ✅ | v10.0+
Annotation plugin | ✅ | v10.0+
View annotation plugin | ❌ | -
Scale bar plugin | ❌ | -
Attribution | ❌ | -

View [LICENSE.md](LICENSE.md) for all dependencies used by this extension.

The Android Auto extension before v0.5.0 is released separately from the Android Maps SDK v10 and has a compileOnly dependency. When using the Android Auto extension you need to include a compatible Maps SDK. The feature compatibility checklist can be found below.

| Features | Supported? | Compatible Maps SDK version |
|----------------------------|------------|-----------------------------|
| Xiaomi animations | ✅ | v10.9+ |
| Logo Widget | ✅ | v10.4+ |
| Compass Widget | ✅ | v10.4+ |
| Map rendering | ✅ | v10.0+ |
| Runtime styling | ✅ | v10.0+ |
| Camera animation | ✅ | v10.0+ |
| Viewport plugin | ✅ | v10.0+ |
| Location Component plugin | ✅ | v10.0+ |
| Gestures(scroll and scale) | ✅ | v10.0+ |
| Annotation plugin | ✅ | v10.0+ |
| View annotation plugin | ❌ | - |
| Scale bar plugin | ❌ | - |
| Attribution | ❌ | - |

View [LICENSE.md](LICENSE.md) for all dependencies used by this extension.
3 changes: 1 addition & 2 deletions extension-androidauto/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,13 @@ android {
}

dependencies {
api(libs.android.autoMapboxMapSdk)
api(project(":sdk"))
api(libs.googleCarAppLibrary)
implementation(libs.kotlin)
implementation(libs.androidx.coreKtx)
implementation(libs.androidx.annotations)

testImplementation(libs.bundles.base.dependenciesTests)
testImplementation(libs.android.autoMapboxMapSdk)
androidTestImplementation(libs.bundles.base.dependenciesAndroidTests)
detektPlugins(libs.detektFormatting)
}
Expand Down
Loading

0 comments on commit 844b955

Please sign in to comment.