Skip to content

Commit cf57218

Browse files
authored
[compose] Expose MapViewportState.cameraForCoordinates (#2835)
* [compose] Expose several methods in MapViewportState * Add example * Remove couple methods
1 parent 69eb845 commit cf57218

File tree

5 files changed

+76
-15
lines changed

5 files changed

+76
-15
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
Mapbox welcomes participation and contributions from everyone.
44

55
# main
6+
## Features ✨ and improvements 🏁
7+
* [compose] Expose `MapViewportState.cameraForCoordinates` method.
8+
69
# 11.8.0
710
## Breaking changes ⚠️
811
* Change the signature of experimental `MapboxMap.queryRenderedFeatures(RenderedQueryGeometry, TypedFeaturesetDescriptor, Value?, QueryRenderedFeaturesetFeaturesCallback)` to `MapboxMap.queryRenderedFeatures(TypedFeaturesetDescriptor, RenderedQueryGeometry?, Value?, QueryRenderedFeaturesetFeaturesCallback)`. `RenderedQueryGeometry` being NULL is equivalent to passing a bounding box encompassing the entire map viewport.

compose-app/src/main/java/com/mapbox/maps/compose/testapp/examples/style/InteractionsActivity.kt

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.wrapContentWidth
1212
import androidx.compose.foundation.shape.CircleShape
1313
import androidx.compose.material.MaterialTheme
1414
import androidx.compose.material.Text
15+
import androidx.compose.runtime.LaunchedEffect
1516
import androidx.compose.runtime.getValue
1617
import androidx.compose.runtime.mutableStateOf
1718
import androidx.compose.runtime.remember
@@ -22,6 +23,7 @@ import androidx.compose.ui.graphics.Color
2223
import androidx.compose.ui.text.style.TextAlign
2324
import androidx.compose.ui.unit.dp
2425
import com.mapbox.geojson.Point
26+
import com.mapbox.maps.EdgeInsets
2527
import com.mapbox.maps.MapboxExperimental
2628
import com.mapbox.maps.compose.testapp.ExampleScaffold
2729
import com.mapbox.maps.compose.testapp.ui.theme.MapboxMapComposeTheme
@@ -53,22 +55,38 @@ public class InteractionsActivity : ComponentActivity() {
5355
}
5456

5557
val mapState = rememberMapState()
58+
val mapViewportState = rememberMapViewportState {
59+
setCameraOptions(
60+
cameraOptions {
61+
center(Point.fromLngLat(-73.99, 40.72))
62+
zoom(11.0)
63+
pitch(45.0)
64+
}
65+
)
66+
}
67+
68+
LaunchedEffect(selectedPriceLabel) {
69+
selectedPriceLabel?.let {
70+
val camera = mapViewportState.cameraForCoordinates(
71+
listOf(it.geometry as Point),
72+
cameraOptions {
73+
padding(
74+
EdgeInsets(100.0, 100.0, 100.0, 100.0)
75+
)
76+
},
77+
maxZoom = 11.0
78+
)
79+
mapViewportState.flyTo(camera)
80+
}
81+
}
5682

5783
MapboxMapComposeTheme {
5884
ExampleScaffold {
5985
Box(modifier = Modifier.fillMaxSize()) {
6086
MapboxMap(
6187
modifier = Modifier.fillMaxSize(),
6288
mapState = mapState,
63-
mapViewportState = rememberMapViewportState {
64-
setCameraOptions(
65-
cameraOptions {
66-
center(Point.fromLngLat(-73.99, 40.72))
67-
zoom(11.0)
68-
pitch(45.0)
69-
}
70-
)
71-
},
89+
mapViewportState = mapViewportState,
7290
style = {
7391
GenericStyle(
7492
style = "asset://fragment-realestate-NY.json",
@@ -102,12 +120,12 @@ public class InteractionsActivity : ComponentActivity() {
102120
selectedPriceLabel?.let { actualSelectedPriceLabel ->
103121
Text(
104122
modifier = Modifier
105-
.wrapContentWidth()
106-
.align(Alignment.BottomCenter)
107-
.padding(40.dp)
108-
.border(2.dp, MaterialTheme.colors.secondary, CircleShape)
109-
.background(MaterialTheme.colors.primary, CircleShape)
110-
.padding(10.dp),
123+
.wrapContentWidth()
124+
.align(Alignment.BottomCenter)
125+
.padding(40.dp)
126+
.border(2.dp, MaterialTheme.colors.secondary, CircleShape)
127+
.background(MaterialTheme.colors.primary, CircleShape)
128+
.padding(10.dp),
111129
textAlign = TextAlign.Center,
112130
color = Color.White,
113131
text = "Feature with id: ${actualSelectedPriceLabel.id!!}; active: $isActive",

extension-compose/api/Release/metalava.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ package com.mapbox.maps.extension.compose.animation.viewport {
126126

127127
@androidx.compose.runtime.Stable public final class MapViewportState {
128128
ctor public MapViewportState(com.mapbox.maps.CameraState initialCameraState = com.mapbox.maps.extension.compose.animation.viewport.MapViewportState.INIT_CAMERA_STATE);
129+
method @UiThread public suspend Object? cameraForCoordinates(java.util.List<com.mapbox.geojson.Point> coordinates, com.mapbox.maps.CameraOptions camera = cameraOptions({
130+
131+
}), com.mapbox.maps.EdgeInsets? coordinatesPadding = null, Double? maxZoom = null, com.mapbox.maps.ScreenCoordinate? offset = null, kotlin.coroutines.Continuation<? super com.mapbox.maps.CameraOptions> = null);
129132
method public void easeTo(com.mapbox.maps.CameraOptions cameraOptions, com.mapbox.maps.plugin.animation.MapAnimationOptions? animationOptions = null, com.mapbox.maps.plugin.viewport.CompletionListener? completionListener = null);
130133
method public void flyTo(com.mapbox.maps.CameraOptions cameraOptions, com.mapbox.maps.plugin.animation.MapAnimationOptions? animationOptions = null, com.mapbox.maps.plugin.viewport.CompletionListener? completionListener = null);
131134
method public com.mapbox.maps.CameraState? getCameraState();

extension-compose/api/extension-compose.api

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ public final class com/mapbox/maps/extension/compose/animation/viewport/MapViewp
143143
public fun <init> ()V
144144
public fun <init> (Lcom/mapbox/maps/CameraState;)V
145145
public synthetic fun <init> (Lcom/mapbox/maps/CameraState;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
146+
public final fun cameraForCoordinates (Ljava/util/List;Lcom/mapbox/maps/CameraOptions;Lcom/mapbox/maps/EdgeInsets;Ljava/lang/Double;Lcom/mapbox/maps/ScreenCoordinate;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
147+
public static synthetic fun cameraForCoordinates$default (Lcom/mapbox/maps/extension/compose/animation/viewport/MapViewportState;Ljava/util/List;Lcom/mapbox/maps/CameraOptions;Lcom/mapbox/maps/EdgeInsets;Ljava/lang/Double;Lcom/mapbox/maps/ScreenCoordinate;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
146148
public final fun easeTo (Lcom/mapbox/maps/CameraOptions;Lcom/mapbox/maps/plugin/animation/MapAnimationOptions;Lcom/mapbox/maps/plugin/viewport/CompletionListener;)V
147149
public static synthetic fun easeTo$default (Lcom/mapbox/maps/extension/compose/animation/viewport/MapViewportState;Lcom/mapbox/maps/CameraOptions;Lcom/mapbox/maps/plugin/animation/MapAnimationOptions;Lcom/mapbox/maps/plugin/viewport/CompletionListener;ILjava/lang/Object;)V
148150
public final fun flyTo (Lcom/mapbox/maps/CameraOptions;Lcom/mapbox/maps/plugin/animation/MapAnimationOptions;Lcom/mapbox/maps/plugin/viewport/CompletionListener;)V

extension-compose/src/main/java/com/mapbox/maps/extension/compose/animation/viewport/MapViewportState.kt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import com.mapbox.maps.CameraState
1919
import com.mapbox.maps.EdgeInsets
2020
import com.mapbox.maps.MapView
2121
import com.mapbox.maps.MapboxMap
22+
import com.mapbox.maps.ScreenCoordinate
2223
import com.mapbox.maps.coroutine.cameraChangedEvents
2324
import com.mapbox.maps.dsl.cameraOptions
2425
import com.mapbox.maps.plugin.animation.CameraAnimationsPlugin
@@ -40,6 +41,8 @@ import com.mapbox.maps.plugin.viewport.transition.ViewportTransition
4041
import com.mapbox.maps.plugin.viewport.viewport
4142
import com.mapbox.maps.toCameraOptions
4243
import kotlinx.coroutines.channels.Channel
44+
import kotlin.coroutines.resume
45+
import kotlin.coroutines.suspendCoroutine
4346

4447
/**
4548
* Create and [rememberSaveable] a [MapViewportState] using [MapViewportState.Saver].
@@ -180,6 +183,38 @@ public class MapViewportState(
180183
setCameraOptions(cameraOptions(block))
181184
}
182185

186+
/**
187+
* Convenience method that returns the [CameraOptions] object for given parameters.
188+
*
189+
* @param coordinates The `coordinates` representing the bounds of the camera.
190+
* @param camera The [CameraOptions] which will be applied before calculating the camera for the coordinates. If any of the fields in [CameraOptions] are not provided then the current value from the map for that field will be used.
191+
* @param coordinatesPadding The amount of padding in pixels to add to the given `coordinates`.
192+
* Note: This padding is not applied to the map but to the coordinates provided. If you want to apply padding to the map use param `camera`.
193+
* @param maxZoom The maximum zoom level allowed in the returned camera options.
194+
* @param offset The center of the given bounds relative to map center in pixels.
195+
*
196+
* @return The [CameraOptions] object representing the provided parameters.
197+
*/
198+
@UiThread
199+
public suspend fun cameraForCoordinates(
200+
coordinates: List<Point>,
201+
camera: CameraOptions = cameraOptions { },
202+
coordinatesPadding: EdgeInsets? = null,
203+
maxZoom: Double? = null,
204+
offset: ScreenCoordinate? = null,
205+
): CameraOptions = suspendCoroutine { continuation ->
206+
viewportActionChannel.trySend { mapView ->
207+
mapView.mapboxMap.cameraForCoordinates(
208+
coordinates,
209+
camera,
210+
coordinatesPadding,
211+
maxZoom,
212+
offset,
213+
continuation::resume
214+
)
215+
}
216+
}
217+
183218
/**
184219
* A utility function to get the default [CameraOptions] defined in the style or null if this
185220
* [MapViewportState] is not yet associated with a map.

0 commit comments

Comments
 (0)