Skip to content

Commit d1b8e50

Browse files
authored
Interactive features: generated Standard interactions (#2779)
* Final adjustments Simplify generics a bit Adjustments to support typed QRF Rename featureId / layerId to id Mark some methods as MapboxDelicateApi Fix QRF not returning an empty list PR fixes Rename FeaturesetHolder to TypedFeaturesetDescriptor Remove Standard APIs Fixes Rename InteractiveFeature to FeaturesetFeature API adjustments, changelog Simplify generics Enhance example a bit wip Standard interactions * Adjust upstream fixes Adjust new generics for typed QRF Move typed feature properties from state to FeaturesetFeature Interactions changes Final adjustments Simplify generics a bit Adjustments to support typed QRF Rename featureId / layerId to id Mark some methods as MapboxDelicateApi Fix QRF not returning an empty list PR fixes Rename FeaturesetHolder to TypedFeaturesetDescriptor Remove Standard APIs Fixes Rename InteractiveFeature to FeaturesetFeature API adjustments, changelog Simplify generics Enhance example a bit wip Standard interactions * Interactive features: generate Standard interactions * Generate all Standard interactions * Make interactions itself (click, long click) generated * Generate Standard TypedFeaturesetDescriptor * [Compose] Introduce dedicated state holders for Standard styles (#2781) * Introduce dedicated state holders for Standard styles * add generator * PR fixes * Adapt latest changes * Fix compilation * Some formatting fixes * update api * Fixes, rebase * Use Point instead of Geometry for POIs * Fix script * PR fixes * Use experimental style * Updated experimental style * PR fixes * Rebase, append changelog
1 parent 1c8662e commit d1b8e50

40 files changed

+2261
-103
lines changed

CHANGELOG.md

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,39 @@ Mapbox welcomes participation and contributions from everyone.
44

55
# main
66
## Features ✨ and improvements 🏁
7-
* [compose] Deprecate all `Annotation` and `AnnotationGroup` composables that take `onClick` parameter. Now all annotation interactions could be set with appropriate `AnnotationInteractionsState` or `AnnotationGroupInteractionsState` stored in `AnnotationGroupState`.
8-
* [compose] Introduce `AnnotationInteractionsState` and `AnnotationGroupInteractionsState` states that allow to set callbacks for annotation interactions via `onClicked()` and `onLongClicked()`.`PointAnnotationGroupInteractionsState` and `CircleAnnotationGroupInteractionsState` also provide ability to set callbacks for interactions with clusters via `onClusterClicked` and `onClusterLongClicked`.
9-
* [compose] Introduce `remember` (e.g. `rememberPolylineAnnotationGroupInteractionsState` and `rememberPolylineAnnotationInteractionsState`) composable functions to create, init and remember all types of `AnnotationInteractionsState` and `AnnotationGroupInteractionsState`.
10-
* [compose] Introduce `<AnnotationType>InteractionsState.isDraggable` / `<AnnotationType>GroupInteractionsState.isDraggable` API for all annotation types allowing to drag annotations. Callbacks `onDragStarted()`, `onDragged()`,`onDragFinished()` are added as well.
11-
* Introduce experimental `getStyleGlyphURL` / `setStyleGlyphURL` functions for `MapboxMap` and `Style`.
7+
* Introduce `Style.STANDARD_EXPERIMENTAL` style supporting featuresets and map interactions. **Important: this style should not be used in production as the style definition on backend is a subject to change after v11.8.0 stable release!**
8+
* Introduce fully typed map click and long click interactions working with `Style.STANDARD_EXPERIMENTAL`: `standardPoi`, `standardPlaceLabels`, `standardBuildings`.
129
* Introduce `OnClusterClickListener` and `OnClusterLongClickListener` for `CircleAnnotationManager` and `PointAnnotationManager`. These callbacks receive the clicked cluster represented by a `ClusterFeature`.
10+
* Introduce experimental `getStyleGlyphURL` / `setStyleGlyphURL` functions for `MapboxMap` and `Style`.
1311
* Make `fill-extrusion-emissive-strength` property data-driven.
1412
* Dispatch view annotations update before rendering, so that view annotations and map layers are rendered simultaneously and thus decreasing the view annotations latency when using `ViewAnnotationUpdateMode.MAP_FIXED_DELAY` mode.
15-
* Overscale composited tile components in Offline.
13+
* Overscale composited tile components in offline.
1614
* Skip rendering landmarks when the camera is inside them.
15+
* [compose] Deprecate all `Annotation` and `AnnotationGroup` composables that take `onClick` parameter. Now all annotation interactions could be set with appropriate `AnnotationInteractionsState` or `AnnotationGroupInteractionsState` stored in `AnnotationGroupState`.
16+
* [compose] Introduce `AnnotationInteractionsState` and `AnnotationGroupInteractionsState` states that allow to set callbacks for annotation interactions via `onClicked()` and `onLongClicked()`.`PointAnnotationGroupInteractionsState` and `CircleAnnotationGroupInteractionsState` also provide ability to set callbacks for interactions with clusters via `onClusterClicked` and `onClusterLongClicked`.
17+
* [compose] Introduce `remember` (e.g. `rememberPolylineAnnotationGroupInteractionsState` and `rememberPolylineAnnotationInteractionsState`) composable functions to create, init and remember all types of `AnnotationInteractionsState` and `AnnotationGroupInteractionsState`.
18+
* [compose] Introduce `<AnnotationType>InteractionsState.isDraggable` / `<AnnotationType>GroupInteractionsState.isDraggable` API for all annotation types allowing to drag annotations. Callbacks `onDragStarted()`, `onDragged()`,`onDragFinished()` are added as well.
1719

1820
## Bug fixes 🐞
1921
* Improve zooming performance on dynamic Standard terrain and optimize terrain re-rendering performance on e.g routeline `line-trim-offset` change.
2022
* Respect polygons with holes on querying rendered features.
2123
* Fix self-overlap of line corners when large `line-width` is used.
2224
* Adjust conflation intersection test padding to fix disappearing `fill-extrusion`.
2325
* Fix TileCover bug with polygon horizontal edges.
24-
* Fixing a bug with image dependent paint properties not getting a correct value after image become available.
26+
* Fix a bug with image dependent paint properties not getting a correct value after image become available.
2527
* Clear tile pyramid on color theme change before the tiles are updated.
26-
* Fixed missing images notifications for images within coalesce expression when other images in coalesce are present. Image expressions with two arguments are no longer being considered present if only second image is present.
28+
* Fix missing images notifications for images within coalesce expression when other images in coalesce are present. Image expressions with two arguments are no longer being considered present if only second image is present.
2729
* Return operation error for featurestate related API in case the featureset is not valid.
2830
* Fix crash on style pack load when no access token is set.
2931
* Fix crash in TerrainRenderer when using snapshotter.
3032
* Fix crash on re-creation of a custom raster source when different options are provided.
3133
* Return parsing errors if runtime added style import JSON is not valid.
32-
* Fix missing models in rendering result if reduceMemoryUse is called before taking snapshot.
33-
* Compilation error due to dynamic_cast on embedded linux.
34+
* Fix missing models in rendering result if `reduceMemoryUse` is called before taking snapshot.
3435
* Fix the incorrect behaviour when using `symbol-z-oder` property.
3536
* Fix `raster-particle` trail discontinuity at the antimeridian.
3637

37-
38+
## Dependencies
39+
* Update gl-native to v11.8.0-beta.1 and common to v24.8.0-beta.1.
3840

3941
# 11.7.1 October 10, 2024
4042
## Bug fixes 🐞

app/src/main/AndroidManifest.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,5 +1377,17 @@
13771377
android:name="android.support.PARENT_ACTIVITY"
13781378
android:value=".ExampleOverviewActivity" />
13791379
</activity>
1380+
<activity
1381+
android:name=".examples.StandardStyleInteractionsActivity"
1382+
android:description="@string/description_standard_interactions"
1383+
android:exported="true"
1384+
android:label="@string/activity_standard_interactions">
1385+
<meta-data
1386+
android:name="@string/category"
1387+
android:value="@string/category_styles" />
1388+
<meta-data
1389+
android:name="android.support.PARENT_ACTIVITY"
1390+
android:value=".ExampleOverviewActivity" />
1391+
</activity>
13801392
</application>
13811393
</manifest>

app/src/main/java/com/mapbox/maps/testapp/examples/JavaInterfaceChecker.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@
7676
import com.mapbox.maps.interactions.FeatureState;
7777
import com.mapbox.maps.interactions.FeatureStateKey;
7878
import com.mapbox.maps.interactions.TypedFeaturesetDescriptor;
79+
import com.mapbox.maps.interactions.standard.generated.StandardBuildingsState;
80+
import com.mapbox.maps.interactions.standard.generated.StandardInteractions;
7981
import com.mapbox.maps.module.MapTelemetry;
8082
import com.mapbox.maps.plugin.LocationPuck;
8183
import com.mapbox.maps.plugin.LocationPuck2D;
@@ -699,5 +701,29 @@ private void interactions(final MapboxMap mapboxMap) {
699701
!context.getScreenCoordinate().equals(new ScreenCoordinate(0.0, 0.0))
700702
)
701703
);
704+
705+
mapboxMap.loadStyle(Style.STANDARD_EXPERIMENTAL);
706+
mapboxMap.addInteraction(
707+
StandardInteractions.standardBuildings(
708+
ClickInteraction.Companion,
709+
(clickedBuilding, context) -> {
710+
mapboxMap.setFeatureState(
711+
clickedBuilding,
712+
new StandardBuildingsState.Builder()
713+
.highlight(true)
714+
.build()
715+
);
716+
return true;
717+
}
718+
)
719+
);
720+
721+
StandardInteractions.standardPlaceLabels(
722+
ClickInteraction.Companion,
723+
(placeLabelsFeature, context) -> {
724+
placeLabelsFeature.getClass();
725+
return true;
726+
}
727+
);
702728
}
703729
}
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
package com.mapbox.maps.testapp.examples
2+
3+
import android.annotation.SuppressLint
4+
import android.graphics.Color
5+
import android.os.Bundle
6+
import android.view.Gravity
7+
import android.view.ViewGroup
8+
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
9+
import android.widget.TextView
10+
import android.widget.Toast
11+
import androidx.appcompat.app.AppCompatActivity
12+
import com.mapbox.geojson.Point
13+
import com.mapbox.maps.ClickInteraction
14+
import com.mapbox.maps.MapInitOptions
15+
import com.mapbox.maps.MapView
16+
import com.mapbox.maps.MapboxExperimental
17+
import com.mapbox.maps.Style
18+
import com.mapbox.maps.ViewAnnotationAnchor
19+
import com.mapbox.maps.dsl.cameraOptions
20+
import com.mapbox.maps.interactions.standard.generated.StandardBuildingsState
21+
import com.mapbox.maps.interactions.standard.generated.StandardPlaceLabelsState
22+
import com.mapbox.maps.interactions.standard.generated.StandardPoiFeature
23+
import com.mapbox.maps.interactions.standard.generated.StandardPoiState
24+
import com.mapbox.maps.interactions.standard.generated.StandardPoiStateKey
25+
import com.mapbox.maps.interactions.standard.generated.standardBuildings
26+
import com.mapbox.maps.interactions.standard.generated.standardPlaceLabels
27+
import com.mapbox.maps.interactions.standard.generated.standardPoi
28+
import com.mapbox.maps.viewannotation.annotationAnchor
29+
import com.mapbox.maps.viewannotation.geometry
30+
import com.mapbox.maps.viewannotation.viewAnnotationOptions
31+
32+
/**
33+
* Interactive map elements when using experimental Mapbox Standard Style.
34+
*/
35+
@OptIn(MapboxExperimental::class)
36+
class StandardStyleInteractionsActivity : AppCompatActivity() {
37+
38+
@SuppressLint("SetTextI18n")
39+
override fun onCreate(savedInstanceState: Bundle?) {
40+
super.onCreate(savedInstanceState)
41+
val mapView = MapView(
42+
this,
43+
MapInitOptions(
44+
this,
45+
cameraOptions = cameraOptions {
46+
center(HELSINKI)
47+
zoom(15.0)
48+
pitch(30.0)
49+
}
50+
)
51+
)
52+
setContentView(mapView)
53+
val map = mapView.mapboxMap
54+
val selectedPoiList = mutableListOf<StandardPoiFeature>()
55+
56+
map.loadStyle(Style.STANDARD_EXPERIMENTAL)
57+
58+
// the most basic use-case to highlight clicked building
59+
map.addInteraction(
60+
ClickInteraction.standardBuildings { selectedBuilding, _ ->
61+
map.setFeatureState(
62+
selectedBuilding,
63+
StandardBuildingsState {
64+
highlight(true)
65+
}
66+
)
67+
return@standardBuildings true
68+
}
69+
)
70+
71+
// a bit more advanced use-case to fade a place label and also show a pop-up
72+
// with clicked place label class
73+
map.addInteraction(
74+
ClickInteraction.standardPlaceLabels { selectedPlaceLabel, _ ->
75+
Toast.makeText(this, selectedPlaceLabel.`class` ?: "No class!", Toast.LENGTH_SHORT).show()
76+
map.setFeatureState(
77+
selectedPlaceLabel,
78+
StandardPlaceLabelsState {
79+
select(true)
80+
}
81+
)
82+
return@standardPlaceLabels true
83+
}
84+
)
85+
86+
// the most advanced use case to:
87+
// 1. Hide clicked POI.
88+
// 2. Show the Android View Annotation instead in the place where user clicked.
89+
// 3. Clicking the Android View Annotation removes it and shows hidden POI again.
90+
// 4. Text color of the Android View Annotation is driven by POI type: RED if it's transit and BLUE otherwise.
91+
map.addInteraction(
92+
ClickInteraction.standardPoi { selectedPoi, _ ->
93+
map.setFeatureState(
94+
selectedPoi,
95+
StandardPoiState {
96+
hide(true)
97+
}
98+
) {
99+
selectedPoiList.add(selectedPoi)
100+
mapView.viewAnnotationManager.addViewAnnotation(
101+
TextView(this).apply {
102+
text = "${selectedPoi.name}\nGroup: ${selectedPoi.group}"
103+
if (selectedPoi.group == "transit") {
104+
setTextColor(Color.RED)
105+
} else {
106+
setTextColor(Color.BLUE)
107+
}
108+
gravity = Gravity.CENTER
109+
layoutParams = ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
110+
// when clicking on the view annotation - remove it and bring the map POI back
111+
setOnClickListener { selectedPoiView ->
112+
// check with getter to get the most actual state
113+
map.getFeatureState(selectedPoi) { currentState ->
114+
if (currentState.hide == true) {
115+
// show POI again and remove the view annotation
116+
map.setFeatureState(
117+
selectedPoi,
118+
StandardPoiState {
119+
hide(false)
120+
}
121+
)
122+
mapView.viewAnnotationManager.removeViewAnnotation(selectedPoiView)
123+
}
124+
}
125+
}
126+
},
127+
viewAnnotationOptions {
128+
geometry(selectedPoi.geometry)
129+
annotationAnchor {
130+
anchor(ViewAnnotationAnchor.CENTER)
131+
}
132+
}
133+
)
134+
}
135+
return@standardPoi true
136+
}
137+
)
138+
139+
// when clicked on the map - remove the feature state from all selected POIs
140+
// and show them as defined in Mapbox Standard Style
141+
map.addInteraction(
142+
ClickInteraction { _ ->
143+
selectedPoiList.forEach { selectedPoi ->
144+
map.removeFeatureState(
145+
selectedPoi,
146+
StandardPoiStateKey.HIDE
147+
)
148+
}
149+
selectedPoiList.clear()
150+
mapView.viewAnnotationManager.removeAllViewAnnotations()
151+
Toast.makeText(this, "Map clicked, removing selected POIs if any", Toast.LENGTH_SHORT).show()
152+
true
153+
}
154+
)
155+
}
156+
157+
private companion object {
158+
private val HELSINKI = Point.fromLngLat(24.94180921290157, 60.171227338006844)
159+
}
160+
}

app/src/main/res/values/example_descriptions.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,5 @@
107107
<string name="description_slot_layer">Showcase the usage of slot layer.</string>
108108
<string name="description_raster_particles">Showcase the usage of a raster particle layer.</string>
109109
<string name="description_clip_layer">Showcase the usage of clip layer.</string>
110+
<string name="description_standard_interactions">Showcase of the Standard Style interactions.</string>
110111
</resources>

app/src/main/res/values/example_titles.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,5 @@
109109
<string name="actvity_slot_layer">Slot layer example</string>
110110
<string name="activity_raster_particles">Raster Particles</string>
111111
<string name="activity_clip_layer">Clip layer example</string>
112+
<string name="activity_standard_interactions">Standard Style interactions</string>
112113
</resources>

0 commit comments

Comments
 (0)