Skip to content

Commit 827b26f

Browse files
committed
Update examples to use separate location providers, fix custom journey location provider.
1 parent 9191283 commit 827b26f

File tree

4 files changed

+147
-69
lines changed

4 files changed

+147
-69
lines changed

app/src/main/java/com/mapbox/maps/testapp/examples/location/CustomJourneyLocationProviderActivity.kt

+29-1
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,29 @@ import com.mapbox.maps.CameraOptions
1010
import com.mapbox.maps.MapView
1111
import com.mapbox.maps.Style
1212
import com.mapbox.maps.plugin.LocationPuck3D
13+
import com.mapbox.maps.plugin.annotation.annotations
14+
import com.mapbox.maps.plugin.annotation.generated.PointAnnotation
15+
import com.mapbox.maps.plugin.annotation.generated.PointAnnotationManager
16+
import com.mapbox.maps.plugin.annotation.generated.PointAnnotationOptions
17+
import com.mapbox.maps.plugin.annotation.generated.createPointAnnotationManager
1318
import com.mapbox.maps.plugin.gestures.OnMapClickListener
1419
import com.mapbox.maps.plugin.gestures.gestures
1520
import com.mapbox.maps.plugin.locationcomponent.CustomJourneyLocationProvider
1621
import com.mapbox.maps.plugin.locationcomponent.Journey
1722
import com.mapbox.maps.plugin.locationcomponent.location2
23+
import com.mapbox.maps.testapp.R
24+
import com.mapbox.maps.testapp.utils.BitmapUtils
25+
import java.util.*
1826

1927
/**
2028
* Example of using custom location provider.
2129
*/
2230
class CustomJourneyLocationProviderActivity : AppCompatActivity(), OnMapClickListener {
23-
2431
private val journey = Journey()
2532
private val customJourneyLocationProvider = CustomJourneyLocationProvider().apply { loadJourney(journey) }
2633
private lateinit var mapView: MapView
34+
private val annotationList = LinkedList<PointAnnotation>()
35+
private lateinit var pointAnnotationManager: PointAnnotationManager
2736

2837
@SuppressLint("SetTextI18n")
2938
override fun onCreate(savedInstanceState: Bundle?) {
@@ -42,6 +51,7 @@ class CustomJourneyLocationProviderActivity : AppCompatActivity(), OnMapClickLis
4251
}
4352
}
4453
)
54+
pointAnnotationManager = mapView.annotations.createPointAnnotationManager()
4555
mapView.getMapboxMap()
4656
.apply {
4757
setCamera(
@@ -57,6 +67,13 @@ class CustomJourneyLocationProviderActivity : AppCompatActivity(), OnMapClickLis
5767
journey.start()
5868
}
5969
}
70+
71+
journey.observeJourneyUpdates { location, bearing, locationAnimationDurationMs, bearingAnimateDurationMs ->
72+
annotationList.poll()?.let {
73+
pointAnnotationManager.delete(it)
74+
}
75+
true
76+
}
6077
}
6178

