Skip to content

Commit 6920b2b

Browse files
jushgithub-actions[bot]
authored andcommitted
Access array of doubles directly for LineString and MultiPoint (#9537)
This PR uses direct access to the `double []` provided by the new `FlattenListOfPoints` in GeoJSON `MultiPoint` and `LineString` when marshalling through JNI. For `Point` there's no need to change it since we were already doing two JNI calls (latitude, longitude). The changes requires Mapbox GeoJSON 7.10.0 which includes: - mapbox/mapbox-java#1630 GitOrigin-RevId: 26168ab0d9f7df6a1a42d9005466e01c02ea00bf
1 parent 8bda2eb commit 6920b2b

4 files changed

Lines changed: 68 additions & 31 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ Mapbox welcomes participation and contributions from everyone.
55
> **16 KB Page Size Support:** Starting with version 11.7.0 and 10.19.0, **NDK 27 is supported** with dedicated artifacts that include [support for 16 KB page sizes](https://developer.android.com/guide/practices/page-sizes). If your app does not require 16 KB page size support, you can keep using our default artifacts without `-ndk27` suffix. For more information about our NDK support, see https://docs.mapbox.com/android/maps/guides/#ndk-support
66
77
# main
8+
## Features ✨ and improvements 🏁
89
* Introduce new `LineLayer.lineElevationGroundScale` property to scale elevated lines with terrain exaggeration.
910
* Promote elevated lines properties to stable: `LineLayer.lineZOffset` and `LineLayer.lineElevationReference`.
11+
* Improve data serialization speed when using `LineString` or `MultiPoint` in `GeoJsonSource`.
1012

1113
# 11.19.0-rc.1
1214

app/src/main/java/com/mapbox/maps/testapp/examples/linesandpolygons/SnakingDirectionsRouteActivity.kt

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import com.mapbox.geojson.Feature
1818
import com.mapbox.geojson.FeatureCollection
1919
import com.mapbox.geojson.LineString
2020
import com.mapbox.geojson.Point
21+
import com.mapbox.maps.MapboxMap
2122
import com.mapbox.maps.Style
2223
import com.mapbox.maps.extension.style.image.image
2324
import com.mapbox.maps.extension.style.layers.generated.lineLayer
@@ -150,30 +151,56 @@ class SnakingDirectionsRouteActivity : AppCompatActivity() {
150151
.flatMap { it.coordinates() }
151152
.let(LineString::fromLngLats)
152153

153-
val features = List(ANIMATION_STEPS) { index ->
154-
Feature.fromGeometry(
154+
val features = MutableList(ANIMATION_STEPS) { index ->
155155
TurfMisc.lineSliceAlong(
156156
line,
157157
singleAnimationDistance * index,
158158
singleAnimationDistance * (index + 1),
159159
TurfConstants.UNIT_METERS
160160
)
161-
)
162161
}
163162

164163
val map = binding.mapView.mapboxMap
165-
(0..ANIMATION_STEPS).forEach { index ->
166164
binding.mapView.postDelayed(
167165
{
168-
if (map.isValid()) {
169-
map.getStyle {
170-
(it.getSource(DRIVING_ROUTE_POLYLINE_SOURCE_ID) as? GeoJsonSource)
171-
?.featureCollection(FeatureCollection.fromFeatures(features.take(index)))
172-
}
173-
}
166+
setCurrentLine(map, features, features.removeAt(0))
174167
},
175-
DRAW_SPEED_MILLISECONDS * index
168+
DRAW_SPEED_MILLISECONDS
176169
)
170+
}
171+
172+
private fun setCurrentLine(
173+
map: MapboxMap,
174+
features: MutableList<LineString>,
175+
currentLineString: LineString
176+
) {
177+
if (map.isValid()) {
178+
// Draw current line
179+
map.getStyle {
180+
(it.getSource(DRIVING_ROUTE_POLYLINE_SOURCE_ID) as? GeoJsonSource)
181+
?.geometry(currentLineString)
182+
}
183+
184+
// Extend the current line with the next segment
185+
if (features.isNotEmpty()) {
186+
val currentSegmentLngLats = currentLineString.flattenCoordinates().flattenLngLatArray
187+
val nextSegmentLngLats = features.removeAt(0).flattenCoordinates().flattenLngLatArray
188+
// Merge the current segment and the next one
189+
val lngLats = DoubleArray(nextSegmentLngLats.size + currentSegmentLngLats.size)
190+
System.arraycopy(currentSegmentLngLats, 0, lngLats, 0, currentSegmentLngLats.size)
191+
System.arraycopy(
192+
nextSegmentLngLats,
193+
0,
194+
lngLats,
195+
currentSegmentLngLats.size,
196+
nextSegmentLngLats.size
197+
)
198+
val nextLine = LineString.fromFlattenArrayOfPoints(lngLats, null)
199+
binding.mapView.postDelayed(
200+
{ setCurrentLine(map, features, nextLine) },
201+
DRAW_SPEED_MILLISECONDS
202+
)
203+
}
177204
}
178205
}
179206

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

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ class SimulateRouteLocationProvider(
2828
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
2929
private var emitLocationsJob: Job? = null
3030
private val totalRouteLength by lazy { TurfMeasurement.length(route, TurfConstants.UNIT_CENTIMETERS) }
31-
private val routeStartPoint = route.coordinates().first()
31+
private val routeStartPoint = Point.fromLngLat(
32+
route.flattenCoordinates().flattenLngLatArray[0],
33+
route.flattenCoordinates().flattenLngLatArray[1]
34+
)
3235
private val locationConsumers = CopyOnWriteArraySet<LocationConsumer>()
3336
private var isFakeLocationEmitting = false
34-
private val iterator = route.coordinates().toMutableList().iterator()
3537

3638
override fun registerLocationConsumer(locationConsumer: LocationConsumer) {
3739
locationConsumers.add(locationConsumer)
@@ -54,16 +56,18 @@ class SimulateRouteLocationProvider(
5456
emitLocationsJob = scope.launch {
5557
// Make sure previous job is cancelled before starting a new one
5658
previousEmitLocationsJob?.cancelAndJoin()
57-
var lastLocation: Point = if (iterator.hasNext()) {
58-
iterator.next()
59-
} else {
60-
Point.fromLngLat(0.0, 0.0)
61-
}
62-
while (isActive && iterator.hasNext()) {
63-
val point = iterator.next().insertProgressInfo()
59+
val flattenCoordinates = route.flattenCoordinates()
60+
var lastLocation: Point = routeStartPoint
61+
var nextLocationIdx = 1
62+
val flattenLngLatArray = flattenCoordinates.flattenLngLatArray
63+
while (isActive && nextLocationIdx < flattenCoordinates.size()) {
64+
val point = Point.fromLngLat(
65+
flattenLngLatArray[nextLocationIdx * 2],
66+
flattenLngLatArray[(nextLocationIdx * 2) + 1]
67+
).insertProgressInfo()
6468
val bearing = TurfMeasurement.bearing(lastLocation, point)
6569
lastLocation = point
66-
iterator.remove()
70+
nextLocationIdx++
6771

6872
withContext(Dispatchers.Main) {
6973
locationConsumers.forEach { it.onLocationUpdated(point) }

compose-app/src/main/java/com/mapbox/maps/compose/testapp/examples/utils/SimulateRouteLocationProvider.kt

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ public class SimulateRouteLocationProvider(
2828
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
2929
private var emitLocationsJob: Job? = null
3030
private val totalRouteLength by lazy { TurfMeasurement.length(route, TurfConstants.UNIT_CENTIMETERS) }
31-
private val routeStartPoint = route.coordinates().first()
31+
private val routeStartPoint = Point.fromLngLat(
32+
route.flattenCoordinates().flattenLngLatArray[0],
33+
route.flattenCoordinates().flattenLngLatArray[1]
34+
)
3235
private val locationConsumers = CopyOnWriteArraySet<LocationConsumer>()
3336
private var isFakeLocationEmitting = false
34-
private val iterator = route.coordinates().toMutableList().iterator()
3537

3638
override fun registerLocationConsumer(locationConsumer: LocationConsumer) {
3739
locationConsumers.add(locationConsumer)
@@ -54,16 +56,18 @@ public class SimulateRouteLocationProvider(
5456
emitLocationsJob = scope.launch {
5557
// Make sure previous job is cancelled before starting a new one
5658
previousEmitLocationsJob?.cancelAndJoin()
57-
var lastLocation: Point = if (iterator.hasNext()) {
58-
iterator.next()
59-
} else {
60-
Point.fromLngLat(0.0, 0.0)
61-
}
62-
while (isActive && iterator.hasNext()) {
63-
val point = iterator.next().insertProgressInfo()
59+
val flattenCoordinates = route.flattenCoordinates()
60+
var lastLocation: Point = routeStartPoint
61+
var nextLocationIdx = 1
62+
val flattenLngLatArray = flattenCoordinates.flattenLngLatArray
63+
while (isActive && nextLocationIdx < flattenCoordinates.size()) {
64+
val point = Point.fromLngLat(
65+
flattenLngLatArray[nextLocationIdx * 2],
66+
flattenLngLatArray[(nextLocationIdx * 2) + 1]
67+
).insertProgressInfo()
6468
val bearing = TurfMeasurement.bearing(lastLocation, point)
6569
lastLocation = point
66-
iterator.remove()
70+
nextLocationIdx++
6771

6872
withContext(Dispatchers.Main) {
6973
locationConsumers.forEach { it.onLocationUpdated(point) }

0 commit comments

Comments
 (0)