From 04f23fa4bd4a8de301c426347084aa8fc97f5c56 Mon Sep 17 00:00:00 2001 From: Roman Laitarenko Date: Tue, 11 Nov 2025 11:31:56 +0200 Subject: [PATCH 1/2] allAnnotations + customData --- .../annotation/CircleAnnotationController.kt | 13 ++++ .../annotation/PointAnnotationController.kt | 13 ++++ .../annotation/PolygonAnnotationController.kt | 13 ++++ .../PolylineAnnotationController.kt | 13 ++++ .../pigeons/CircleAnnotationMessenger.kt | 68 +++++++++++++++++-- .../pigeons/PointAnnotationMessenger.kt | 43 ++++++++++-- .../pigeons/PolygonAnnotationMessenger.kt | 68 +++++++++++++++++-- .../pigeons/PolylineAnnotationMessenger.kt | 68 +++++++++++++++++-- .../annotations/circle_annotation_test.dart | 5 ++ .../annotations/point_annotation_test.dart | 5 ++ .../annotations/polygon_annotation_test.dart | 5 ++ .../annotations/polyline_annotation_test.dart | 5 ++ .../integration_test/map_interface_test.dart | 3 +- .../Annotations/BaseAnnotationMessenger.swift | 4 ++ .../CircleAnnotationController.swift | 13 +++- .../PointAnnotationController.swift | 13 +++- .../PolygonAnnotationController.swift | 13 +++- .../PolylineAnnotationController.swift | 13 +++- .../Generated/CircleAnnotationMessenger.swift | 32 ++++++++- .../Generated/PointAnnotationMessenger.swift | 32 ++++++++- .../PolygonAnnotationMessenger.swift | 32 ++++++++- .../PolylineAnnotationMessenger.swift | 32 ++++++++- .../Classes/TurfAdapters.swift | 37 ++++++++++ .../annotation/circle_annotation_manager.dart | 4 ++ .../annotation/point_annotation_manager.dart | 4 ++ .../polygon_annotation_manager.dart | 4 ++ .../polyline_annotation_manager.dart | 4 ++ .../pigeons/circle_annotation_messenger.dart | 52 +++++++++++++- .../pigeons/point_annotation_messenger.dart | 52 +++++++++++++- .../pigeons/polygon_annotation_messenger.dart | 52 +++++++++++++- .../polyline_annotation_messenger.dart | 52 +++++++++++++- 31 files changed, 721 insertions(+), 46 deletions(-) diff --git a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/CircleAnnotationController.kt b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/CircleAnnotationController.kt index 0cc5db88b..02ac00d5a 100644 --- a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/CircleAnnotationController.kt +++ b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/CircleAnnotationController.kt @@ -1,6 +1,7 @@ // This file is generated. package com.mapbox.maps.mapbox_maps.annotation +import com.google.gson.Gson import com.mapbox.maps.mapbox_maps.pigeons.* import com.mapbox.maps.plugin.annotation.generated.CircleAnnotationManager import toCircleElevationReference @@ -16,6 +17,14 @@ class CircleAnnotationController(private val delegate: ControllerDelegate) : _Ci private val annotationMap = mutableMapOf() private val managerCreateAnnotationMap = mutableMapOf>() + override fun getAnnotations( + managerId: String, + callback: (Result>) -> Unit + ) { + val manager = delegate.getManager(managerId) as CircleAnnotationManager + callback(Result.success(manager.annotations.map { it.toFLTCircleAnnotation() })) + } + override fun create( managerId: String, annotationOption: CircleAnnotationOptions, @@ -490,6 +499,7 @@ fun com.mapbox.maps.plugin.annotation.generated.CircleAnnotation.toFLTCircleAnno circleStrokeColor = circleStrokeColorInt?.toUInt()?.toLong(), circleStrokeOpacity = circleStrokeOpacity, circleStrokeWidth = circleStrokeWidth, + customData = if (getData() != null) Gson().fromJson>(getData()!!, Map::class.java) else null ) } @@ -525,6 +535,9 @@ fun CircleAnnotationOptions.toCircleAnnotationOptions(): com.mapbox.maps.plugin. this.circleStrokeWidth?.let { options.withCircleStrokeWidth(it) } + this.customData?.let { + options.withData(Gson().toJsonTree(it)) + } return options } // End of generated file. \ No newline at end of file diff --git a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/PointAnnotationController.kt b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/PointAnnotationController.kt index 7d319f857..c20a6a8ab 100644 --- a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/PointAnnotationController.kt +++ b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/PointAnnotationController.kt @@ -3,6 +3,7 @@ package com.mapbox.maps.mapbox_maps.annotation import android.graphics.Bitmap import android.graphics.BitmapFactory +import com.google.gson.Gson import com.mapbox.maps.mapbox_maps.pigeons.* import com.mapbox.maps.plugin.annotation.generated.PointAnnotationManager import toFLTIconAnchor @@ -39,6 +40,14 @@ class PointAnnotationController(private val delegate: ControllerDelegate) : _Poi private val annotationMap = mutableMapOf() private val managerCreateAnnotationMap = mutableMapOf>() + override fun getAnnotations( + managerId: String, + callback: (Result>) -> Unit + ) { + val manager = delegate.getManager(managerId) as PointAnnotationManager + callback(Result.success(manager.annotations.map { it.toFLTPointAnnotation() })) + } + override fun create( managerId: String, annotationOption: PointAnnotationOptions, @@ -1781,6 +1790,7 @@ fun com.mapbox.maps.plugin.annotation.generated.PointAnnotation.toFLTPointAnnota textHaloWidth = textHaloWidth, textOcclusionOpacity = textOcclusionOpacity, textOpacity = textOpacity, + customData = if (getData() != null) Gson().fromJson>(getData()!!, Map::class.java) else null ) } @@ -1900,6 +1910,9 @@ fun PointAnnotationOptions.toPointAnnotationOptions(): com.mapbox.maps.plugin.an this.textOpacity?.let { options.withTextOpacity(it) } + this.customData?.let { + options.withData(Gson().toJsonTree(it)) + } return options } // End of generated file. \ No newline at end of file diff --git a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/PolygonAnnotationController.kt b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/PolygonAnnotationController.kt index 49e6942ce..9264cffef 100644 --- a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/PolygonAnnotationController.kt +++ b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/PolygonAnnotationController.kt @@ -1,6 +1,7 @@ // This file is generated. package com.mapbox.maps.mapbox_maps.annotation +import com.google.gson.Gson import com.mapbox.maps.mapbox_maps.pigeons.* import com.mapbox.maps.plugin.annotation.generated.PolygonAnnotationManager import toFLTFillElevationReference @@ -12,6 +13,14 @@ class PolygonAnnotationController(private val delegate: ControllerDelegate) : _P private val annotationMap = mutableMapOf() private val managerCreateAnnotationMap = mutableMapOf>() + override fun getAnnotations( + managerId: String, + callback: (Result>) -> Unit + ) { + val manager = delegate.getManager(managerId) as PolygonAnnotationManager + callback(Result.success(manager.annotations.map { it.toFLTPolygonAnnotation() })) + } + override fun create( managerId: String, annotationOption: PolygonAnnotationOptions, @@ -492,6 +501,7 @@ fun com.mapbox.maps.plugin.annotation.generated.PolygonAnnotation.toFLTPolygonAn // colorInt is 32 bit and may be bigger than MAX_INT, so transfer to UInt firstly and then to Long. fillTunnelStructureColor = fillTunnelStructureColorInt?.toUInt()?.toLong(), fillZOffset = fillZOffset, + customData = if (getData() != null) Gson().fromJson>(getData()!!, Map::class.java) else null ) } @@ -530,6 +540,9 @@ fun PolygonAnnotationOptions.toPolygonAnnotationOptions(): com.mapbox.maps.plugi this.fillZOffset?.let { options.withFillZOffset(it) } + this.customData?.let { + options.withData(Gson().toJsonTree(it)) + } return options } // End of generated file. \ No newline at end of file diff --git a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/PolylineAnnotationController.kt b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/PolylineAnnotationController.kt index 68315afa9..af95efc5b 100644 --- a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/PolylineAnnotationController.kt +++ b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/PolylineAnnotationController.kt @@ -1,6 +1,7 @@ // This file is generated. package com.mapbox.maps.mapbox_maps.annotation +import com.google.gson.Gson import com.mapbox.maps.extension.style.utils.ColorUtils import com.mapbox.maps.mapbox_maps.pigeons.* import com.mapbox.maps.plugin.annotation.generated.PolylineAnnotationManager @@ -19,6 +20,14 @@ class PolylineAnnotationController(private val delegate: ControllerDelegate) : _ private val annotationMap = mutableMapOf() private val managerCreateAnnotationMap = mutableMapOf>() + override fun getAnnotations( + managerId: String, + callback: (Result>) -> Unit + ) { + val manager = delegate.getManager(managerId) as PolylineAnnotationManager + callback(Result.success(manager.annotations.map { it.toFLTPolylineAnnotation() })) + } + override fun create( managerId: String, annotationOption: PolylineAnnotationOptions, @@ -877,6 +886,7 @@ fun com.mapbox.maps.plugin.annotation.generated.PolylineAnnotation.toFLTPolyline lineOpacity = lineOpacity, linePattern = linePattern, lineWidth = lineWidth, + customData = if (getData() != null) Gson().fromJson>(getData()!!, Map::class.java) else null ) } @@ -924,6 +934,9 @@ fun PolylineAnnotationOptions.toPolylineAnnotationOptions(): com.mapbox.maps.plu this.lineWidth?.let { options.withLineWidth(it) } + this.customData?.let { + options.withData(Gson().toJsonTree(it)) + } return options } // End of generated file. \ No newline at end of file diff --git a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/CircleAnnotationMessenger.kt b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/CircleAnnotationMessenger.kt index b625ef5e9..1700e92d3 100644 --- a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/CircleAnnotationMessenger.kt +++ b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/CircleAnnotationMessenger.kt @@ -33,6 +33,31 @@ private fun wrapError(exception: Throwable): List { ) } } +private fun deepEqualsCircleAnnotationMessenger(a: Any?, b: Any?): Boolean { + if (a is ByteArray && b is ByteArray) { + return a.contentEquals(b) + } + if (a is IntArray && b is IntArray) { + return a.contentEquals(b) + } + if (a is LongArray && b is LongArray) { + return a.contentEquals(b) + } + if (a is DoubleArray && b is DoubleArray) { + return a.contentEquals(b) + } + if (a is Array<*> && b is Array<*>) { + return a.size == b.size && + a.indices.all { deepEqualsCircleAnnotationMessenger(a[it], b[it]) } + } + if (a is Map<*, *> && b is Map<*, *>) { + return a.size == b.size && a.keys.all { + (b as Map).containsKey(it) && + deepEqualsCircleAnnotationMessenger(a[it], b[it]) + } + } + return a == b +} /** * Selects the base of circle-elevation. Some modes might require precomputed elevation data in the tileset. @@ -146,7 +171,9 @@ data class CircleAnnotation( */ val circleStrokeWidth: Double? = null, /** Property to determine whether annotation can be manually moved around map. */ - val isDraggable: Boolean? = null + val isDraggable: Boolean? = null, + /** JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. */ + val customData: Map? = null ) { companion object { fun fromList(pigeonVar_list: List): CircleAnnotation { @@ -161,7 +188,8 @@ data class CircleAnnotation( val circleStrokeOpacity = pigeonVar_list[8] as Double? val circleStrokeWidth = pigeonVar_list[9] as Double? val isDraggable = pigeonVar_list[10] as Boolean? - return CircleAnnotation(id, geometry, circleSortKey, circleBlur, circleColor, circleOpacity, circleRadius, circleStrokeColor, circleStrokeOpacity, circleStrokeWidth, isDraggable) + val customData = pigeonVar_list[11] as Map? + return CircleAnnotation(id, geometry, circleSortKey, circleBlur, circleColor, circleOpacity, circleRadius, circleStrokeColor, circleStrokeOpacity, circleStrokeWidth, isDraggable, customData) } } fun toList(): List { @@ -177,6 +205,7 @@ data class CircleAnnotation( circleStrokeOpacity, circleStrokeWidth, isDraggable, + customData, ) } override fun equals(other: Any?): Boolean { @@ -196,7 +225,8 @@ data class CircleAnnotation( circleStrokeColor == other.circleStrokeColor && circleStrokeOpacity == other.circleStrokeOpacity && circleStrokeWidth == other.circleStrokeWidth && - isDraggable == other.isDraggable + isDraggable == other.isDraggable && + deepEqualsCircleAnnotationMessenger(customData, other.customData) } override fun hashCode(): Int = toList().hashCode() @@ -244,7 +274,9 @@ data class CircleAnnotationOptions( */ val circleStrokeWidth: Double? = null, /** Property to determine whether annotation can be manually moved around map. */ - val isDraggable: Boolean? = null + val isDraggable: Boolean? = null, + /** JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. */ + val customData: Map? = null ) { companion object { fun fromList(pigeonVar_list: List): CircleAnnotationOptions { @@ -258,7 +290,8 @@ data class CircleAnnotationOptions( val circleStrokeOpacity = pigeonVar_list[7] as Double? val circleStrokeWidth = pigeonVar_list[8] as Double? val isDraggable = pigeonVar_list[9] as Boolean? - return CircleAnnotationOptions(geometry, circleSortKey, circleBlur, circleColor, circleOpacity, circleRadius, circleStrokeColor, circleStrokeOpacity, circleStrokeWidth, isDraggable) + val customData = pigeonVar_list[10] as Map? + return CircleAnnotationOptions(geometry, circleSortKey, circleBlur, circleColor, circleOpacity, circleRadius, circleStrokeColor, circleStrokeOpacity, circleStrokeWidth, isDraggable, customData) } } fun toList(): List { @@ -273,6 +306,7 @@ data class CircleAnnotationOptions( circleStrokeOpacity, circleStrokeWidth, isDraggable, + customData, ) } override fun equals(other: Any?): Boolean { @@ -291,7 +325,8 @@ data class CircleAnnotationOptions( circleStrokeColor == other.circleStrokeColor && circleStrokeOpacity == other.circleStrokeOpacity && circleStrokeWidth == other.circleStrokeWidth && - isDraggable == other.isDraggable + isDraggable == other.isDraggable && + deepEqualsCircleAnnotationMessenger(customData, other.customData) } override fun hashCode(): Int = toList().hashCode() @@ -374,6 +409,7 @@ private open class CircleAnnotationMessengerPigeonCodec : StandardMessageCodec() /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ interface _CircleAnnotationMessenger { + fun getAnnotations(managerId: String, callback: (Result>) -> Unit) fun create(managerId: String, annotationOption: CircleAnnotationOptions, callback: (Result) -> Unit) fun createMulti(managerId: String, annotationOptions: List, callback: (Result>) -> Unit) fun update(managerId: String, annotation: CircleAnnotation, callback: (Result) -> Unit) @@ -417,6 +453,26 @@ interface _CircleAnnotationMessenger { @JvmOverloads fun setUp(binaryMessenger: BinaryMessenger, api: _CircleAnnotationMessenger?, messageChannelSuffix: String = "") { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.mapbox_maps_flutter._CircleAnnotationMessenger.getAnnotations$separatedMessageChannelSuffix", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val managerIdArg = args[0] as String + api.getAnnotations(managerIdArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } run { val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.mapbox_maps_flutter._CircleAnnotationMessenger.create$separatedMessageChannelSuffix", codec) if (api != null) { diff --git a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/PointAnnotationMessenger.kt b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/PointAnnotationMessenger.kt index 151b7920c..42b6981c4 100644 --- a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/PointAnnotationMessenger.kt +++ b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/PointAnnotationMessenger.kt @@ -574,7 +574,9 @@ data class PointAnnotation( */ val textOpacity: Double? = null, /** Property to determine whether annotation can be manually moved around map. */ - val isDraggable: Boolean? = null + val isDraggable: Boolean? = null, + /** JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. */ + val customData: Map? = null ) { companion object { fun fromList(pigeonVar_list: List): PointAnnotation { @@ -617,7 +619,8 @@ data class PointAnnotation( val textOcclusionOpacity = pigeonVar_list[36] as Double? val textOpacity = pigeonVar_list[37] as Double? val isDraggable = pigeonVar_list[38] as Boolean? - return PointAnnotation(id, geometry, image, iconAnchor, iconImage, iconOffset, iconRotate, iconSize, iconTextFit, iconTextFitPadding, symbolSortKey, textAnchor, textField, textJustify, textLetterSpacing, textLineHeight, textMaxWidth, textOffset, textRadialOffset, textRotate, textSize, textTransform, iconColor, iconEmissiveStrength, iconHaloBlur, iconHaloColor, iconHaloWidth, iconImageCrossFade, iconOcclusionOpacity, iconOpacity, symbolZOffset, textColor, textEmissiveStrength, textHaloBlur, textHaloColor, textHaloWidth, textOcclusionOpacity, textOpacity, isDraggable) + val customData = pigeonVar_list[39] as Map? + return PointAnnotation(id, geometry, image, iconAnchor, iconImage, iconOffset, iconRotate, iconSize, iconTextFit, iconTextFitPadding, symbolSortKey, textAnchor, textField, textJustify, textLetterSpacing, textLineHeight, textMaxWidth, textOffset, textRadialOffset, textRotate, textSize, textTransform, iconColor, iconEmissiveStrength, iconHaloBlur, iconHaloColor, iconHaloWidth, iconImageCrossFade, iconOcclusionOpacity, iconOpacity, symbolZOffset, textColor, textEmissiveStrength, textHaloBlur, textHaloColor, textHaloWidth, textOcclusionOpacity, textOpacity, isDraggable, customData) } } fun toList(): List { @@ -661,6 +664,7 @@ data class PointAnnotation( textOcclusionOpacity, textOpacity, isDraggable, + customData, ) } override fun equals(other: Any?): Boolean { @@ -708,7 +712,8 @@ data class PointAnnotation( textHaloWidth == other.textHaloWidth && textOcclusionOpacity == other.textOcclusionOpacity && textOpacity == other.textOpacity && - isDraggable == other.isDraggable + isDraggable == other.isDraggable && + deepEqualsPointAnnotationMessenger(customData, other.customData) } override fun hashCode(): Int = toList().hashCode() @@ -895,7 +900,9 @@ data class PointAnnotationOptions( */ val textOpacity: Double? = null, /** Property to determine whether annotation can be manually moved around map. */ - val isDraggable: Boolean? = null + val isDraggable: Boolean? = null, + /** JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. */ + val customData: Map? = null ) { companion object { fun fromList(pigeonVar_list: List): PointAnnotationOptions { @@ -937,7 +944,8 @@ data class PointAnnotationOptions( val textOcclusionOpacity = pigeonVar_list[35] as Double? val textOpacity = pigeonVar_list[36] as Double? val isDraggable = pigeonVar_list[37] as Boolean? - return PointAnnotationOptions(geometry, image, iconAnchor, iconImage, iconOffset, iconRotate, iconSize, iconTextFit, iconTextFitPadding, symbolSortKey, textAnchor, textField, textJustify, textLetterSpacing, textLineHeight, textMaxWidth, textOffset, textRadialOffset, textRotate, textSize, textTransform, iconColor, iconEmissiveStrength, iconHaloBlur, iconHaloColor, iconHaloWidth, iconImageCrossFade, iconOcclusionOpacity, iconOpacity, symbolZOffset, textColor, textEmissiveStrength, textHaloBlur, textHaloColor, textHaloWidth, textOcclusionOpacity, textOpacity, isDraggable) + val customData = pigeonVar_list[38] as Map? + return PointAnnotationOptions(geometry, image, iconAnchor, iconImage, iconOffset, iconRotate, iconSize, iconTextFit, iconTextFitPadding, symbolSortKey, textAnchor, textField, textJustify, textLetterSpacing, textLineHeight, textMaxWidth, textOffset, textRadialOffset, textRotate, textSize, textTransform, iconColor, iconEmissiveStrength, iconHaloBlur, iconHaloColor, iconHaloWidth, iconImageCrossFade, iconOcclusionOpacity, iconOpacity, symbolZOffset, textColor, textEmissiveStrength, textHaloBlur, textHaloColor, textHaloWidth, textOcclusionOpacity, textOpacity, isDraggable, customData) } } fun toList(): List { @@ -980,6 +988,7 @@ data class PointAnnotationOptions( textOcclusionOpacity, textOpacity, isDraggable, + customData, ) } override fun equals(other: Any?): Boolean { @@ -1026,7 +1035,8 @@ data class PointAnnotationOptions( textHaloWidth == other.textHaloWidth && textOcclusionOpacity == other.textOcclusionOpacity && textOpacity == other.textOpacity && - isDraggable == other.isDraggable + isDraggable == other.isDraggable && + deepEqualsPointAnnotationMessenger(customData, other.customData) } override fun hashCode(): Int = toList().hashCode() @@ -1217,6 +1227,7 @@ private open class PointAnnotationMessengerPigeonCodec : StandardMessageCodec() /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ interface _PointAnnotationMessenger { + fun getAnnotations(managerId: String, callback: (Result>) -> Unit) fun create(managerId: String, annotationOption: PointAnnotationOptions, callback: (Result) -> Unit) fun createMulti(managerId: String, annotationOptions: List, callback: (Result>) -> Unit) fun update(managerId: String, annotation: PointAnnotation, callback: (Result) -> Unit) @@ -1360,6 +1371,26 @@ interface _PointAnnotationMessenger { @JvmOverloads fun setUp(binaryMessenger: BinaryMessenger, api: _PointAnnotationMessenger?, messageChannelSuffix: String = "") { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.mapbox_maps_flutter._PointAnnotationMessenger.getAnnotations$separatedMessageChannelSuffix", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val managerIdArg = args[0] as String + api.getAnnotations(managerIdArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } run { val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.mapbox_maps_flutter._PointAnnotationMessenger.create$separatedMessageChannelSuffix", codec) if (api != null) { diff --git a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/PolygonAnnotationMessenger.kt b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/PolygonAnnotationMessenger.kt index 6b653debd..c0e6498fb 100644 --- a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/PolygonAnnotationMessenger.kt +++ b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/PolygonAnnotationMessenger.kt @@ -33,6 +33,31 @@ private fun wrapError(exception: Throwable): List { ) } } +private fun deepEqualsPolygonAnnotationMessenger(a: Any?, b: Any?): Boolean { + if (a is ByteArray && b is ByteArray) { + return a.contentEquals(b) + } + if (a is IntArray && b is IntArray) { + return a.contentEquals(b) + } + if (a is LongArray && b is LongArray) { + return a.contentEquals(b) + } + if (a is DoubleArray && b is DoubleArray) { + return a.contentEquals(b) + } + if (a is Array<*> && b is Array<*>) { + return a.size == b.size && + a.indices.all { deepEqualsPolygonAnnotationMessenger(a[it], b[it]) } + } + if (a is Map<*, *> && b is Map<*, *>) { + return a.size == b.size && a.keys.all { + (b as Map).containsKey(it) && + deepEqualsPolygonAnnotationMessenger(a[it], b[it]) + } + } + return a == b +} /** * Selects the base of fill-elevation. Some modes might require precomputed elevation data in the tileset. @@ -117,7 +142,9 @@ data class PolygonAnnotation( */ val fillZOffset: Double? = null, /** Property to determine whether annotation can be manually moved around map. */ - val isDraggable: Boolean? = null + val isDraggable: Boolean? = null, + /** JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. */ + val customData: Map? = null ) { companion object { fun fromList(pigeonVar_list: List): PolygonAnnotation { @@ -133,7 +160,8 @@ data class PolygonAnnotation( val fillTunnelStructureColor = pigeonVar_list[9] as Long? val fillZOffset = pigeonVar_list[10] as Double? val isDraggable = pigeonVar_list[11] as Boolean? - return PolygonAnnotation(id, geometry, fillConstructBridgeGuardRail, fillSortKey, fillBridgeGuardRailColor, fillColor, fillOpacity, fillOutlineColor, fillPattern, fillTunnelStructureColor, fillZOffset, isDraggable) + val customData = pigeonVar_list[12] as Map? + return PolygonAnnotation(id, geometry, fillConstructBridgeGuardRail, fillSortKey, fillBridgeGuardRailColor, fillColor, fillOpacity, fillOutlineColor, fillPattern, fillTunnelStructureColor, fillZOffset, isDraggable, customData) } } fun toList(): List { @@ -150,6 +178,7 @@ data class PolygonAnnotation( fillTunnelStructureColor, fillZOffset, isDraggable, + customData, ) } override fun equals(other: Any?): Boolean { @@ -170,7 +199,8 @@ data class PolygonAnnotation( fillPattern == other.fillPattern && fillTunnelStructureColor == other.fillTunnelStructureColor && fillZOffset == other.fillZOffset && - isDraggable == other.isDraggable + isDraggable == other.isDraggable && + deepEqualsPolygonAnnotationMessenger(customData, other.customData) } override fun hashCode(): Int = toList().hashCode() @@ -221,7 +251,9 @@ data class PolygonAnnotationOptions( */ val fillZOffset: Double? = null, /** Property to determine whether annotation can be manually moved around map. */ - val isDraggable: Boolean? = null + val isDraggable: Boolean? = null, + /** JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. */ + val customData: Map? = null ) { companion object { fun fromList(pigeonVar_list: List): PolygonAnnotationOptions { @@ -236,7 +268,8 @@ data class PolygonAnnotationOptions( val fillTunnelStructureColor = pigeonVar_list[8] as Long? val fillZOffset = pigeonVar_list[9] as Double? val isDraggable = pigeonVar_list[10] as Boolean? - return PolygonAnnotationOptions(geometry, fillConstructBridgeGuardRail, fillSortKey, fillBridgeGuardRailColor, fillColor, fillOpacity, fillOutlineColor, fillPattern, fillTunnelStructureColor, fillZOffset, isDraggable) + val customData = pigeonVar_list[11] as Map? + return PolygonAnnotationOptions(geometry, fillConstructBridgeGuardRail, fillSortKey, fillBridgeGuardRailColor, fillColor, fillOpacity, fillOutlineColor, fillPattern, fillTunnelStructureColor, fillZOffset, isDraggable, customData) } } fun toList(): List { @@ -252,6 +285,7 @@ data class PolygonAnnotationOptions( fillTunnelStructureColor, fillZOffset, isDraggable, + customData, ) } override fun equals(other: Any?): Boolean { @@ -271,7 +305,8 @@ data class PolygonAnnotationOptions( fillPattern == other.fillPattern && fillTunnelStructureColor == other.fillTunnelStructureColor && fillZOffset == other.fillZOffset && - isDraggable == other.isDraggable + isDraggable == other.isDraggable && + deepEqualsPolygonAnnotationMessenger(customData, other.customData) } override fun hashCode(): Int = toList().hashCode() @@ -336,6 +371,7 @@ private open class PolygonAnnotationMessengerPigeonCodec : StandardMessageCodec( /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ interface _PolygonAnnotationMessenger { + fun getAnnotations(managerId: String, callback: (Result>) -> Unit) fun create(managerId: String, annotationOption: PolygonAnnotationOptions, callback: (Result) -> Unit) fun createMulti(managerId: String, annotationOptions: List, callback: (Result>) -> Unit) fun update(managerId: String, annotation: PolygonAnnotation, callback: (Result) -> Unit) @@ -379,6 +415,26 @@ interface _PolygonAnnotationMessenger { @JvmOverloads fun setUp(binaryMessenger: BinaryMessenger, api: _PolygonAnnotationMessenger?, messageChannelSuffix: String = "") { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.mapbox_maps_flutter._PolygonAnnotationMessenger.getAnnotations$separatedMessageChannelSuffix", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val managerIdArg = args[0] as String + api.getAnnotations(managerIdArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } run { val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.mapbox_maps_flutter._PolygonAnnotationMessenger.create$separatedMessageChannelSuffix", codec) if (api != null) { diff --git a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/PolylineAnnotationMessenger.kt b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/PolylineAnnotationMessenger.kt index 480e4682a..439d706d5 100644 --- a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/PolylineAnnotationMessenger.kt +++ b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/PolylineAnnotationMessenger.kt @@ -33,6 +33,31 @@ private fun wrapError(exception: Throwable): List { ) } } +private fun deepEqualsPolylineAnnotationMessenger(a: Any?, b: Any?): Boolean { + if (a is ByteArray && b is ByteArray) { + return a.contentEquals(b) + } + if (a is IntArray && b is IntArray) { + return a.contentEquals(b) + } + if (a is LongArray && b is LongArray) { + return a.contentEquals(b) + } + if (a is DoubleArray && b is DoubleArray) { + return a.contentEquals(b) + } + if (a is Array<*> && b is Array<*>) { + return a.size == b.size && + a.indices.all { deepEqualsPolylineAnnotationMessenger(a[it], b[it]) } + } + if (a is Map<*, *> && b is Map<*, *>) { + return a.size == b.size && a.keys.all { + (b as Map).containsKey(it) && + deepEqualsPolylineAnnotationMessenger(a[it], b[it]) + } + } + return a == b +} /** * The display of line endings. @@ -198,7 +223,9 @@ data class PolylineAnnotation( */ val lineWidth: Double? = null, /** Property to determine whether annotation can be manually moved around map. */ - val isDraggable: Boolean? = null + val isDraggable: Boolean? = null, + /** JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. */ + val customData: Map? = null ) { companion object { fun fromList(pigeonVar_list: List): PolylineAnnotation { @@ -217,7 +244,8 @@ data class PolylineAnnotation( val linePattern = pigeonVar_list[12] as String? val lineWidth = pigeonVar_list[13] as Double? val isDraggable = pigeonVar_list[14] as Boolean? - return PolylineAnnotation(id, geometry, lineJoin, lineSortKey, lineZOffset, lineBlur, lineBorderColor, lineBorderWidth, lineColor, lineGapWidth, lineOffset, lineOpacity, linePattern, lineWidth, isDraggable) + val customData = pigeonVar_list[15] as Map? + return PolylineAnnotation(id, geometry, lineJoin, lineSortKey, lineZOffset, lineBlur, lineBorderColor, lineBorderWidth, lineColor, lineGapWidth, lineOffset, lineOpacity, linePattern, lineWidth, isDraggable, customData) } } fun toList(): List { @@ -237,6 +265,7 @@ data class PolylineAnnotation( linePattern, lineWidth, isDraggable, + customData, ) } override fun equals(other: Any?): Boolean { @@ -260,7 +289,8 @@ data class PolylineAnnotation( lineOpacity == other.lineOpacity && linePattern == other.linePattern && lineWidth == other.lineWidth && - isDraggable == other.isDraggable + isDraggable == other.isDraggable && + deepEqualsPolylineAnnotationMessenger(customData, other.customData) } override fun hashCode(): Int = toList().hashCode() @@ -333,7 +363,9 @@ data class PolylineAnnotationOptions( */ val lineWidth: Double? = null, /** Property to determine whether annotation can be manually moved around map. */ - val isDraggable: Boolean? = null + val isDraggable: Boolean? = null, + /** JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. */ + val customData: Map? = null ) { companion object { fun fromList(pigeonVar_list: List): PolylineAnnotationOptions { @@ -351,7 +383,8 @@ data class PolylineAnnotationOptions( val linePattern = pigeonVar_list[11] as String? val lineWidth = pigeonVar_list[12] as Double? val isDraggable = pigeonVar_list[13] as Boolean? - return PolylineAnnotationOptions(geometry, lineJoin, lineSortKey, lineZOffset, lineBlur, lineBorderColor, lineBorderWidth, lineColor, lineGapWidth, lineOffset, lineOpacity, linePattern, lineWidth, isDraggable) + val customData = pigeonVar_list[14] as Map? + return PolylineAnnotationOptions(geometry, lineJoin, lineSortKey, lineZOffset, lineBlur, lineBorderColor, lineBorderWidth, lineColor, lineGapWidth, lineOffset, lineOpacity, linePattern, lineWidth, isDraggable, customData) } } fun toList(): List { @@ -370,6 +403,7 @@ data class PolylineAnnotationOptions( linePattern, lineWidth, isDraggable, + customData, ) } override fun equals(other: Any?): Boolean { @@ -392,7 +426,8 @@ data class PolylineAnnotationOptions( lineOpacity == other.lineOpacity && linePattern == other.linePattern && lineWidth == other.lineWidth && - isDraggable == other.isDraggable + isDraggable == other.isDraggable && + deepEqualsPolylineAnnotationMessenger(customData, other.customData) } override fun hashCode(): Int = toList().hashCode() @@ -484,6 +519,7 @@ private open class PolylineAnnotationMessengerPigeonCodec : StandardMessageCodec /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ interface _PolylineAnnotationMessenger { + fun getAnnotations(managerId: String, callback: (Result>) -> Unit) fun create(managerId: String, annotationOption: PolylineAnnotationOptions, callback: (Result) -> Unit) fun createMulti(managerId: String, annotationOptions: List, callback: (Result>) -> Unit) fun update(managerId: String, annotation: PolylineAnnotation, callback: (Result) -> Unit) @@ -559,6 +595,26 @@ interface _PolylineAnnotationMessenger { @JvmOverloads fun setUp(binaryMessenger: BinaryMessenger, api: _PolylineAnnotationMessenger?, messageChannelSuffix: String = "") { val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.mapbox_maps_flutter._PolylineAnnotationMessenger.getAnnotations$separatedMessageChannelSuffix", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val managerIdArg = args[0] as String + api.getAnnotations(managerIdArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } run { val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.mapbox_maps_flutter._PolylineAnnotationMessenger.create$separatedMessageChannelSuffix", codec) if (api != null) { diff --git a/example/integration_test/annotations/circle_annotation_test.dart b/example/integration_test/annotations/circle_annotation_test.dart index d3c872987..141277105 100644 --- a/example/integration_test/annotations/circle_annotation_test.dart +++ b/example/integration_test/annotations/circle_annotation_test.dart @@ -25,6 +25,7 @@ void main() { circleStrokeColor: Colors.red.value, circleStrokeOpacity: 1.0, circleStrokeWidth: 1.0, + customData: {'foo': 'bar'}, ); final annotation = await manager.create(circleAnnotationOptions); var point = annotation.geometry; @@ -38,6 +39,7 @@ void main() { expect(Colors.red.value, annotation.circleStrokeColor); expect(1.0, annotation.circleStrokeOpacity); expect(1.0, annotation.circleStrokeWidth); + expect({'foo': 'bar'}, annotation.customData); }); testWidgets('update and delete CircleAnnotation', @@ -64,6 +66,9 @@ void main() { await manager.create(circleAnnotationOptions); } + final annotations = await manager.getAnnotations(); + expect(annotations.length, equals(10)); + await manager.deleteAll(); }); } diff --git a/example/integration_test/annotations/point_annotation_test.dart b/example/integration_test/annotations/point_annotation_test.dart index 31595cda9..28259e00d 100644 --- a/example/integration_test/annotations/point_annotation_test.dart +++ b/example/integration_test/annotations/point_annotation_test.dart @@ -56,6 +56,7 @@ void main() { textHaloWidth: 1.0, textOcclusionOpacity: 1.0, textOpacity: 1.0, + customData: {'foo': 'bar'}, ); final annotation = await manager.create(pointAnnotationOptions); var point = annotation.geometry; @@ -96,6 +97,7 @@ void main() { expect(1.0, annotation.textHaloWidth); expect(1.0, annotation.textOcclusionOpacity); expect(1.0, annotation.textOpacity); + expect({'foo': 'bar'}, annotation.customData); }); testWidgets('update and delete PointAnnotation', (WidgetTester tester) async { @@ -121,6 +123,9 @@ void main() { await manager.create(pointAnnotationOptions); } + final annotations = await manager.getAnnotations(); + expect(annotations.length, equals(10)); + await manager.deleteAll(); }); } diff --git a/example/integration_test/annotations/polygon_annotation_test.dart b/example/integration_test/annotations/polygon_annotation_test.dart index 203399437..8a6b59170 100644 --- a/example/integration_test/annotations/polygon_annotation_test.dart +++ b/example/integration_test/annotations/polygon_annotation_test.dart @@ -34,6 +34,7 @@ void main() { fillPattern: "abc", fillTunnelStructureColor: Colors.red.value, fillZOffset: 1.0, + customData: {'foo': 'bar'}, ); final annotation = await manager.create(polygonAnnotationOptions); var polygon = annotation.geometry; @@ -53,6 +54,7 @@ void main() { expect("abc", annotation.fillPattern); expect(Colors.red.value, annotation.fillTunnelStructureColor); expect(1.0, annotation.fillZOffset); + expect({'foo': 'bar'}, annotation.customData); }); testWidgets('update and delete PolygonAnnotation', @@ -89,6 +91,9 @@ void main() { await manager.create(polygonAnnotationOptions); } + final annotations = await manager.getAnnotations(); + expect(annotations.length, equals(10)); + await manager.deleteAll(); }); } diff --git a/example/integration_test/annotations/polyline_annotation_test.dart b/example/integration_test/annotations/polyline_annotation_test.dart index cc70490c4..f96e0250c 100644 --- a/example/integration_test/annotations/polyline_annotation_test.dart +++ b/example/integration_test/annotations/polyline_annotation_test.dart @@ -31,6 +31,7 @@ void main() { lineOpacity: 1.0, linePattern: "abc", lineWidth: 1.0, + customData: {'foo': 'bar'}, ); final annotation = await manager.create(polylineAnnotationOptions); var lineString = annotation.geometry; @@ -52,6 +53,7 @@ void main() { expect(1.0, annotation.lineOpacity); expect("abc", annotation.linePattern); expect(1.0, annotation.lineWidth); + expect({'foo': 'bar'}, annotation.customData); }); testWidgets('update and delete PolylineAnnotation', @@ -81,6 +83,9 @@ void main() { await manager.create(polylineAnnotationOptions); } + final annotations = await manager.getAnnotations(); + expect(annotations.length, equals(10)); + await manager.deleteAll(); }); } diff --git a/example/integration_test/map_interface_test.dart b/example/integration_test/map_interface_test.dart index 996b8117d..2c67a95d6 100644 --- a/example/integration_test/map_interface_test.dart +++ b/example/integration_test/map_interface_test.dart @@ -235,8 +235,7 @@ void main() { await mapboxMap.setFeatureState( 'source', null, 'point', json.encode({'choose': true})); - var featureState = - await mapboxMap.getFeatureState('source', null, 'point'); + var featureState = await mapboxMap.getFeatureState('source', null, 'point'); var stateMap = json.decode(featureState); expect(stateMap.length, 1); expect(stateMap['choose'], true); diff --git a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/BaseAnnotationMessenger.swift b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/BaseAnnotationMessenger.swift index 0e16af8f5..92f6f0dc4 100644 --- a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/BaseAnnotationMessenger.swift +++ b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/BaseAnnotationMessenger.swift @@ -33,6 +33,10 @@ class BaseAnnotationMessenger { storage[managerId]?.onLongPress(context) ?? false } + func allAnnotations(_ managerId: String) -> [C.Child] { + storage[managerId]?.controller.annotations ?? [] + } + private subscript(id: String) -> C? { return storage[id]?.controller } diff --git a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/CircleAnnotationController.swift b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/CircleAnnotationController.swift index 6c9094e1e..a8d04d204 100644 --- a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/CircleAnnotationController.swift +++ b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/CircleAnnotationController.swift @@ -8,6 +8,10 @@ final class CircleAnnotationController: BaseAnnotationMessenger) -> Void) { + completion(.success(allAnnotations(managerId).map { $0.toFLTCircleAnnotation() })) + } + func create(managerId: String, annotationOption: CircleAnnotationOptions, completion: @escaping (Result) -> Void) { try createMulti(managerId: managerId, annotationOptions: [annotationOption]) { result in completion(result.flatMap { @@ -371,6 +375,9 @@ extension CircleAnnotationOptions { if let isDraggable { annotation.isDraggable = isDraggable } + if let customData { + annotation.customData = customData.compactMapValues { JSONValue.fromAny($0) } + } return annotation } } @@ -406,6 +413,9 @@ extension CircleAnnotation { if let isDraggable { annotation.isDraggable = isDraggable } + if let customData { + annotation.customData = customData.compactMapValues { JSONValue.fromAny($0) } + } return annotation } } @@ -423,7 +433,8 @@ extension MapboxMaps.CircleAnnotation { circleStrokeColor: circleStrokeColor?.intValue, circleStrokeOpacity: circleStrokeOpacity, circleStrokeWidth: circleStrokeWidth, - isDraggable: isDraggable + isDraggable: isDraggable, + customData: customData.compactMapValues { $0?.toAny } ) } } diff --git a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/PointAnnotationController.swift b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/PointAnnotationController.swift index cb0bbcab6..8a4f7517b 100644 --- a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/PointAnnotationController.swift +++ b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/PointAnnotationController.swift @@ -8,6 +8,10 @@ final class PointAnnotationController: BaseAnnotationMessenger) -> Void) { + completion(.success(allAnnotations(managerId).map { $0.toFLTPointAnnotation() })) + } + func create(managerId: String, annotationOption: PointAnnotationOptions, completion: @escaping (Result) -> Void) { try createMulti(managerId: managerId, annotationOptions: [annotationOption]) { result in completion(result.flatMap { @@ -1355,6 +1359,9 @@ extension PointAnnotationOptions { if let isDraggable { annotation.isDraggable = isDraggable } + if let customData { + annotation.customData = customData.compactMapValues { JSONValue.fromAny($0) } + } return annotation } } @@ -1474,6 +1481,9 @@ extension PointAnnotation { if let isDraggable { annotation.isDraggable = isDraggable } + if let customData { + annotation.customData = customData.compactMapValues { JSONValue.fromAny($0) } + } return annotation } } @@ -1519,7 +1529,8 @@ extension MapboxMaps.PointAnnotation { textHaloWidth: textHaloWidth, textOcclusionOpacity: textOcclusionOpacity, textOpacity: textOpacity, - isDraggable: isDraggable + isDraggable: isDraggable, + customData: customData.compactMapValues { $0?.toAny } ) } } diff --git a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/PolygonAnnotationController.swift b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/PolygonAnnotationController.swift index 2b880a30e..713865b5f 100644 --- a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/PolygonAnnotationController.swift +++ b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/PolygonAnnotationController.swift @@ -8,6 +8,10 @@ final class PolygonAnnotationController: BaseAnnotationMessenger) -> Void) { + completion(.success(allAnnotations(managerId).map { $0.toFLTPolygonAnnotation() })) + } + func create(managerId: String, annotationOption: PolygonAnnotationOptions, completion: @escaping (Result) -> Void) { try createMulti(managerId: managerId, annotationOptions: [annotationOption]) { result in completion(result.flatMap { @@ -374,6 +378,9 @@ extension PolygonAnnotationOptions { if let isDraggable { annotation.isDraggable = isDraggable } + if let customData { + annotation.customData = customData.compactMapValues { JSONValue.fromAny($0) } + } return annotation } } @@ -412,6 +419,9 @@ extension PolygonAnnotation { if let isDraggable { annotation.isDraggable = isDraggable } + if let customData { + annotation.customData = customData.compactMapValues { JSONValue.fromAny($0) } + } return annotation } } @@ -430,7 +440,8 @@ extension MapboxMaps.PolygonAnnotation { fillPattern: fillPattern, fillTunnelStructureColor: fillTunnelStructureColor?.intValue, fillZOffset: fillZOffset, - isDraggable: isDraggable + isDraggable: isDraggable, + customData: customData.compactMapValues { $0?.toAny } ) } } diff --git a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/PolylineAnnotationController.swift b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/PolylineAnnotationController.swift index 0291005c6..af028ef73 100644 --- a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/PolylineAnnotationController.swift +++ b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Annotations/PolylineAnnotationController.swift @@ -8,6 +8,10 @@ final class PolylineAnnotationController: BaseAnnotationMessenger) -> Void) { + completion(.success(allAnnotations(managerId).map { $0.toFLTPolylineAnnotation() })) + } + func create(managerId: String, annotationOption: PolylineAnnotationOptions, completion: @escaping (Result) -> Void) { try createMulti(managerId: managerId, annotationOptions: [annotationOption]) { result in completion(result.flatMap { @@ -671,6 +675,9 @@ extension PolylineAnnotationOptions { if let isDraggable { annotation.isDraggable = isDraggable } + if let customData { + annotation.customData = customData.compactMapValues { JSONValue.fromAny($0) } + } return annotation } } @@ -718,6 +725,9 @@ extension PolylineAnnotation { if let isDraggable { annotation.isDraggable = isDraggable } + if let customData { + annotation.customData = customData.compactMapValues { JSONValue.fromAny($0) } + } return annotation } } @@ -739,7 +749,8 @@ extension MapboxMaps.PolylineAnnotation { lineOpacity: lineOpacity, linePattern: linePattern, lineWidth: lineWidth, - isDraggable: isDraggable + isDraggable: isDraggable, + customData: customData.compactMapValues { $0?.toAny } ) } } diff --git a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Generated/CircleAnnotationMessenger.swift b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Generated/CircleAnnotationMessenger.swift index 069c7c6a3..2f9ceb3ae 100644 --- a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Generated/CircleAnnotationMessenger.swift +++ b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Generated/CircleAnnotationMessenger.swift @@ -132,6 +132,8 @@ struct CircleAnnotation { var circleStrokeWidth: Double? = nil /// Property to determine whether annotation can be manually moved around map. var isDraggable: Bool? = nil + /// JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. + var customData: [String: Any]? = nil // swift-format-ignore: AlwaysUseLowerCamelCase @@ -147,6 +149,7 @@ struct CircleAnnotation { let circleStrokeOpacity: Double? = nilOrValue(pigeonVar_list[8]) let circleStrokeWidth: Double? = nilOrValue(pigeonVar_list[9]) let isDraggable: Bool? = nilOrValue(pigeonVar_list[10]) + let customData: [String: Any]? = nilOrValue(pigeonVar_list[11]) return CircleAnnotation( id: id, @@ -159,7 +162,8 @@ struct CircleAnnotation { circleStrokeColor: circleStrokeColor, circleStrokeOpacity: circleStrokeOpacity, circleStrokeWidth: circleStrokeWidth, - isDraggable: isDraggable + isDraggable: isDraggable, + customData: customData ) } func toList() -> [Any?] { @@ -175,6 +179,7 @@ struct CircleAnnotation { circleStrokeOpacity, circleStrokeWidth, isDraggable, + customData, ] } } @@ -208,6 +213,8 @@ struct CircleAnnotationOptions { var circleStrokeWidth: Double? = nil /// Property to determine whether annotation can be manually moved around map. var isDraggable: Bool? = nil + /// JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. + var customData: [String: Any]? = nil // swift-format-ignore: AlwaysUseLowerCamelCase @@ -222,6 +229,7 @@ struct CircleAnnotationOptions { let circleStrokeOpacity: Double? = nilOrValue(pigeonVar_list[7]) let circleStrokeWidth: Double? = nilOrValue(pigeonVar_list[8]) let isDraggable: Bool? = nilOrValue(pigeonVar_list[9]) + let customData: [String: Any]? = nilOrValue(pigeonVar_list[10]) return CircleAnnotationOptions( geometry: geometry, @@ -233,7 +241,8 @@ struct CircleAnnotationOptions { circleStrokeColor: circleStrokeColor, circleStrokeOpacity: circleStrokeOpacity, circleStrokeWidth: circleStrokeWidth, - isDraggable: isDraggable + isDraggable: isDraggable, + customData: customData ) } func toList() -> [Any?] { @@ -248,6 +257,7 @@ struct CircleAnnotationOptions { circleStrokeOpacity, circleStrokeWidth, isDraggable, + customData, ] } } @@ -336,6 +346,7 @@ class CircleAnnotationMessengerPigeonCodec: FlutterStandardMessageCodec, @unchec /// Generated protocol from Pigeon that represents a handler of messages from Flutter. protocol _CircleAnnotationMessenger { + func getAnnotations(managerId: String, completion: @escaping (Result<[CircleAnnotation], Error>) -> Void) func create(managerId: String, annotationOption: CircleAnnotationOptions, completion: @escaping (Result) -> Void) func createMulti(managerId: String, annotationOptions: [CircleAnnotationOptions], completion: @escaping (Result<[CircleAnnotation], Error>) -> Void) func update(managerId: String, annotation: CircleAnnotation, completion: @escaping (Result) -> Void) @@ -377,6 +388,23 @@ class _CircleAnnotationMessengerSetup { /// Sets up an instance of `_CircleAnnotationMessenger` to handle messages through the `binaryMessenger`. static func setUp(binaryMessenger: FlutterBinaryMessenger, api: _CircleAnnotationMessenger?, messageChannelSuffix: String = "") { let channelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" + let getAnnotationsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.mapbox_maps_flutter._CircleAnnotationMessenger.getAnnotations\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + getAnnotationsChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let managerIdArg = args[0] as! String + api.getAnnotations(managerId: managerIdArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + getAnnotationsChannel.setMessageHandler(nil) + } let createChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.mapbox_maps_flutter._CircleAnnotationMessenger.create\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { createChannel.setMessageHandler { message, reply in diff --git a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Generated/PointAnnotationMessenger.swift b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Generated/PointAnnotationMessenger.swift index af7a689ed..f2ac63be0 100644 --- a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Generated/PointAnnotationMessenger.swift +++ b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Generated/PointAnnotationMessenger.swift @@ -389,6 +389,8 @@ struct PointAnnotation { var textOpacity: Double? = nil /// Property to determine whether annotation can be manually moved around map. var isDraggable: Bool? = nil + /// JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. + var customData: [String: Any]? = nil // swift-format-ignore: AlwaysUseLowerCamelCase @@ -432,6 +434,7 @@ struct PointAnnotation { let textOcclusionOpacity: Double? = nilOrValue(pigeonVar_list[36]) let textOpacity: Double? = nilOrValue(pigeonVar_list[37]) let isDraggable: Bool? = nilOrValue(pigeonVar_list[38]) + let customData: [String: Any]? = nilOrValue(pigeonVar_list[39]) return PointAnnotation( id: id, @@ -472,7 +475,8 @@ struct PointAnnotation { textHaloWidth: textHaloWidth, textOcclusionOpacity: textOcclusionOpacity, textOpacity: textOpacity, - isDraggable: isDraggable + isDraggable: isDraggable, + customData: customData ) } func toList() -> [Any?] { @@ -516,6 +520,7 @@ struct PointAnnotation { textOcclusionOpacity, textOpacity, isDraggable, + customData, ] } } @@ -634,6 +639,8 @@ struct PointAnnotationOptions { var textOpacity: Double? = nil /// Property to determine whether annotation can be manually moved around map. var isDraggable: Bool? = nil + /// JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. + var customData: [String: Any]? = nil // swift-format-ignore: AlwaysUseLowerCamelCase @@ -676,6 +683,7 @@ struct PointAnnotationOptions { let textOcclusionOpacity: Double? = nilOrValue(pigeonVar_list[35]) let textOpacity: Double? = nilOrValue(pigeonVar_list[36]) let isDraggable: Bool? = nilOrValue(pigeonVar_list[37]) + let customData: [String: Any]? = nilOrValue(pigeonVar_list[38]) return PointAnnotationOptions( geometry: geometry, @@ -715,7 +723,8 @@ struct PointAnnotationOptions { textHaloWidth: textHaloWidth, textOcclusionOpacity: textOcclusionOpacity, textOpacity: textOpacity, - isDraggable: isDraggable + isDraggable: isDraggable, + customData: customData ) } func toList() -> [Any?] { @@ -758,6 +767,7 @@ struct PointAnnotationOptions { textOcclusionOpacity, textOpacity, isDraggable, + customData, ] } } @@ -954,6 +964,7 @@ class PointAnnotationMessengerPigeonCodec: FlutterStandardMessageCodec, @uncheck /// Generated protocol from Pigeon that represents a handler of messages from Flutter. protocol _PointAnnotationMessenger { + func getAnnotations(managerId: String, completion: @escaping (Result<[PointAnnotation], Error>) -> Void) func create(managerId: String, annotationOption: PointAnnotationOptions, completion: @escaping (Result) -> Void) func createMulti(managerId: String, annotationOptions: [PointAnnotationOptions], completion: @escaping (Result<[PointAnnotation], Error>) -> Void) func update(managerId: String, annotation: PointAnnotation, completion: @escaping (Result) -> Void) @@ -1095,6 +1106,23 @@ class _PointAnnotationMessengerSetup { /// Sets up an instance of `_PointAnnotationMessenger` to handle messages through the `binaryMessenger`. static func setUp(binaryMessenger: FlutterBinaryMessenger, api: _PointAnnotationMessenger?, messageChannelSuffix: String = "") { let channelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" + let getAnnotationsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.mapbox_maps_flutter._PointAnnotationMessenger.getAnnotations\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + getAnnotationsChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let managerIdArg = args[0] as! String + api.getAnnotations(managerId: managerIdArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + getAnnotationsChannel.setMessageHandler(nil) + } let createChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.mapbox_maps_flutter._PointAnnotationMessenger.create\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { createChannel.setMessageHandler { message, reply in diff --git a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Generated/PolygonAnnotationMessenger.swift b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Generated/PolygonAnnotationMessenger.swift index 2d6bb9a5c..c19e1e23d 100644 --- a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Generated/PolygonAnnotationMessenger.swift +++ b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Generated/PolygonAnnotationMessenger.swift @@ -121,6 +121,8 @@ struct PolygonAnnotation { var fillZOffset: Double? = nil /// Property to determine whether annotation can be manually moved around map. var isDraggable: Bool? = nil + /// JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. + var customData: [String: Any]? = nil // swift-format-ignore: AlwaysUseLowerCamelCase @@ -137,6 +139,7 @@ struct PolygonAnnotation { let fillTunnelStructureColor: Int64? = nilOrValue(pigeonVar_list[9]) let fillZOffset: Double? = nilOrValue(pigeonVar_list[10]) let isDraggable: Bool? = nilOrValue(pigeonVar_list[11]) + let customData: [String: Any]? = nilOrValue(pigeonVar_list[12]) return PolygonAnnotation( id: id, @@ -150,7 +153,8 @@ struct PolygonAnnotation { fillPattern: fillPattern, fillTunnelStructureColor: fillTunnelStructureColor, fillZOffset: fillZOffset, - isDraggable: isDraggable + isDraggable: isDraggable, + customData: customData ) } func toList() -> [Any?] { @@ -167,6 +171,7 @@ struct PolygonAnnotation { fillTunnelStructureColor, fillZOffset, isDraggable, + customData, ] } } @@ -205,6 +210,8 @@ struct PolygonAnnotationOptions { var fillZOffset: Double? = nil /// Property to determine whether annotation can be manually moved around map. var isDraggable: Bool? = nil + /// JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. + var customData: [String: Any]? = nil // swift-format-ignore: AlwaysUseLowerCamelCase @@ -220,6 +227,7 @@ struct PolygonAnnotationOptions { let fillTunnelStructureColor: Int64? = nilOrValue(pigeonVar_list[8]) let fillZOffset: Double? = nilOrValue(pigeonVar_list[9]) let isDraggable: Bool? = nilOrValue(pigeonVar_list[10]) + let customData: [String: Any]? = nilOrValue(pigeonVar_list[11]) return PolygonAnnotationOptions( geometry: geometry, @@ -232,7 +240,8 @@ struct PolygonAnnotationOptions { fillPattern: fillPattern, fillTunnelStructureColor: fillTunnelStructureColor, fillZOffset: fillZOffset, - isDraggable: isDraggable + isDraggable: isDraggable, + customData: customData ) } func toList() -> [Any?] { @@ -248,6 +257,7 @@ struct PolygonAnnotationOptions { fillTunnelStructureColor, fillZOffset, isDraggable, + customData, ] } } @@ -318,6 +328,7 @@ class PolygonAnnotationMessengerPigeonCodec: FlutterStandardMessageCodec, @unche /// Generated protocol from Pigeon that represents a handler of messages from Flutter. protocol _PolygonAnnotationMessenger { + func getAnnotations(managerId: String, completion: @escaping (Result<[PolygonAnnotation], Error>) -> Void) func create(managerId: String, annotationOption: PolygonAnnotationOptions, completion: @escaping (Result) -> Void) func createMulti(managerId: String, annotationOptions: [PolygonAnnotationOptions], completion: @escaping (Result<[PolygonAnnotation], Error>) -> Void) func update(managerId: String, annotation: PolygonAnnotation, completion: @escaping (Result) -> Void) @@ -359,6 +370,23 @@ class _PolygonAnnotationMessengerSetup { /// Sets up an instance of `_PolygonAnnotationMessenger` to handle messages through the `binaryMessenger`. static func setUp(binaryMessenger: FlutterBinaryMessenger, api: _PolygonAnnotationMessenger?, messageChannelSuffix: String = "") { let channelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" + let getAnnotationsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.mapbox_maps_flutter._PolygonAnnotationMessenger.getAnnotations\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + getAnnotationsChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let managerIdArg = args[0] as! String + api.getAnnotations(managerId: managerIdArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + getAnnotationsChannel.setMessageHandler(nil) + } let createChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.mapbox_maps_flutter._PolygonAnnotationMessenger.create\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { createChannel.setMessageHandler { message, reply in diff --git a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Generated/PolylineAnnotationMessenger.swift b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Generated/PolylineAnnotationMessenger.swift index 08e849499..9d030056d 100644 --- a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Generated/PolylineAnnotationMessenger.swift +++ b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Generated/PolylineAnnotationMessenger.swift @@ -170,6 +170,8 @@ struct PolylineAnnotation { var lineWidth: Double? = nil /// Property to determine whether annotation can be manually moved around map. var isDraggable: Bool? = nil + /// JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. + var customData: [String: Any]? = nil // swift-format-ignore: AlwaysUseLowerCamelCase @@ -189,6 +191,7 @@ struct PolylineAnnotation { let linePattern: String? = nilOrValue(pigeonVar_list[12]) let lineWidth: Double? = nilOrValue(pigeonVar_list[13]) let isDraggable: Bool? = nilOrValue(pigeonVar_list[14]) + let customData: [String: Any]? = nilOrValue(pigeonVar_list[15]) return PolylineAnnotation( id: id, @@ -205,7 +208,8 @@ struct PolylineAnnotation { lineOpacity: lineOpacity, linePattern: linePattern, lineWidth: lineWidth, - isDraggable: isDraggable + isDraggable: isDraggable, + customData: customData ) } func toList() -> [Any?] { @@ -225,6 +229,7 @@ struct PolylineAnnotation { linePattern, lineWidth, isDraggable, + customData, ] } } @@ -277,6 +282,8 @@ struct PolylineAnnotationOptions { var lineWidth: Double? = nil /// Property to determine whether annotation can be manually moved around map. var isDraggable: Bool? = nil + /// JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. + var customData: [String: Any]? = nil // swift-format-ignore: AlwaysUseLowerCamelCase @@ -295,6 +302,7 @@ struct PolylineAnnotationOptions { let linePattern: String? = nilOrValue(pigeonVar_list[11]) let lineWidth: Double? = nilOrValue(pigeonVar_list[12]) let isDraggable: Bool? = nilOrValue(pigeonVar_list[13]) + let customData: [String: Any]? = nilOrValue(pigeonVar_list[14]) return PolylineAnnotationOptions( geometry: geometry, @@ -310,7 +318,8 @@ struct PolylineAnnotationOptions { lineOpacity: lineOpacity, linePattern: linePattern, lineWidth: lineWidth, - isDraggable: isDraggable + isDraggable: isDraggable, + customData: customData ) } func toList() -> [Any?] { @@ -329,6 +338,7 @@ struct PolylineAnnotationOptions { linePattern, lineWidth, isDraggable, + customData, ] } } @@ -426,6 +436,7 @@ class PolylineAnnotationMessengerPigeonCodec: FlutterStandardMessageCodec, @unch /// Generated protocol from Pigeon that represents a handler of messages from Flutter. protocol _PolylineAnnotationMessenger { + func getAnnotations(managerId: String, completion: @escaping (Result<[PolylineAnnotation], Error>) -> Void) func create(managerId: String, annotationOption: PolylineAnnotationOptions, completion: @escaping (Result) -> Void) func createMulti(managerId: String, annotationOptions: [PolylineAnnotationOptions], completion: @escaping (Result<[PolylineAnnotation], Error>) -> Void) func update(managerId: String, annotation: PolylineAnnotation, completion: @escaping (Result) -> Void) @@ -499,6 +510,23 @@ class _PolylineAnnotationMessengerSetup { /// Sets up an instance of `_PolylineAnnotationMessenger` to handle messages through the `binaryMessenger`. static func setUp(binaryMessenger: FlutterBinaryMessenger, api: _PolylineAnnotationMessenger?, messageChannelSuffix: String = "") { let channelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" + let getAnnotationsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.mapbox_maps_flutter._PolylineAnnotationMessenger.getAnnotations\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + getAnnotationsChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let managerIdArg = args[0] as! String + api.getAnnotations(managerId: managerIdArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + getAnnotationsChannel.setMessageHandler(nil) + } let createChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.mapbox_maps_flutter._PolylineAnnotationMessenger.create\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { createChannel.setMessageHandler { message, reply in diff --git a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/TurfAdapters.swift b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/TurfAdapters.swift index 5abaaea56..af0c6b23b 100644 --- a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/TurfAdapters.swift +++ b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/TurfAdapters.swift @@ -110,3 +110,40 @@ extension LocationCoordinate2D { [longitude, latitude] } } + +extension JSONValue { + static func fromAny(_ any: Any) -> Self? { + switch any { + case let string as String: + return .string(string) + case let number as Double: + return .number(number) + case let number as Float: + return .number(Double(number)) + case let number as Int: + return .number(Double(number)) + case let boolean as Bool: + return .boolean(boolean) + case let array as [Any]: + return .array(array.compactMap { fromAny($0) }) + case let obj as [String: Any]: + return .object(obj.compactMapValues { fromAny($0) }) + default: return nil + } + } + + var toAny: Any { + switch self { + case .string(let string): + return string + case .number(let number): + return number + case .boolean(let boolean): + return boolean + case .array(let array): + return array.compactMap { $0?.toAny } + case .object(let object): + return object.compactMapValues { $0?.toAny } + } + } +} diff --git a/lib/src/annotation/circle_annotation_manager.dart b/lib/src/annotation/circle_annotation_manager.dart index 014d43dd8..a75c9446c 100644 --- a/lib/src/annotation/circle_annotation_manager.dart +++ b/lib/src/annotation/circle_annotation_manager.dart @@ -89,6 +89,10 @@ class CircleAnnotationManager extends BaseAnnotationManager { }).asCancelable(); } + /// Get all annotations of manager. + Future> getAnnotations() => + _annotationMessenger.getAnnotations(id); + /// Create a new annotation with the option. Future create(CircleAnnotationOptions annotation) => _annotationMessenger.create(id, annotation); diff --git a/lib/src/annotation/point_annotation_manager.dart b/lib/src/annotation/point_annotation_manager.dart index bebb5333d..497d78db4 100644 --- a/lib/src/annotation/point_annotation_manager.dart +++ b/lib/src/annotation/point_annotation_manager.dart @@ -88,6 +88,10 @@ class PointAnnotationManager extends BaseAnnotationManager { }).asCancelable(); } + /// Get all annotations of manager. + Future> getAnnotations() => + _annotationMessenger.getAnnotations(id); + /// Create a new annotation with the option. Future create(PointAnnotationOptions annotation) => _annotationMessenger.create(id, annotation); diff --git a/lib/src/annotation/polygon_annotation_manager.dart b/lib/src/annotation/polygon_annotation_manager.dart index 99caa8fa1..298e933aa 100644 --- a/lib/src/annotation/polygon_annotation_manager.dart +++ b/lib/src/annotation/polygon_annotation_manager.dart @@ -89,6 +89,10 @@ class PolygonAnnotationManager extends BaseAnnotationManager { }).asCancelable(); } + /// Get all annotations of manager. + Future> getAnnotations() => + _annotationMessenger.getAnnotations(id); + /// Create a new annotation with the option. Future create(PolygonAnnotationOptions annotation) => _annotationMessenger.create(id, annotation); diff --git a/lib/src/annotation/polyline_annotation_manager.dart b/lib/src/annotation/polyline_annotation_manager.dart index 458ae03e4..808ef127a 100644 --- a/lib/src/annotation/polyline_annotation_manager.dart +++ b/lib/src/annotation/polyline_annotation_manager.dart @@ -89,6 +89,10 @@ class PolylineAnnotationManager extends BaseAnnotationManager { }).asCancelable(); } + /// Get all annotations of manager. + Future> getAnnotations() => + _annotationMessenger.getAnnotations(id); + /// Create a new annotation with the option. Future create(PolylineAnnotationOptions annotation) => _annotationMessenger.create(id, annotation); diff --git a/lib/src/pigeons/circle_annotation_messenger.dart b/lib/src/pigeons/circle_annotation_messenger.dart index af7c778db..2d7037e45 100644 --- a/lib/src/pigeons/circle_annotation_messenger.dart +++ b/lib/src/pigeons/circle_annotation_messenger.dart @@ -57,6 +57,7 @@ class CircleAnnotation { this.circleStrokeOpacity, this.circleStrokeWidth, this.isDraggable, + this.customData, }); /// The id for annotation @@ -99,6 +100,9 @@ class CircleAnnotation { /// Property to determine whether annotation can be manually moved around map. bool? isDraggable; + /// JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. + Map? customData; + List _toList() { return [ id, @@ -112,6 +116,7 @@ class CircleAnnotation { circleStrokeOpacity, circleStrokeWidth, isDraggable, + customData, ]; } @@ -133,6 +138,8 @@ class CircleAnnotation { circleStrokeOpacity: result[8] as double?, circleStrokeWidth: result[9] as double?, isDraggable: result[10] as bool?, + customData: + (result[11] as Map?)?.cast(), ); } @@ -155,7 +162,8 @@ class CircleAnnotation { circleStrokeColor == other.circleStrokeColor && circleStrokeOpacity == other.circleStrokeOpacity && circleStrokeWidth == other.circleStrokeWidth && - isDraggable == other.isDraggable; + isDraggable == other.isDraggable && + _deepEquals(customData, other.customData); } @override @@ -175,6 +183,7 @@ class CircleAnnotationOptions { this.circleStrokeOpacity, this.circleStrokeWidth, this.isDraggable, + this.customData, }); /// The geometry that determines the location/shape of this annotation @@ -214,6 +223,9 @@ class CircleAnnotationOptions { /// Property to determine whether annotation can be manually moved around map. bool? isDraggable; + /// JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. + Map? customData; + List _toList() { return [ geometry, @@ -226,6 +238,7 @@ class CircleAnnotationOptions { circleStrokeOpacity, circleStrokeWidth, isDraggable, + customData, ]; } @@ -246,6 +259,8 @@ class CircleAnnotationOptions { circleStrokeOpacity: result[7] as double?, circleStrokeWidth: result[8] as double?, isDraggable: result[9] as bool?, + customData: + (result[10] as Map?)?.cast(), ); } @@ -267,7 +282,8 @@ class CircleAnnotationOptions { circleStrokeColor == other.circleStrokeColor && circleStrokeOpacity == other.circleStrokeOpacity && circleStrokeWidth == other.circleStrokeWidth && - isDraggable == other.isDraggable; + isDraggable == other.isDraggable && + _deepEquals(customData, other.customData); } @override @@ -351,6 +367,38 @@ class _CircleAnnotationMessenger { final String pigeonVar_messageChannelSuffix; + Future> getAnnotations(String managerId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.mapbox_maps_flutter._CircleAnnotationMessenger.getAnnotations$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = + pigeonVar_channel.send([managerId]); + final List? pigeonVar_replyList = + await pigeonVar_sendFuture as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as List?)! + .cast(); + } + } + Future create( String managerId, CircleAnnotationOptions annotationOption) async { final String pigeonVar_channelName = diff --git a/lib/src/pigeons/point_annotation_messenger.dart b/lib/src/pigeons/point_annotation_messenger.dart index 3b8dab0ab..ec6137f0d 100644 --- a/lib/src/pigeons/point_annotation_messenger.dart +++ b/lib/src/pigeons/point_annotation_messenger.dart @@ -302,6 +302,7 @@ class PointAnnotation { this.textOcclusionOpacity, this.textOpacity, this.isDraggable, + this.customData, }); /// The id for annotation @@ -457,6 +458,9 @@ class PointAnnotation { /// Property to determine whether annotation can be manually moved around map. bool? isDraggable; + /// JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. + Map? customData; + List _toList() { return [ id, @@ -498,6 +502,7 @@ class PointAnnotation { textOcclusionOpacity, textOpacity, isDraggable, + customData, ]; } @@ -547,6 +552,8 @@ class PointAnnotation { textOcclusionOpacity: result[36] as double?, textOpacity: result[37] as double?, isDraggable: result[38] as bool?, + customData: + (result[39] as Map?)?.cast(), ); } @@ -597,7 +604,8 @@ class PointAnnotation { textHaloWidth == other.textHaloWidth && textOcclusionOpacity == other.textOcclusionOpacity && textOpacity == other.textOpacity && - isDraggable == other.isDraggable; + isDraggable == other.isDraggable && + _deepEquals(customData, other.customData); } @override @@ -645,6 +653,7 @@ class PointAnnotationOptions { this.textOcclusionOpacity, this.textOpacity, this.isDraggable, + this.customData, }); /// The geometry that determines the location/shape of this annotation @@ -797,6 +806,9 @@ class PointAnnotationOptions { /// Property to determine whether annotation can be manually moved around map. bool? isDraggable; + /// JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. + Map? customData; + List _toList() { return [ geometry, @@ -837,6 +849,7 @@ class PointAnnotationOptions { textOcclusionOpacity, textOpacity, isDraggable, + customData, ]; } @@ -885,6 +898,8 @@ class PointAnnotationOptions { textOcclusionOpacity: result[35] as double?, textOpacity: result[36] as double?, isDraggable: result[37] as bool?, + customData: + (result[38] as Map?)?.cast(), ); } @@ -934,7 +949,8 @@ class PointAnnotationOptions { textHaloWidth == other.textHaloWidth && textOcclusionOpacity == other.textOcclusionOpacity && textOpacity == other.textOpacity && - isDraggable == other.isDraggable; + isDraggable == other.isDraggable && + _deepEquals(customData, other.customData); } @override @@ -1090,6 +1106,38 @@ class _PointAnnotationMessenger { final String pigeonVar_messageChannelSuffix; + Future> getAnnotations(String managerId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.mapbox_maps_flutter._PointAnnotationMessenger.getAnnotations$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = + pigeonVar_channel.send([managerId]); + final List? pigeonVar_replyList = + await pigeonVar_sendFuture as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as List?)! + .cast(); + } + } + Future create( String managerId, PointAnnotationOptions annotationOption) async { final String pigeonVar_channelName = diff --git a/lib/src/pigeons/polygon_annotation_messenger.dart b/lib/src/pigeons/polygon_annotation_messenger.dart index c6ebc0121..e0eea0d0c 100644 --- a/lib/src/pigeons/polygon_annotation_messenger.dart +++ b/lib/src/pigeons/polygon_annotation_messenger.dart @@ -41,6 +41,7 @@ class PolygonAnnotation { this.fillTunnelStructureColor, this.fillZOffset, this.isDraggable, + this.customData, }); /// The id for annotation @@ -89,6 +90,9 @@ class PolygonAnnotation { /// Property to determine whether annotation can be manually moved around map. bool? isDraggable; + /// JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. + Map? customData; + List _toList() { return [ id, @@ -103,6 +107,7 @@ class PolygonAnnotation { fillTunnelStructureColor, fillZOffset, isDraggable, + customData, ]; } @@ -125,6 +130,8 @@ class PolygonAnnotation { fillTunnelStructureColor: result[9] as int?, fillZOffset: result[10] as double?, isDraggable: result[11] as bool?, + customData: + (result[12] as Map?)?.cast(), ); } @@ -148,7 +155,8 @@ class PolygonAnnotation { fillPattern == other.fillPattern && fillTunnelStructureColor == other.fillTunnelStructureColor && fillZOffset == other.fillZOffset && - isDraggable == other.isDraggable; + isDraggable == other.isDraggable && + _deepEquals(customData, other.customData); } @override @@ -169,6 +177,7 @@ class PolygonAnnotationOptions { this.fillTunnelStructureColor, this.fillZOffset, this.isDraggable, + this.customData, }); /// The geometry that determines the location/shape of this annotation @@ -214,6 +223,9 @@ class PolygonAnnotationOptions { /// Property to determine whether annotation can be manually moved around map. bool? isDraggable; + /// JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. + Map? customData; + List _toList() { return [ geometry, @@ -227,6 +239,7 @@ class PolygonAnnotationOptions { fillTunnelStructureColor, fillZOffset, isDraggable, + customData, ]; } @@ -248,6 +261,8 @@ class PolygonAnnotationOptions { fillTunnelStructureColor: result[8] as int?, fillZOffset: result[9] as double?, isDraggable: result[10] as bool?, + customData: + (result[11] as Map?)?.cast(), ); } @@ -271,7 +286,8 @@ class PolygonAnnotationOptions { fillPattern == other.fillPattern && fillTunnelStructureColor == other.fillTunnelStructureColor && fillZOffset == other.fillZOffset && - isDraggable == other.isDraggable; + isDraggable == other.isDraggable && + _deepEquals(customData, other.customData); } @override @@ -343,6 +359,38 @@ class _PolygonAnnotationMessenger { final String pigeonVar_messageChannelSuffix; + Future> getAnnotations(String managerId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.mapbox_maps_flutter._PolygonAnnotationMessenger.getAnnotations$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = + pigeonVar_channel.send([managerId]); + final List? pigeonVar_replyList = + await pigeonVar_sendFuture as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as List?)! + .cast(); + } + } + Future create( String managerId, PolygonAnnotationOptions annotationOption) async { final String pigeonVar_channelName = diff --git a/lib/src/pigeons/polyline_annotation_messenger.dart b/lib/src/pigeons/polyline_annotation_messenger.dart index 9a38c52fd..e9927286f 100644 --- a/lib/src/pigeons/polyline_annotation_messenger.dart +++ b/lib/src/pigeons/polyline_annotation_messenger.dart @@ -86,6 +86,7 @@ class PolylineAnnotation { this.linePattern, this.lineWidth, this.isDraggable, + this.customData, }); /// The id for annotation @@ -151,6 +152,9 @@ class PolylineAnnotation { /// Property to determine whether annotation can be manually moved around map. bool? isDraggable; + /// JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. + Map? customData; + List _toList() { return [ id, @@ -168,6 +172,7 @@ class PolylineAnnotation { linePattern, lineWidth, isDraggable, + customData, ]; } @@ -193,6 +198,8 @@ class PolylineAnnotation { linePattern: result[12] as String?, lineWidth: result[13] as double?, isDraggable: result[14] as bool?, + customData: + (result[15] as Map?)?.cast(), ); } @@ -219,7 +226,8 @@ class PolylineAnnotation { lineOpacity == other.lineOpacity && linePattern == other.linePattern && lineWidth == other.lineWidth && - isDraggable == other.isDraggable; + isDraggable == other.isDraggable && + _deepEquals(customData, other.customData); } @override @@ -243,6 +251,7 @@ class PolylineAnnotationOptions { this.linePattern, this.lineWidth, this.isDraggable, + this.customData, }); /// The geometry that determines the location/shape of this annotation @@ -305,6 +314,9 @@ class PolylineAnnotationOptions { /// Property to determine whether annotation can be manually moved around map. bool? isDraggable; + /// JSON convertible properties associated with the annotation, used to enrich Feature GeoJSON `properties["custom_data"]` field. + Map? customData; + List _toList() { return [ geometry, @@ -321,6 +333,7 @@ class PolylineAnnotationOptions { linePattern, lineWidth, isDraggable, + customData, ]; } @@ -345,6 +358,8 @@ class PolylineAnnotationOptions { linePattern: result[11] as String?, lineWidth: result[12] as double?, isDraggable: result[13] as bool?, + customData: + (result[14] as Map?)?.cast(), ); } @@ -371,7 +386,8 @@ class PolylineAnnotationOptions { lineOpacity == other.lineOpacity && linePattern == other.linePattern && lineWidth == other.lineWidth && - isDraggable == other.isDraggable; + isDraggable == other.isDraggable && + _deepEquals(customData, other.customData); } @override @@ -461,6 +477,38 @@ class _PolylineAnnotationMessenger { final String pigeonVar_messageChannelSuffix; + Future> getAnnotations(String managerId) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.mapbox_maps_flutter._PolylineAnnotationMessenger.getAnnotations$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = + pigeonVar_channel.send([managerId]); + final List? pigeonVar_replyList = + await pigeonVar_sendFuture as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as List?)! + .cast(); + } + } + Future create( String managerId, PolylineAnnotationOptions annotationOption) async { final String pigeonVar_channelName = From 76dc59d0077c4fac5925a70cfa257fa4ac4d2877 Mon Sep 17 00:00:00 2001 From: Roman Laitarenko Date: Tue, 11 Nov 2025 11:33:30 +0200 Subject: [PATCH 2/2] add changelog entry --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49bfad857..21bba6407 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +### 2.17.0-rc.1 + +* Add the ability to get all annotations from an annotation manager. +* Add `customData` field to annotations to be able to pass user data. + ### 2.17.0-beta.1 > [!NOTE]