Skip to content

Commit ebd18f6

Browse files
authored
Support strong typed geometry (#528)
* strong typed Turf geometry support for annotations API
1 parent 41fea7a commit ebd18f6

35 files changed

+533
-269
lines changed

CHANGELOG.md

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ snapshotter.setCamera(CameraOptions(center: Point(...)));
4444
4545
final snapshotImage = await snapshotter.start()
4646
```
47-
##### Map wiget snapshotting
47+
##### Map widget snapshotting
4848

4949
Create snapshots of the map displayed in the `MapWidget` with `MapboxMap.snapshot()`. This new feature allows you to capture a static image of the current map view.
5050

@@ -60,6 +60,10 @@ Please note that the `snapshot()` method works best if the Mapbox Map is fully l
6060

6161
#### ⚠️ Breaking changes
6262

63+
##### Leveraging [Turf](https://pub.dev/packages/turf)'s geometries as a replacement for Map<String, Any?>
64+
65+
You now have the convenience of directly initializing annotations with Turf's geometries, eliminating the need for converting geometry to JSON.
66+
6367
##### Geographical position represented by `Point`s
6468

6569
Geographical positions denoted by `Map<String?, Object?>?` are migrated to [`Point`](https://pub.dev/documentation/turf/latest/turf/Point-class.html) type from [turf](https://pub.dev/packages/turf) package.
@@ -102,7 +106,56 @@ onTapListener: { (context)
102106
...
103107
}
104108
```
109+
##### Creating an annotation with a given geometry
110+
*Before:*
111+
```dart
112+
PointAnnotationOptions(
113+
geometry: Point(
114+
coordinates: Position(0.381457, 6.687337)
115+
).toJson()
116+
)
117+
PolygonAnnotationOptions(
118+
geometry: Polygon(coordinates: [
119+
[
120+
Position(-3.363937, -10.733102),
121+
Position(1.754703, -19.716317),
122+
Position(-15.747196, -21.085074),
123+
Position(-3.363937, -10.733102)
124+
]
125+
]).toJson()
126+
)
127+
PolylineAnnotationOptions(
128+
geometry: LineString(coordinates: [
129+
Position(1.0, 2.0),
130+
Position(10.0, 20.0)
131+
]).toJson()
132+
)
133+
```
105134

135+
*After:*
136+
```dart
137+
PointAnnotationOptions(
138+
geometry: Point(
139+
coordinates: Position(0.381457, 6.687337)
140+
)
141+
)
142+
PolygonAnnotationOptions(
143+
geometry: Polygon(coordinates: [
144+
[
145+
Position(-3.363937, -10.733102),
146+
Position(1.754703, -19.716317),
147+
Position(-15.747196, -21.085074),
148+
Position(-3.363937, -10.733102)
149+
]
150+
])
151+
)
152+
PolylineAnnotationOptions(
153+
geometry: LineString(coordinates: [
154+
Position(1.0, 2.0),
155+
Position(10.0, 20.0)
156+
])
157+
)
158+
```
106159

107160
* Fix camera center not applied from map init options.
108161
* [iOS] Free up resources upon map widget disposal. This should help to reduce the amount of used memory when previously shown map widget is removed from the widget tree.

android/src/main/kotlin/com/mapbox/maps/mapbox_maps/Extentions.kt

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -284,36 +284,6 @@ fun Map<String?, Any?>.toPoint(): Point {
284284
return Point.fromLngLat(longitude, latitude, boundingBox)
285285
}
286286

287-
fun Map<String?, Any?>.toPoints(): List<Point> {
288-
return (this["coordinates"] as List<List<Double>>).map {
289-
Point.fromLngLat(it.first(), it.last())
290-
}
291-
}
292-
293-
fun Map<String?, Any?>.toPointsList(): List<List<Point>> {
294-
return (this["coordinates"] as List<List<List<Double>>>).map {
295-
it.map {
296-
Point.fromLngLat(it.first(), it.last())
297-
}
298-
}
299-
}
300-
301-
fun Map<String?, Any?>.toLineString(): LineString {
302-
return LineString.fromLngLats(
303-
(this["coordinates"] as List<List<Double>>).map {
304-
Point.fromLngLat(it.first(), it.last())
305-
}
306-
)
307-
}
308-
309-
fun Map<String?, Any?>.toPolygon(): Polygon {
310-
return Polygon.fromLngLats(
311-
(this["coordinates"] as List<List<List<Double>>>).map {
312-
it.map { Point.fromLngLat(it.first(), it.last()) }
313-
}
314-
)
315-
}
316-
317287
fun CoordinateBounds.toCoordinateBounds() =
318288
com.mapbox.maps.CoordinateBounds(southwest, northeast, infiniteBounds)
319289

@@ -489,33 +459,6 @@ fun com.mapbox.maps.Size.toFLTSize(context: Context): Size {
489459
return Size(width.toLogicalPixels(context), height.toLogicalPixels(context))
490460
}
491461

492-
fun Point.toMap(): Map<String?, Any> {
493-
val map = mutableMapOf<String?, Any>()
494-
map["coordinates"] = coordinates()
495-
bbox()?.let {
496-
map["bbox"] = mapOf(Pair("southwest", it.southwest()), Pair("northeast", it.northeast()))
497-
}
498-
return map
499-
}
500-
501-
fun Polygon.toMap(): Map<String?, Any> {
502-
val map = mutableMapOf<String?, Any>()
503-
map["coordinates"] = coordinates().map { it.map { it.coordinates() } }
504-
bbox()?.let {
505-
map["bbox"] = mapOf(Pair("southwest", it.southwest()), Pair("northeast", it.northeast()))
506-
}
507-
return map
508-
}
509-
510-
fun LineString.toMap(): Map<String?, Any> {
511-
val map = mutableMapOf<String?, Any>()
512-
map["coordinates"] = coordinates().map { it.coordinates() }
513-
bbox()?.let {
514-
map["bbox"] = mapOf(Pair("southwest", it.southwest()), Pair("northeast", it.northeast()))
515-
}
516-
return map
517-
}
518-
519462
fun com.mapbox.maps.ScreenCoordinate.toFLTScreenCoordinate(context: Context): ScreenCoordinate {
520463
return ScreenCoordinate(x.toLogicalPixels(context), y.toLogicalPixels(context))
521464
}

android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/CircleAnnotationController.kt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
package com.mapbox.maps.mapbox_maps.annotation
33

44
import com.mapbox.maps.mapbox_maps.pigeons.*
5-
import com.mapbox.maps.mapbox_maps.toMap
6-
import com.mapbox.maps.mapbox_maps.toPoint
75
import com.mapbox.maps.plugin.annotation.generated.CircleAnnotationManager
86
import toCirclePitchAlignment
97
import toCirclePitchScale
@@ -124,7 +122,7 @@ class CircleAnnotationController(private val delegate: ControllerDelegate) : _Ci
124122
private fun updateAnnotation(annotation: CircleAnnotation): com.mapbox.maps.plugin.annotation.generated.CircleAnnotation {
125123
val originalAnnotation = annotationMap[annotation.id]!!
126124
annotation.geometry?.let {
127-
originalAnnotation.geometry = it.toPoint()
125+
originalAnnotation.geometry = it
128126
}
129127
annotation.circleSortKey?.let {
130128
originalAnnotation.circleSortKey = it
@@ -267,7 +265,7 @@ class CircleAnnotationController(private val delegate: ControllerDelegate) : _Ci
267265
fun com.mapbox.maps.plugin.annotation.generated.CircleAnnotation.toFLTCircleAnnotation(): CircleAnnotation {
268266
return CircleAnnotation(
269267
id = id,
270-
geometry = geometry.toMap(),
268+
geometry = geometry,
271269
circleSortKey = circleSortKey,
272270
circleBlur = circleBlur,
273271
// colorInt is 32 bit and may be bigger than MAX_INT, so transfer to UInt firstly and then to Long.
@@ -284,7 +282,7 @@ fun com.mapbox.maps.plugin.annotation.generated.CircleAnnotation.toFLTCircleAnno
284282
fun CircleAnnotationOptions.toCircleAnnotationOptions(): com.mapbox.maps.plugin.annotation.generated.CircleAnnotationOptions {
285283
val options = com.mapbox.maps.plugin.annotation.generated.CircleAnnotationOptions()
286284
this.geometry?.let {
287-
options.withPoint(it.toPoint())
285+
options.withPoint(it)
288286
}
289287
this.circleSortKey?.let {
290288
options.withCircleSortKey(it)

android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/PointAnnotationController.kt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ package com.mapbox.maps.mapbox_maps.annotation
44
import android.graphics.Bitmap
55
import android.graphics.BitmapFactory
66
import com.mapbox.maps.mapbox_maps.pigeons.*
7-
import com.mapbox.maps.mapbox_maps.toMap
8-
import com.mapbox.maps.mapbox_maps.toPoint
97
import com.mapbox.maps.plugin.annotation.generated.PointAnnotationManager
108
import toFLTIconAnchor
119
import toFLTIconPitchAlignment
@@ -147,7 +145,7 @@ class PointAnnotationController(private val delegate: ControllerDelegate) : _Poi
147145
private fun updateAnnotation(annotation: PointAnnotation): com.mapbox.maps.plugin.annotation.generated.PointAnnotation {
148146
val originalAnnotation = annotationMap[annotation.id]!!
149147
annotation.geometry?.let {
150-
originalAnnotation.geometry = it.toPoint()
148+
originalAnnotation.geometry = it
151149
}
152150
annotation.image?.let {
153151
originalAnnotation.iconImageBitmap = (BitmapFactory.decodeByteArray(it, 0, it.size))
@@ -827,7 +825,7 @@ class PointAnnotationController(private val delegate: ControllerDelegate) : _Poi
827825
fun com.mapbox.maps.plugin.annotation.generated.PointAnnotation.toFLTPointAnnotation(): PointAnnotation {
828826
return PointAnnotation(
829827
id = id,
830-
geometry = geometry.toMap(),
828+
geometry = geometry,
831829
image = iconImageBitmap?.let {
832830
ByteArrayOutputStream().also { stream ->
833831
it.compress(Bitmap.CompressFormat.PNG, 100, stream)
@@ -875,7 +873,7 @@ fun com.mapbox.maps.plugin.annotation.generated.PointAnnotation.toFLTPointAnnota
875873
fun PointAnnotationOptions.toPointAnnotationOptions(): com.mapbox.maps.plugin.annotation.generated.PointAnnotationOptions {
876874
val options = com.mapbox.maps.plugin.annotation.generated.PointAnnotationOptions()
877875
this.geometry?.let {
878-
options.withPoint(it.toPoint())
876+
options.withPoint(it)
879877
}
880878
this.image?.let {
881879
options.withIconImage(BitmapFactory.decodeByteArray(it, 0, it.size))

android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/PolygonAnnotationController.kt

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
package com.mapbox.maps.mapbox_maps.annotation
33

44
import com.mapbox.maps.mapbox_maps.pigeons.*
5-
import com.mapbox.maps.mapbox_maps.toMap
6-
import com.mapbox.maps.mapbox_maps.toPointsList
7-
import com.mapbox.maps.mapbox_maps.toPolygon
85
import com.mapbox.maps.plugin.annotation.generated.PolygonAnnotationManager
96
import toFLTFillTranslateAnchor
107
import toFillTranslateAnchor
@@ -121,7 +118,7 @@ class PolygonAnnotationController(private val delegate: ControllerDelegate) : _P
121118
private fun updateAnnotation(annotation: PolygonAnnotation): com.mapbox.maps.plugin.annotation.generated.PolygonAnnotation {
122119
val originalAnnotation = annotationMap[annotation.id]!!
123120
annotation.geometry?.let {
124-
originalAnnotation.geometry = it.toPolygon()
121+
originalAnnotation.geometry = it
125122
}
126123
annotation.fillSortKey?.let {
127124
originalAnnotation.fillSortKey = it
@@ -233,7 +230,7 @@ class PolygonAnnotationController(private val delegate: ControllerDelegate) : _P
233230
fun com.mapbox.maps.plugin.annotation.generated.PolygonAnnotation.toFLTPolygonAnnotation(): PolygonAnnotation {
234231
return PolygonAnnotation(
235232
id = id,
236-
geometry = geometry.toMap(),
233+
geometry = geometry,
237234
fillSortKey = fillSortKey,
238235
// colorInt is 32 bit and may be bigger than MAX_INT, so transfer to UInt firstly and then to Long.
239236
fillColor = fillColorInt?.toUInt()?.toLong(),
@@ -247,7 +244,7 @@ fun com.mapbox.maps.plugin.annotation.generated.PolygonAnnotation.toFLTPolygonAn
247244
fun PolygonAnnotationOptions.toPolygonAnnotationOptions(): com.mapbox.maps.plugin.annotation.generated.PolygonAnnotationOptions {
248245
val options = com.mapbox.maps.plugin.annotation.generated.PolygonAnnotationOptions()
249246
this.geometry?.let {
250-
options.withPoints(it.toPointsList())
247+
options.withGeometry(it)
251248
}
252249
this.fillSortKey?.let {
253250
options.withFillSortKey(it)

android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/PolylineAnnotationController.kt

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
package com.mapbox.maps.mapbox_maps.annotation
33

44
import com.mapbox.maps.mapbox_maps.pigeons.*
5-
import com.mapbox.maps.mapbox_maps.toLineString
6-
import com.mapbox.maps.mapbox_maps.toMap
7-
import com.mapbox.maps.mapbox_maps.toPoints
85
import com.mapbox.maps.plugin.annotation.generated.PolylineAnnotationManager
96
import toFLTLineCap
107
import toFLTLineJoin
@@ -125,7 +122,7 @@ class PolylineAnnotationController(private val delegate: ControllerDelegate) : _
125122
private fun updateAnnotation(annotation: PolylineAnnotation): com.mapbox.maps.plugin.annotation.generated.PolylineAnnotation {
126123
val originalAnnotation = annotationMap[annotation.id]!!
127124
annotation.geometry?.let {
128-
originalAnnotation.geometry = it.toLineString()
125+
originalAnnotation.geometry = it
129126
}
130127
annotation.lineJoin?.let {
131128
originalAnnotation.lineJoin = it.toLineJoin()
@@ -365,7 +362,7 @@ class PolylineAnnotationController(private val delegate: ControllerDelegate) : _
365362
fun com.mapbox.maps.plugin.annotation.generated.PolylineAnnotation.toFLTPolylineAnnotation(): PolylineAnnotation {
366363
return PolylineAnnotation(
367364
id = id,
368-
geometry = geometry.toMap(),
365+
geometry = geometry,
369366
lineJoin = lineJoin?.toFLTLineJoin(),
370367
lineSortKey = lineSortKey,
371368
lineBlur = lineBlur,
@@ -385,7 +382,7 @@ fun com.mapbox.maps.plugin.annotation.generated.PolylineAnnotation.toFLTPolyline
385382
fun PolylineAnnotationOptions.toPolylineAnnotationOptions(): com.mapbox.maps.plugin.annotation.generated.PolylineAnnotationOptions {
386383
val options = com.mapbox.maps.plugin.annotation.generated.PolylineAnnotationOptions()
387384
this.geometry?.let {
388-
options.withPoints(it.toPoints())
385+
options.withGeometry(it)
389386
}
390387
this.lineJoin?.let {
391388
options.withLineJoin(it.toLineJoin())

android/src/main/kotlin/com/mapbox/maps/mapbox_maps/mapping/turf/TurfAdapters.kt

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.mapbox.maps.mapbox_maps.mapping.turf
22

3-
import com.mapbox.geojson.Point
3+
import com.mapbox.geojson.*
44

55
fun Point.toList(): List<Any?> {
66
return listOf(mapOf("coordinates" to coordinates()))
@@ -14,4 +14,38 @@ object PointDecoder {
1414

1515
return Point.fromLngLat(coordinates[0], coordinates[1])
1616
}
17+
}
18+
19+
fun LineString.toList(): List<Any?> {
20+
return listOf(mapOf("coordinates" to coordinates().map { it.coordinates() }))
21+
}
22+
23+
object LineStringDecoder {
24+
@Suppress("UNCHECKED_CAST")
25+
fun fromList(list: List<Any?>): LineString {
26+
val rawData = list.first() as Map<String, Any>
27+
28+
return LineString.fromLngLats(
29+
(rawData["coordinates"] as List<List<Double>>).map {
30+
Point.fromLngLat(it.first(), it.last())
31+
}
32+
)
33+
}
34+
}
35+
36+
fun Polygon.toList(): List<Any?> {
37+
return listOf(mapOf("coordinates" to coordinates().map { it.map { it.coordinates() } }))
38+
}
39+
40+
object PolygonDecoder {
41+
@Suppress("UNCHECKED_CAST")
42+
fun fromList(list: List<Any?>): Polygon {
43+
val rawData = list.first() as Map<String, Any>
44+
45+
return Polygon.fromLngLats(
46+
(rawData["coordinates"] as List<List<List<Double>>>).map {
47+
it.map { Point.fromLngLat(it.first(), it.last()) }
48+
}
49+
)
50+
}
1751
}

0 commit comments

Comments
 (0)