6279
private fun initClickListeners() {
@@ -80,6 +97,17 @@ class CustomJourneyLocationProviderActivity : AppCompatActivity(), OnMapClickLis
8097

8198
override fun onMapClick(point: Point): Boolean {
8299
journey.queueLocationUpdate(point)
100+
BitmapUtils.bitmapFromDrawableRes(
101+
this,
102+
R.drawable.red_marker
103+
)?.let {
104+
pointAnnotationManager.create(
105+
PointAnnotationOptions()
106+
.withPoint(point)
107+
.withIconImage(it)
108+
.withDraggable(true)
109+
).also { annotation -> annotationList.add(annotation) }
110+
}
83111
return true
84112
}
85113

app/src/main/java/com/mapbox/maps/testapp/examples/location/MultipleLocationComponentActivity.kt

+100-48
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,46 @@ package com.mapbox.maps.testapp.examples.location
33
import android.annotation.SuppressLint
44
import android.os.Bundle
55
import android.view.ViewGroup
6+
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
67
import android.widget.Button
78
import androidx.appcompat.app.AppCompatActivity
89
import com.mapbox.geojson.Point
910
import com.mapbox.maps.CameraOptions
1011
import com.mapbox.maps.MapView
12+
import com.mapbox.maps.MapboxExperimental
1113
import com.mapbox.maps.Style
12-
import com.mapbox.maps.extension.style.expressions.dsl.generated.literal
1314
import com.mapbox.maps.plugin.LocationPuck2D
1415
import com.mapbox.maps.plugin.LocationPuck3D
16+
import com.mapbox.maps.plugin.annotation.annotations
17+
import com.mapbox.maps.plugin.annotation.generated.*
1518
import com.mapbox.maps.plugin.gestures.OnMapClickListener
1619
import com.mapbox.maps.plugin.gestures.gestures
1720
import com.mapbox.maps.plugin.locationcomponent.CustomJourneyLocationProvider
1821
import com.mapbox.maps.plugin.locationcomponent.Journey
1922
import com.mapbox.maps.plugin.locationcomponent.LocationComponentPlugin2
20-
import com.mapbox.maps.plugin.locationcomponent.location2
23+
import com.mapbox.maps.testapp.R
24+
import com.mapbox.maps.testapp.utils.BitmapUtils
2125
import com.mapbox.maps.testapp.utils.LocationComponentUtils
2226
import com.mapbox.maps.testapp.utils.createLocationComponent
23-
import java.util.concurrent.CopyOnWriteArraySet
27+
import java.util.*
2428

2529
/**
2630
* Example of using multiple location component.
2731
*/
32+
@OptIn(MapboxExperimental::class)
2833
class MultipleLocationComponentActivity : AppCompatActivity(), OnMapClickListener {
29-
30-
private val journey = Journey()
31-
private val customJourneyLocationProvider = CustomJourneyLocationProvider().apply { loadJourney(journey) }
3234
private lateinit var mapView: MapView
33-
private val locationComponents = CopyOnWriteArraySet<LocationComponentPlugin2>()
35+
private val journeys = mutableListOf(Journey(speed = 150.0), Journey(speed = 100.0))
36+
private val customJourneyLocationProviders = mutableListOf(
37+
CustomJourneyLocationProvider().apply { loadJourney(journeys.first()) },
38+
CustomJourneyLocationProvider().apply { loadJourney(journeys.last()) }
39+
)
40+
private val annotationLists =
41+
mutableListOf(LinkedList<PointAnnotation>(), LinkedList<PointAnnotation>())
42+
private val locationComponents = mutableListOf<LocationComponentPlugin2>()
43+
private lateinit var pointAnnotationManager: PointAnnotationManager
44+
45+
var selectedPuck = 0
3446

3547
@SuppressLint("SetTextI18n")
3648
override fun onCreate(savedInstanceState: Bundle?) {
@@ -39,16 +51,15 @@ class MultipleLocationComponentActivity : AppCompatActivity(), OnMapClickListene
3951
setContentView(mapView)
4052
mapView.addView(
4153
Button(this).apply {
42-
layoutParams = ViewGroup.LayoutParams(
43-
ViewGroup.LayoutParams.WRAP_CONTENT,
44-
ViewGroup.LayoutParams.WRAP_CONTENT
45-
)
46-
text = "Cancel"
54+
layoutParams = ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
55+
text = "Controlling ${if (selectedPuck == 0) "Car" else "Duck"}"
4756
setOnClickListener {
48-
journey.pause()
57+
toggleControl()
58+
text = "Controlling ${if (selectedPuck == 0) "Car" else "Duck"}"
4959
}
5060
}
5161
)
62+
pointAnnotationManager = mapView.annotations.createPointAnnotationManager()
5263
mapView.getMapboxMap()
5364
.apply {
5465
setCamera(
@@ -61,59 +72,100 @@ class MultipleLocationComponentActivity : AppCompatActivity(), OnMapClickListene
6172
loadStyleUri(Style.MAPBOX_STREETS) {
6273
initLocationComponents()
6374
initClickListeners()
64-
journey.start()
75+
journeys.forEach { it.start() }
76+
}
77+
}
78+
79+
journeys.forEachIndexed { index, journey ->
80+
journey.observeJourneyUpdates { _, _, _, _ ->
81+
annotationLists[index].poll()?.let {
82+
pointAnnotationManager.delete(it)
6583
}
84+
true
6685
}
86+
}
87+
}
88+
89+
private fun toggleControl() {
90+
selectedPuck = (selectedPuck + 1) % 2
6791
}
6892

6993
private fun initClickListeners() {
7094
mapView.gestures.addOnMapClickListener(this)
7195
}
7296

7397
private fun initLocationComponents() {
98+
// Puck with pulsing car
7499
locationComponents.add(
75-
mapView.createLocationComponent(LocationComponentUtils.getNextLocationComponentOptions()).apply {
76-
setLocationProvider(customJourneyLocationProvider)
77-
enabled = true
78-
locationPuck = LocationPuck2D(
79-
topImage = null,
80-
bearingImage = null,
81-
)
82-
puckBearingEnabled = true
83-
pulsingEnabled = true
84-
}
100+
mapView.createLocationComponent(LocationComponentUtils.getNextLocationComponentOptions())
101+
.apply {
102+
setLocationProvider(customJourneyLocationProviders.first())
103+
enabled = true
104+
locationPuck = LocationPuck2D(
105+
topImage = null,
106+
bearingImage = null,
107+
)
108+
puckBearingEnabled = true
109+
pulsingEnabled = true
110+
}
85111
)
86112
locationComponents.add(
87-
mapView.createLocationComponent(LocationComponentUtils.getNextLocationComponentOptions()).apply {
88-
setLocationProvider(customJourneyLocationProvider)
89-
enabled = true
90-
locationPuck = LocationPuck3D(
91-
modelUri = "asset://sportcar.glb",
92-
modelScale = listOf(0.2f, 0.2f, 0.2f),
93-
modelTranslation = listOf(0.1f, 0.1f, 0.1f),
94-
modelRotation = listOf(0.0f, 0.0f, 180.0f)
95-
)
96-
puckBearingEnabled = true
97-
}
113+
mapView.createLocationComponent(LocationComponentUtils.getNextLocationComponentOptions())
114+
.apply {
115+
setLocationProvider(customJourneyLocationProviders.first())
116+
enabled = true
117+
locationPuck = LocationPuck3D(
118+
modelUri = "asset://sportcar.glb",
119+
modelScale = listOf(0.3f, 0.3f, 0.3f),
120+
modelTranslation = listOf(0.1f, 0.1f, 0.1f),
121+
modelRotation = listOf(0.0f, 0.0f, 180.0f)
122+
)
123+
puckBearingEnabled = true
124+
}
98125
)
126+
// Puck with pulsing duck
99127
locationComponents.add(
100-
mapView.createLocationComponent(LocationComponentUtils.getNextLocationComponentOptions()).apply {
101-
setLocationProvider(customJourneyLocationProvider)
102-
enabled = true
103-
locationPuck = LocationPuck3D(
104-
modelUri = "https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/Duck/glTF-Embedded/Duck.gltf",
105-
modelScale = listOf(0.2f, 0.2f, 0.2f),
106-
modelRotation = listOf(0f, 0f, -90f),
107-
modelTranslation = listOf(0f, 0.0f, 0.0f)
108-
)
109-
puckBearingEnabled = true
110-
}
128+
mapView.createLocationComponent(LocationComponentUtils.getNextLocationComponentOptions())
129+
.apply {
130+
setLocationProvider(customJourneyLocationProviders.last())
131+
enabled = true
132+
locationPuck = LocationPuck2D(
133+
topImage = null,
134+
bearingImage = null,
135+
)
136+
puckBearingEnabled = true
137+
pulsingEnabled = true
138+
}
139+
)
140+
locationComponents.add(
141+
mapView.createLocationComponent(LocationComponentUtils.getNextLocationComponentOptions())
142+
.apply {
143+
setLocationProvider(customJourneyLocationProviders.last())
144+
enabled = true
145+
locationPuck = LocationPuck3D(
146+
modelUri = "https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/Duck/glTF-Embedded/Duck.gltf",
147+
modelScale = listOf(0.5f, 0.5f, 0.5f),
148+
modelRotation = listOf(0f, 0f, -90f),
149+
modelTranslation = listOf(0f, 0.0f, 0.0f)
150+
)
151+
puckBearingEnabled = true
152+
}
111153
)
112-
113154
}
114155

115156
override fun onMapClick(point: Point): Boolean {
116-
journey.queueLocationUpdate(point)
157+
journeys[selectedPuck].queueLocationUpdate(point)
158+
BitmapUtils.bitmapFromDrawableRes(
159+
this,
160+
if (selectedPuck == 0) R.drawable.red_marker else R.drawable.blue_marker_view
161+
)?.let {
162+
pointAnnotationManager.create(
163+
PointAnnotationOptions()
164+
.withPoint(point)
165+
.withIconImage(it)
166+
.withDraggable(true)
167+
).also { annotation -> annotationLists[selectedPuck].add(annotation) }
168+
}
117169
return true
118170
}
119171

app/src/main/java/com/mapbox/maps/testapp/utils/LocationComponentUtils.kt

+8-9
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,15 @@ public fun MapView.createLocationComponent(locationComponentInitOptions: Locatio
1717
}
1818

1919
object LocationComponentUtils {
20-
private var custom2DLayerIdCount = 0
21-
private var custom3DLayerIdCount = 0
22-
private var custom3DSourceIdCount = 0
20+
private var customLocationComponentCount = 0
2321

2422
fun getNextLocationComponentOptions() = LocationComponentInitOptions {
25-
puck2DLayerId = "custom_location_component_2d_layer_$custom2DLayerIdCount"
26-
puck3DLayerId = "custom_location_component_3d_layer_$custom3DLayerIdCount"
27-
puck3DSourceId = "custom_location_component_3d_source_$custom3DSourceIdCount"
28-
custom2DLayerIdCount++
29-
custom3DLayerIdCount++
30-
custom3DSourceIdCount++
23+
puck2DLayerId = "custom_location_component_2d_layer_$customLocationComponentCount"
24+
puck3DLayerId = "custom_location_component_3d_layer_$customLocationComponentCount"
25+
puck3DSourceId = "custom_location_component_3d_source_$customLocationComponentCount"
26+
puck3DSourceId = "custom_location_component_top_icon_image_id_$customLocationComponentCount"
27+
puck3DSourceId = "custom_location_component_shadow_icon_image_id_$customLocationComponentCount"
28+
puck3DSourceId = "custom_location_component_bearing_icon_image_id_$customLocationComponentCount"
29+
customLocationComponentCount++
3130
}
3231
}

plugin-locationcomponent/src/main/java/com/mapbox/maps/plugin/locationcomponent/CustomJourneyLocationProvider.kt

+10-11
Original file line numberDiff line numberDiff line change
@@ -143,26 +143,25 @@ class Journey(val speed: Double = 100.0, val angularSpeed: Double = 500.0) {
143143
private fun drainQueue() {
144144
remainingPoints.peek()?.let { data ->
145145
observers.forEach {
146-
if (it.onNewData(
146+
if (!it.onNewData(
147147
data.location,
148148
data.bearing,
149149
data.locationAnimationDurationMs,
150150
data.bearingAnimateDurationMs
151151
)
152152
) {
153-
if (isPlaying) {
154-
handler.postDelayed(
155-
{
156-
remainingPoints.poll()
157-
drainQueue()
158-
},
159-
max(data.locationAnimationDurationMs, data.bearingAnimateDurationMs)
160-
)
161-
}
162-
} else {
163153
observers.remove(it)
164154
}
165155
}
156+
if (isPlaying) {
157+
handler.postDelayed(
158+
{
159+
remainingPoints.poll()
160+
drainQueue()
161+
},
162+
max(data.locationAnimationDurationMs, data.bearingAnimateDurationMs)
163+
)
164+
}
166165
}
167166
}
168167

0 commit comments

Comments
 (0)