@maplibre/maplibre-react-native 11.0.0-alpha.42 → 11.0.0-alpha.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/android/build.gradle +1 -3
  2. package/android/src/main/java/org/maplibre/reactnative/MLRNPackage.kt +3 -3
  3. package/android/src/main/java/org/maplibre/reactnative/components/annotations/callout/MLRNCallout.kt +7 -0
  4. package/android/src/main/java/org/maplibre/reactnative/components/annotations/callout/MLRNCalloutManager.kt +29 -0
  5. package/android/src/main/java/org/maplibre/reactnative/components/annotations/markerview/MLRNMarkerView.kt +220 -0
  6. package/android/src/main/java/org/maplibre/reactnative/components/annotations/markerview/MLRNMarkerViewContent.kt +50 -0
  7. package/android/src/main/java/org/maplibre/reactnative/components/annotations/markerview/MLRNMarkerViewManager.kt +81 -0
  8. package/android/src/main/java/org/maplibre/reactnative/components/annotations/markerview/MarkerViewManager.kt +127 -0
  9. package/android/src/main/java/org/maplibre/reactnative/components/annotations/pointannotation/MLRNPointAnnotation.kt +407 -0
  10. package/android/src/main/java/org/maplibre/reactnative/components/annotations/pointannotation/MLRNPointAnnotationManager.kt +105 -0
  11. package/android/src/main/java/org/maplibre/reactnative/components/mapview/MLRNMapView.kt +38 -37
  12. package/android/src/main/java/org/maplibre/reactnative/events/PointAnnotationClickEvent.java +1 -1
  13. package/android/src/main/java/org/maplibre/reactnative/events/PointAnnotationDragEvent.java +1 -1
  14. package/android/src/main/java/org/maplibre/reactnative/events/PointAnnotationEvent.kt +30 -0
  15. package/ios/components/annotations/callout/MLRNCalloutComponentView.h +10 -0
  16. package/ios/components/annotations/callout/MLRNCalloutComponentView.mm +91 -0
  17. package/ios/components/annotations/point-annotation/MLRNPointAnnotation.h +44 -0
  18. package/ios/components/annotations/{MLRNPointAnnotation.m → point-annotation/MLRNPointAnnotation.m} +69 -35
  19. package/ios/components/annotations/point-annotation/MLRNPointAnnotationComponentView.h +10 -0
  20. package/ios/components/annotations/point-annotation/MLRNPointAnnotationComponentView.mm +331 -0
  21. package/ios/components/map-view/MLRNMapView.m +4 -5
  22. package/lib/commonjs/components/annotations/callout/Callout.js +94 -0
  23. package/lib/commonjs/components/annotations/callout/Callout.js.map +1 -0
  24. package/lib/commonjs/components/annotations/callout/CalloutNativeComponent.ts +11 -0
  25. package/lib/commonjs/components/annotations/marker-view/MarkerView.js +70 -0
  26. package/lib/commonjs/components/annotations/marker-view/MarkerView.js.map +1 -0
  27. package/lib/commonjs/components/annotations/marker-view/MarkerViewNativeComponent.ts +30 -0
  28. package/lib/commonjs/components/annotations/point-annotation/PointAnnotation.js +88 -0
  29. package/lib/commonjs/components/annotations/point-annotation/PointAnnotation.js.map +1 -0
  30. package/lib/commonjs/components/annotations/point-annotation/PointAnnotationNativeComponent.ts +58 -0
  31. package/lib/commonjs/index.js +3 -3
  32. package/lib/commonjs/index.js.map +1 -1
  33. package/lib/commonjs/types/Anchor.js +68 -0
  34. package/lib/commonjs/types/Anchor.js.map +1 -0
  35. package/lib/commonjs/utils/animated/Animated.js +4 -0
  36. package/lib/commonjs/utils/animated/Animated.js.map +1 -1
  37. package/lib/module/components/annotations/callout/Callout.js +88 -0
  38. package/lib/module/components/annotations/callout/Callout.js.map +1 -0
  39. package/lib/module/components/annotations/callout/CalloutNativeComponent.ts +11 -0
  40. package/lib/module/components/annotations/marker-view/MarkerView.js +64 -0
  41. package/lib/module/components/annotations/marker-view/MarkerView.js.map +1 -0
  42. package/lib/module/components/annotations/marker-view/MarkerViewNativeComponent.ts +30 -0
  43. package/lib/module/components/annotations/point-annotation/PointAnnotation.js +83 -0
  44. package/lib/module/components/annotations/point-annotation/PointAnnotation.js.map +1 -0
  45. package/lib/module/components/annotations/point-annotation/PointAnnotationNativeComponent.ts +58 -0
  46. package/lib/module/index.js +3 -3
  47. package/lib/module/index.js.map +1 -1
  48. package/lib/module/types/Anchor.js +64 -0
  49. package/lib/module/types/Anchor.js.map +1 -0
  50. package/lib/module/utils/animated/Animated.js +4 -0
  51. package/lib/module/utils/animated/Animated.js.map +1 -1
  52. package/lib/typescript/{module/src/components/annotations → commonjs/src/components/annotations/callout}/Callout.d.ts +9 -9
  53. package/lib/typescript/commonjs/src/components/annotations/callout/Callout.d.ts.map +1 -0
  54. package/lib/typescript/commonjs/src/components/annotations/callout/CalloutNativeComponent.d.ts +6 -0
  55. package/lib/typescript/commonjs/src/components/annotations/callout/CalloutNativeComponent.d.ts.map +1 -0
  56. package/lib/typescript/commonjs/src/components/annotations/marker-view/MarkerView.d.ts +52 -0
  57. package/lib/typescript/commonjs/src/components/annotations/marker-view/MarkerView.d.ts.map +1 -0
  58. package/lib/typescript/commonjs/src/components/annotations/marker-view/MarkerViewNativeComponent.d.ts +21 -0
  59. package/lib/typescript/commonjs/src/components/annotations/marker-view/MarkerViewNativeComponent.d.ts.map +1 -0
  60. package/lib/typescript/commonjs/src/components/annotations/point-annotation/PointAnnotation.d.ts +95 -0
  61. package/lib/typescript/commonjs/src/components/annotations/point-annotation/PointAnnotation.d.ts.map +1 -0
  62. package/lib/typescript/commonjs/src/components/annotations/point-annotation/PointAnnotationNativeComponent.d.ts +43 -0
  63. package/lib/typescript/commonjs/src/components/annotations/point-annotation/PointAnnotationNativeComponent.d.ts.map +1 -0
  64. package/lib/typescript/commonjs/src/index.d.ts +4 -4
  65. package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
  66. package/lib/typescript/commonjs/src/types/Anchor.d.ts +17 -0
  67. package/lib/typescript/commonjs/src/types/Anchor.d.ts.map +1 -0
  68. package/lib/typescript/commonjs/src/utils/animated/Animated.d.ts +1 -0
  69. package/lib/typescript/commonjs/src/utils/animated/Animated.d.ts.map +1 -1
  70. package/lib/typescript/{commonjs/src/components/annotations → module/src/components/annotations/callout}/Callout.d.ts +9 -9
  71. package/lib/typescript/module/src/components/annotations/callout/Callout.d.ts.map +1 -0
  72. package/lib/typescript/module/src/components/annotations/callout/CalloutNativeComponent.d.ts +6 -0
  73. package/lib/typescript/module/src/components/annotations/callout/CalloutNativeComponent.d.ts.map +1 -0
  74. package/lib/typescript/module/src/components/annotations/marker-view/MarkerView.d.ts +52 -0
  75. package/lib/typescript/module/src/components/annotations/marker-view/MarkerView.d.ts.map +1 -0
  76. package/lib/typescript/module/src/components/annotations/marker-view/MarkerViewNativeComponent.d.ts +21 -0
  77. package/lib/typescript/module/src/components/annotations/marker-view/MarkerViewNativeComponent.d.ts.map +1 -0
  78. package/lib/typescript/module/src/components/annotations/point-annotation/PointAnnotation.d.ts +95 -0
  79. package/lib/typescript/module/src/components/annotations/point-annotation/PointAnnotation.d.ts.map +1 -0
  80. package/lib/typescript/module/src/components/annotations/point-annotation/PointAnnotationNativeComponent.d.ts +43 -0
  81. package/lib/typescript/module/src/components/annotations/point-annotation/PointAnnotationNativeComponent.d.ts.map +1 -0
  82. package/lib/typescript/module/src/index.d.ts +4 -4
  83. package/lib/typescript/module/src/index.d.ts.map +1 -1
  84. package/lib/typescript/module/src/types/Anchor.d.ts +17 -0
  85. package/lib/typescript/module/src/types/Anchor.d.ts.map +1 -0
  86. package/lib/typescript/module/src/utils/animated/Animated.d.ts +1 -0
  87. package/lib/typescript/module/src/utils/animated/Animated.d.ts.map +1 -1
  88. package/package.json +3 -1
  89. package/src/components/annotations/callout/Callout.tsx +145 -0
  90. package/src/components/annotations/callout/CalloutNativeComponent.ts +11 -0
  91. package/src/components/annotations/marker-view/MarkerView.tsx +124 -0
  92. package/src/components/annotations/marker-view/MarkerViewNativeComponent.ts +30 -0
  93. package/src/components/annotations/point-annotation/PointAnnotation.tsx +219 -0
  94. package/src/components/annotations/point-annotation/PointAnnotationNativeComponent.ts +58 -0
  95. package/src/index.ts +15 -4
  96. package/src/types/Anchor.ts +44 -0
  97. package/src/utils/animated/Animated.tsx +6 -0
  98. package/android/src/main/java/org/maplibre/reactnative/components/annotations/MLRNCallout.java +0 -11
  99. package/android/src/main/java/org/maplibre/reactnative/components/annotations/MLRNCalloutManager.java +0 -18
  100. package/android/src/main/java/org/maplibre/reactnative/components/annotations/MLRNMarkerView.java +0 -112
  101. package/android/src/main/java/org/maplibre/reactnative/components/annotations/MLRNMarkerViewManager.java +0 -45
  102. package/android/src/main/java/org/maplibre/reactnative/components/annotations/MLRNPointAnnotation.java +0 -361
  103. package/android/src/main/java/org/maplibre/reactnative/components/annotations/MLRNPointAnnotationManager.java +0 -84
  104. package/android/src/main/java/org/maplibre/reactnative/components/annotations/MarkerView.java +0 -23
  105. package/android/src/main/java/org/maplibre/reactnative/components/annotations/MarkerViewManager.java +0 -69
  106. package/ios/components/annotations/MLRNCalloutManager.h +0 -5
  107. package/ios/components/annotations/MLRNCalloutManager.m +0 -12
  108. package/ios/components/annotations/MLRNPointAnnotation.h +0 -33
  109. package/ios/components/annotations/MLRNPointAnnotationManager.h +0 -5
  110. package/ios/components/annotations/MLRNPointAnnotationManager.m +0 -27
  111. package/lib/commonjs/components/annotations/Callout.js +0 -101
  112. package/lib/commonjs/components/annotations/Callout.js.map +0 -1
  113. package/lib/commonjs/components/annotations/MarkerView.js +0 -60
  114. package/lib/commonjs/components/annotations/MarkerView.js.map +0 -1
  115. package/lib/commonjs/components/annotations/PointAnnotation.js +0 -114
  116. package/lib/commonjs/components/annotations/PointAnnotation.js.map +0 -1
  117. package/lib/module/components/annotations/Callout.js +0 -96
  118. package/lib/module/components/annotations/Callout.js.map +0 -1
  119. package/lib/module/components/annotations/MarkerView.js +0 -55
  120. package/lib/module/components/annotations/MarkerView.js.map +0 -1
  121. package/lib/module/components/annotations/PointAnnotation.js +0 -110
  122. package/lib/module/components/annotations/PointAnnotation.js.map +0 -1
  123. package/lib/typescript/commonjs/src/components/annotations/Callout.d.ts.map +0 -1
  124. package/lib/typescript/commonjs/src/components/annotations/MarkerView.d.ts +0 -44
  125. package/lib/typescript/commonjs/src/components/annotations/MarkerView.d.ts.map +0 -1
  126. package/lib/typescript/commonjs/src/components/annotations/PointAnnotation.d.ts +0 -90
  127. package/lib/typescript/commonjs/src/components/annotations/PointAnnotation.d.ts.map +0 -1
  128. package/lib/typescript/module/src/components/annotations/Callout.d.ts.map +0 -1
  129. package/lib/typescript/module/src/components/annotations/MarkerView.d.ts +0 -44
  130. package/lib/typescript/module/src/components/annotations/MarkerView.d.ts.map +0 -1
  131. package/lib/typescript/module/src/components/annotations/PointAnnotation.d.ts +0 -90
  132. package/lib/typescript/module/src/components/annotations/PointAnnotation.d.ts.map +0 -1
  133. package/src/components/annotations/Callout.tsx +0 -139
  134. package/src/components/annotations/MarkerView.tsx +0 -86
  135. package/src/components/annotations/PointAnnotation.tsx +0 -240
  136. /package/ios/components/annotations/{MLRNCallout.h → callout/MLRNCallout.h} +0 -0
  137. /package/ios/components/annotations/{MLRNCallout.m → callout/MLRNCallout.m} +0 -0
@@ -0,0 +1,407 @@
1
+ package org.maplibre.reactnative.components.annotations.pointannotation
2
+
3
+ import android.content.Context
4
+ import android.graphics.PointF
5
+ import android.graphics.Bitmap
6
+ import android.view.View
7
+
8
+ import com.facebook.react.bridge.ReactContext
9
+ import com.facebook.react.uimanager.UIManagerHelper
10
+
11
+ import org.maplibre.geojson.Point
12
+ import org.maplibre.android.geometry.LatLng
13
+ import org.maplibre.android.plugins.annotation.Symbol
14
+ import org.maplibre.android.plugins.annotation.SymbolOptions
15
+ import org.maplibre.android.maps.MapLibreMap
16
+
17
+ import org.maplibre.reactnative.components.AbstractMapFeature
18
+ import org.maplibre.reactnative.components.annotations.callout.MLRNCallout
19
+ import org.maplibre.reactnative.components.mapview.MLRNMapView
20
+ import org.maplibre.reactnative.events.PointAnnotationEvent
21
+ import org.maplibre.reactnative.utils.GeoJSONUtils
22
+ import org.maplibre.reactnative.utils.BitmapUtils
23
+
24
+ class MLRNPointAnnotation(private val mContext: Context) : AbstractMapFeature(mContext), View.OnLayoutChangeListener {
25
+ private var mAnnotation: Symbol? = null
26
+ private var mMap: MapLibreMap? = null
27
+ private var mMapView: MLRNMapView? = null
28
+
29
+ private val mHasChildren = false
30
+
31
+ private var mCoordinate: Point? = null
32
+
33
+ public var ID: String? = null
34
+ public var title: String? = null
35
+ private var mSnippet: String? = null
36
+
37
+ private var mAnchor: FloatArray? = null
38
+ private var mOffset: FloatArray? = null
39
+ private val mIsSelected = false
40
+ private var mDraggable = false
41
+
42
+ private var mChildView: View? = null
43
+ private var mChildBitmap: Bitmap? = null
44
+ private var mChildBitmapId: String? = null
45
+
46
+ private var mCalloutView: View? = null
47
+ private var mCalloutSymbol: Symbol? = null
48
+ private var mCalloutBitmap: Bitmap? = null
49
+ private var mCalloutBitmapId: String? = null
50
+
51
+ companion object {
52
+ const val MARKER_IMAGE_ID: String = "MARKER_IMAGE_ID"
53
+ }
54
+
55
+ private val surfaceId: Int
56
+ get() {
57
+ val reactContext = mContext as ReactContext
58
+ return UIManagerHelper.getSurfaceId(reactContext)
59
+ }
60
+
61
+ override fun addView(childView: View, childPosition: Int) {
62
+ if (childView is MLRNCallout) {
63
+ mCalloutView = childView
64
+ } else {
65
+ // Only accept position 0 for non-callout children - the wrapper View
66
+ // with collapsable={false} from JS side. This prevents Fabric from
67
+ // sending multiple flattened children that would overwrite mChildView.
68
+ if (childPosition != 0) {
69
+ return
70
+ }
71
+ mChildView = childView
72
+ }
73
+ childView.addOnLayoutChangeListener(this)
74
+ mMapView?.offscreenAnnotationViewContainer()?.addView(childView)
75
+ }
76
+
77
+ override fun removeView(childView: View?) {
78
+ if (childView == null) return
79
+
80
+ childView.removeOnLayoutChangeListener(this)
81
+ // Remove from offscreen container
82
+ mMapView?.offscreenAnnotationViewContainer()?.removeView(childView)
83
+
84
+ if (childView == mChildView) {
85
+ mMap?.getStyle { style ->
86
+ mChildBitmapId?.let { style.removeImage(it) }
87
+ mChildBitmap = null
88
+ mChildBitmapId = null
89
+ updateOptions()
90
+ }
91
+ mChildView = null
92
+ } else if (childView == mCalloutView) {
93
+ mCalloutView = null
94
+ }
95
+ }
96
+
97
+ override fun removeViewAt(index: Int) {
98
+ val child = getChildAt(index)
99
+ if (child != null) {
100
+ removeView(child)
101
+ }
102
+ }
103
+
104
+ override fun getChildCount(): Int {
105
+ var count = 0
106
+ if (mChildView != null) count++
107
+ if (mCalloutView != null) count++
108
+ return count
109
+ }
110
+
111
+ override fun getChildAt(index: Int): View? {
112
+ // Return children in consistent order: child view first, then callout
113
+ return when {
114
+ index == 0 && mChildView != null -> mChildView
115
+ index == 0 && mChildView == null && mCalloutView != null -> mCalloutView
116
+ index == 1 && mChildView != null && mCalloutView != null -> mCalloutView
117
+ else -> null
118
+ }
119
+ }
120
+
121
+ override fun addToMap(mapView: MLRNMapView) {
122
+ mMapView = mapView
123
+ mMap = mapView.mapLibreMap
124
+ makeMarker()
125
+
126
+ if (mChildView != null) {
127
+ if (!mChildView!!.isAttachedToWindow) {
128
+ mMapView?.offscreenAnnotationViewContainer()?.addView(mChildView)
129
+ }
130
+ addBitmapToStyle(mChildBitmap, mChildBitmapId)
131
+ updateOptions()
132
+ }
133
+ if (mCalloutView != null) {
134
+ if (!mCalloutView!!.isAttachedToWindow) {
135
+ mMapView?.offscreenAnnotationViewContainer()?.addView(mCalloutView)
136
+ }
137
+ addBitmapToStyle(mCalloutBitmap, mCalloutBitmapId)
138
+ }
139
+ }
140
+
141
+ override fun removeFromMap(mapView: MLRNMapView) {
142
+ val map = if (mMapView != null) mMapView else mapView
143
+ if (map == null) {
144
+ return
145
+ }
146
+
147
+ if (mAnnotation != null) {
148
+ map.getSymbolManager().delete(mAnnotation)
149
+ }
150
+ if (mChildView != null) {
151
+ map.offscreenAnnotationViewContainer()?.removeView(mChildView)
152
+ }
153
+ if (mCalloutView != null) {
154
+ map.offscreenAnnotationViewContainer()?.removeView(mCalloutView)
155
+ }
156
+ }
157
+
158
+ override fun onLayoutChange(v: View, left: Int, top: Int, right: Int, bottom: Int, oldLeft: Int,
159
+ oldTop: Int, oldRight: Int, oldBottom: Int) {
160
+ if (left == 0 && top == 0 && right == 0 && bottom == 0) {
161
+ return
162
+ }
163
+ if (left != oldLeft || right != oldRight || top != oldTop || bottom != oldBottom) {
164
+ refreshBitmap(v, left, top, right, bottom)
165
+ }
166
+ }
167
+
168
+ private fun refreshBitmap(v: View, left: Int, top: Int, right: Int, bottom: Int) {
169
+ val bitmap: Bitmap = BitmapUtils.viewToBitmap(v, left, top, right, bottom)
170
+ val bitmapId: String = v.id.toString()
171
+ addBitmapToStyle(bitmap, bitmapId)
172
+ if (v is MLRNCallout) {
173
+ mCalloutBitmap = bitmap
174
+ mCalloutBitmapId = bitmapId
175
+ } else {
176
+ mChildBitmap = bitmap
177
+ mChildBitmapId = bitmapId
178
+ updateOptions()
179
+ }
180
+ }
181
+
182
+ private fun refreshBitmap(v: View) {
183
+ refreshBitmap(v, v.left, v.top, v.right, v.bottom)
184
+ }
185
+
186
+ fun getLatLng(): LatLng? {
187
+ return GeoJSONUtils.toLatLng(mCoordinate)
188
+ }
189
+
190
+ val annotationId: Long? get() = mAnnotation?.id
191
+
192
+ fun setSnippet(snippet: String?) {
193
+ mSnippet = snippet
194
+ }
195
+
196
+ fun getCalloutView(): View? {
197
+ return mCalloutView
198
+ }
199
+
200
+ fun setLngLat(lngLat: DoubleArray?) {
201
+ if (lngLat == null || lngLat.size < 2) {
202
+ return
203
+ }
204
+ val point = Point.fromLngLat(lngLat[0], lngLat[1])
205
+ mCoordinate = point
206
+
207
+ if (mAnnotation != null) {
208
+ mAnnotation!!.latLng = GeoJSONUtils.toLatLng(point)!!
209
+ mMapView?.getSymbolManager()?.update(mAnnotation)
210
+ }
211
+ if (mCalloutSymbol != null) {
212
+ mCalloutSymbol!!.latLng = GeoJSONUtils.toLatLng(point)!!
213
+ mMapView?.getSymbolManager()?.update(mCalloutSymbol)
214
+ }
215
+ }
216
+
217
+ fun setAnchor(x: Float, y: Float) {
218
+ mAnchor = floatArrayOf(x, y)
219
+
220
+ if (mAnnotation != null) {
221
+ updateAnchor()
222
+ mMapView?.getSymbolManager()?.update(mAnnotation)
223
+ }
224
+ }
225
+
226
+ fun setOffset(x: Float, y: Float) {
227
+ mOffset = floatArrayOf(x, y)
228
+
229
+ if (mAnnotation != null) {
230
+ updateAnchor()
231
+ mMapView?.getSymbolManager()?.update(mAnnotation)
232
+ }
233
+ }
234
+
235
+ fun setDraggable(draggable: Boolean) {
236
+ mDraggable = draggable
237
+ if (mAnnotation != null) {
238
+ mAnnotation!!.isDraggable = draggable
239
+ mMapView?.getSymbolManager()?.update(mAnnotation)
240
+ }
241
+ }
242
+
243
+ fun getMarker(): Symbol? {
244
+ return mAnnotation
245
+ }
246
+
247
+ fun onSelect(shouldSendEvent: Boolean) {
248
+ if (mCalloutView != null) {
249
+ makeCallout()
250
+ }
251
+ if (shouldSendEvent) {
252
+ emitEvent("onSelected")
253
+ }
254
+ }
255
+
256
+ fun onDeselect() {
257
+ emitEvent("onDeselected")
258
+ if (mCalloutSymbol != null) {
259
+ mMapView?.getSymbolManager()?.delete(mCalloutSymbol)
260
+ }
261
+ }
262
+
263
+ fun onDragStart() {
264
+ val latLng = mAnnotation?.latLng
265
+ if (latLng != null) {
266
+ mCoordinate = Point.fromLngLat(latLng.longitude, latLng.latitude)
267
+ }
268
+ emitEvent("onDragStart")
269
+ }
270
+
271
+ fun onDrag() {
272
+ val latLng = mAnnotation?.latLng
273
+ if (latLng != null) {
274
+ mCoordinate = Point.fromLngLat(latLng.longitude, latLng.latitude)
275
+ }
276
+ emitEvent("onDrag")
277
+ }
278
+
279
+ fun onDragEnd() {
280
+ val latLng = mAnnotation?.latLng
281
+ if (latLng != null) {
282
+ mCoordinate = Point.fromLngLat(latLng.longitude, latLng.latitude)
283
+ }
284
+ emitEvent("onDragEnd")
285
+ }
286
+
287
+ fun makeMarker() {
288
+ val options = SymbolOptions()
289
+ .withLatLng(GeoJSONUtils.toLatLng(mCoordinate))
290
+ .withDraggable(mDraggable)
291
+ .withIconSize(1.0f)
292
+ .withSymbolSortKey(10.0f)
293
+ val symbolManager = mMapView?.getSymbolManager()
294
+ if (symbolManager != null) {
295
+ mAnnotation = symbolManager.create(options)
296
+ updateOptions()
297
+ }
298
+ }
299
+
300
+ private fun updateOptions() {
301
+ if (mAnnotation != null) {
302
+ updateIconImage()
303
+ updateAnchor()
304
+ mMapView?.getSymbolManager()?.update(mAnnotation)
305
+ }
306
+ }
307
+
308
+ private fun updateIconImage() {
309
+ if (mChildView != null) {
310
+ if (mChildBitmapId != null) {
311
+ mAnnotation?.iconImage = mChildBitmapId
312
+ }
313
+ } else {
314
+ mAnnotation?.iconImage = MARKER_IMAGE_ID
315
+ mAnnotation?.iconAnchor = "bottom"
316
+ }
317
+ }
318
+
319
+ private fun updateAnchor() {
320
+ if (mChildView != null && mChildBitmap != null) {
321
+ val scale = resources.displayMetrics.density
322
+ var offsetX = 0f
323
+ var offsetY = 0f
324
+
325
+ // Apply anchor offset (anchor is a percentage of view dimensions)
326
+ if (mAnchor != null) {
327
+ val w = (mChildBitmap!!.width / scale).toInt()
328
+ val h = (mChildBitmap!!.height / scale).toInt()
329
+ offsetX = w * mAnchor!![0] * -1
330
+ offsetY = h * mAnchor!![1] * -1
331
+ }
332
+
333
+ // Apply pixel offset
334
+ if (mOffset != null) {
335
+ offsetX += mOffset!![0]
336
+ offsetY += mOffset!![1]
337
+ }
338
+
339
+ mAnnotation?.iconAnchor = "top-left"
340
+ mAnnotation?.setIconOffset(PointF(offsetX, offsetY))
341
+ }
342
+ }
343
+
344
+ private fun makeCallout() {
345
+ var yOffset = -28f
346
+ if (mChildView != null) {
347
+ if (mChildBitmap != null) {
348
+ val scale = resources.displayMetrics.density
349
+ var h = mChildBitmap!!.height / 2
350
+ h = (h / scale).toInt()
351
+ yOffset = (h * -1).toFloat()
352
+ }
353
+ }
354
+ val options = SymbolOptions()
355
+ .withLatLng(GeoJSONUtils.toLatLng(mCoordinate))
356
+ .withIconImage(mCalloutBitmapId)
357
+ .withIconSize(1.0f)
358
+ .withIconAnchor("bottom")
359
+ .withIconOffset(floatArrayOf(0f, yOffset).toTypedArray())
360
+ .withSymbolSortKey(11.0f)
361
+ .withDraggable(false)
362
+ val symbolManager = mMapView?.getSymbolManager()
363
+ if (symbolManager != null) {
364
+ mCalloutSymbol = symbolManager.create(options)
365
+ }
366
+ }
367
+
368
+ private fun addBitmapToStyle(bitmap: Bitmap?, bitmapId: String?) {
369
+ if (mMap != null && bitmapId != null && bitmap != null) {
370
+ mMap!!.getStyle { style ->
371
+ style.addImage(bitmapId, bitmap)
372
+ }
373
+ }
374
+ }
375
+
376
+ private fun emitEvent(eventName: String) {
377
+ val latLng = GeoJSONUtils.toLatLng(mCoordinate) ?: return
378
+ val screenPos = getScreenPosition(latLng) ?: return
379
+
380
+ val event = PointAnnotationEvent(
381
+ surfaceId,
382
+ id,
383
+ eventName,
384
+ ID,
385
+ latLng,
386
+ screenPos
387
+ )
388
+
389
+ mMapView?.eventDispatcher?.dispatchEvent(event)
390
+ }
391
+
392
+ private fun getDisplayDensity(): Float {
393
+ return mContext.resources.displayMetrics.density
394
+ }
395
+
396
+ private fun getScreenPosition(latLng: LatLng): PointF? {
397
+ val screenPos = mMap?.projection?.toScreenLocation(latLng)
398
+ val density = getDisplayDensity()
399
+ screenPos?.x = screenPos?.x?.div(density) ?: 0f
400
+ screenPos?.y = screenPos?.y?.div(density) ?: 0f
401
+ return screenPos
402
+ }
403
+
404
+ fun refresh() {
405
+ mChildView?.let { refreshBitmap(it) }
406
+ }
407
+ }
@@ -0,0 +1,105 @@
1
+ package org.maplibre.reactnative.components.annotations.pointannotation
2
+
3
+ import android.view.View
4
+ import com.facebook.react.bridge.Dynamic
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.bridge.ReadableArray
7
+ import com.facebook.react.bridge.ReadableMap
8
+ import com.facebook.react.bridge.ReadableType
9
+ import com.facebook.react.module.annotations.ReactModule
10
+ import com.facebook.react.uimanager.ThemedReactContext
11
+ import com.facebook.react.uimanager.ViewGroupManager
12
+ import com.facebook.react.uimanager.ViewManagerDelegate
13
+ import com.facebook.react.uimanager.annotations.ReactProp
14
+ import com.facebook.react.viewmanagers.MLRNPointAnnotationManagerDelegate
15
+ import com.facebook.react.viewmanagers.MLRNPointAnnotationManagerInterface
16
+
17
+ @ReactModule(name = MLRNPointAnnotationManager.REACT_CLASS)
18
+ class MLRNPointAnnotationManager(private val reactApplicationContext: ReactApplicationContext) :
19
+ ViewGroupManager<MLRNPointAnnotation>(),
20
+ MLRNPointAnnotationManagerInterface<MLRNPointAnnotation> {
21
+
22
+ private val delegate: MLRNPointAnnotationManagerDelegate<MLRNPointAnnotation, MLRNPointAnnotationManager> =
23
+ MLRNPointAnnotationManagerDelegate(this)
24
+
25
+ override fun getDelegate(): ViewManagerDelegate<MLRNPointAnnotation> = delegate
26
+
27
+ companion object {
28
+ const val REACT_CLASS: String = "MLRNPointAnnotation"
29
+ }
30
+
31
+ override fun getName(): String = REACT_CLASS
32
+
33
+ override fun createViewInstance(reactContext: ThemedReactContext): MLRNPointAnnotation {
34
+ return MLRNPointAnnotation(reactContext)
35
+ }
36
+
37
+ override fun addView(parent: MLRNPointAnnotation, child: View, index: Int) {
38
+ parent.addView(child, index)
39
+ }
40
+
41
+ override fun removeViewAt(parent: MLRNPointAnnotation, index: Int) {
42
+ parent.removeViewAt(index)
43
+ }
44
+
45
+ override fun getChildCount(parent: MLRNPointAnnotation): Int {
46
+ return parent.childCount
47
+ }
48
+
49
+ override fun getChildAt(parent: MLRNPointAnnotation, index: Int): View? {
50
+ return parent.getChildAt(index)
51
+ }
52
+
53
+ @ReactProp(name = "id")
54
+ override fun setId(annotation: MLRNPointAnnotation, id: String?) {
55
+ id?.let { annotation.ID = it }
56
+ }
57
+
58
+ @ReactProp(name = "title")
59
+ override fun setTitle(annotation: MLRNPointAnnotation, title: String?) {
60
+ annotation.title = title
61
+ }
62
+
63
+ @ReactProp(name = "snippet")
64
+ override fun setSnippet(annotation: MLRNPointAnnotation, snippet: String?) {
65
+ annotation.setSnippet(snippet)
66
+ }
67
+
68
+ @ReactProp(name = "selected")
69
+ override fun setSelected(annotation: MLRNPointAnnotation, selected: Boolean) {
70
+ // Selection is handled by the map view
71
+ }
72
+
73
+ @ReactProp(name = "lngLat")
74
+ override fun setLngLat(annotation: MLRNPointAnnotation, lngLat: Dynamic) {
75
+ if (lngLat.type == ReadableType.Array) {
76
+ val arr = lngLat.asArray()
77
+ if (arr != null && arr.size() >= 2) {
78
+ annotation.setLngLat(doubleArrayOf(arr.getDouble(0), arr.getDouble(1)))
79
+ }
80
+ }
81
+ }
82
+
83
+ @ReactProp(name = "anchor")
84
+ override fun setAnchor(annotation: MLRNPointAnnotation, map: ReadableMap?) {
85
+ if (map != null) {
86
+ annotation.setAnchor(map.getDouble("x").toFloat(), map.getDouble("y").toFloat())
87
+ }
88
+ }
89
+
90
+ @ReactProp(name = "draggable")
91
+ override fun setDraggable(annotation: MLRNPointAnnotation, draggable: Boolean) {
92
+ annotation.setDraggable(draggable)
93
+ }
94
+
95
+ @ReactProp(name = "offset")
96
+ override fun setOffset(annotation: MLRNPointAnnotation, map: ReadableMap?) {
97
+ if (map != null) {
98
+ annotation.setOffset(map.getDouble("x").toFloat(), map.getDouble("y").toFloat())
99
+ }
100
+ }
101
+
102
+ override fun refresh(annotation: MLRNPointAnnotation) {
103
+ annotation.refresh()
104
+ }
105
+ }
@@ -22,8 +22,6 @@ import com.facebook.react.bridge.WritableArray
22
22
  import com.facebook.react.bridge.WritableMap
23
23
  import com.facebook.react.uimanager.UIManagerHelper
24
24
  import com.facebook.react.uimanager.events.EventDispatcher
25
- import org.json.JSONException
26
- import org.json.JSONObject
27
25
  import org.maplibre.android.camera.CameraPosition
28
26
  import org.maplibre.android.camera.CameraUpdate
29
27
  import org.maplibre.android.geometry.LatLng
@@ -46,9 +44,9 @@ import org.maplibre.android.style.layers.PropertyFactory
46
44
  import org.maplibre.geojson.Feature
47
45
  import org.maplibre.reactnative.R
48
46
  import org.maplibre.reactnative.components.AbstractMapFeature
49
- import org.maplibre.reactnative.components.annotations.MLRNMarkerView
50
- import org.maplibre.reactnative.components.annotations.MLRNPointAnnotation
51
- import org.maplibre.reactnative.components.annotations.MarkerViewManager
47
+ import org.maplibre.reactnative.components.annotations.markerview.MLRNMarkerView
48
+ import org.maplibre.reactnative.components.annotations.markerview.MarkerViewManager
49
+ import org.maplibre.reactnative.components.annotations.pointannotation.MLRNPointAnnotation
52
50
  import org.maplibre.reactnative.components.camera.MLRNCamera
53
51
  import org.maplibre.reactnative.components.images.MLRNImages
54
52
  import org.maplibre.reactnative.components.layers.MLRNLayer
@@ -123,8 +121,8 @@ open class MLRNMapView(
123
121
  private var camera: MLRNCamera? = null
124
122
  private val children: MutableList<MapChild>
125
123
  private var queuedChildren: MutableList<MapChild>?
126
- private val pointAnnotations: MutableMap<String?, MLRNPointAnnotation?>
127
- private val sources: MutableMap<String?, MLRNSource<*>?>
124
+ private val pointAnnotations: MutableMap<String, MLRNPointAnnotation>
125
+ private val sources: MutableMap<String, MLRNSource<*>>
128
126
  private val images: MutableList<MLRNImages>
129
127
 
130
128
  private val cameraChangeTracker = CameraChangeTracker()
@@ -158,12 +156,12 @@ open class MLRNMapView(
158
156
 
159
157
  private var symbolManager: SymbolManager? = null
160
158
 
161
- private var activeMarkerID: Long = -1
159
+ private var activePointAnnotationAnnotationId: Long? = null
160
+ private var pointAnnotationClicked = false
162
161
 
163
162
  private var markerViewManager: MarkerViewManager? = null
164
163
  private var offscreenAnnotationViewContainer: ViewGroup? = null
165
164
 
166
- private var annotationClicked = false
167
165
 
168
166
  val locationComponentManager: LocationComponentManager by lazy {
169
167
  LocationComponentManager(this, context)
@@ -215,7 +213,7 @@ open class MLRNMapView(
215
213
  }
216
214
 
217
215
  is MLRNPointAnnotation -> {
218
- pointAnnotations[childView.getID()] = childView
216
+ pointAnnotations[childView.ID!!] = childView
219
217
  MapChild.FeatureChild(childView)
220
218
  }
221
219
 
@@ -267,11 +265,11 @@ open class MLRNMapView(
267
265
  }
268
266
 
269
267
  is MLRNPointAnnotation -> {
270
- if (child.feature.mapboxID == activeMarkerID) {
271
- activeMarkerID = -1
268
+ if (child.feature.annotationId == activePointAnnotationAnnotationId) {
269
+ activePointAnnotationAnnotationId = null
272
270
  }
273
271
 
274
- pointAnnotations.remove(child.feature.getID())
272
+ child.feature.ID?.let { pointAnnotations.remove(it) }
275
273
  }
276
274
 
277
275
  is MLRNImages -> {
@@ -331,7 +329,7 @@ open class MLRNMapView(
331
329
  for (key in pointAnnotations.keys) {
332
330
  val annotation = pointAnnotations[key]
333
331
 
334
- if (annotation != null && markerID == annotation.mapboxID) {
332
+ if (annotation != null && markerID == annotation.annotationId) {
335
333
  return annotation
336
334
  }
337
335
  }
@@ -434,12 +432,6 @@ open class MLRNMapView(
434
432
  handleMapChangedEvent("onRegionWillChange", true)
435
433
  }
436
434
 
437
- mapLibreMap.addOnCameraMoveListener {
438
- if (markerViewManager != null) {
439
- markerViewManager!!.updateMarkers()
440
- }
441
- }
442
-
443
435
  mapLibreMap.addOnMoveListener(
444
436
  object : MapLibreMap.OnMoveListener {
445
437
  override fun onMoveBegin(detector: MoveGestureDetector) {
@@ -480,7 +472,7 @@ open class MLRNMapView(
480
472
  symbolManager!!.addDragListener(
481
473
  object : OnSymbolDragListener {
482
474
  override fun onAnnotationDragStarted(symbol: Symbol) {
483
- annotationClicked = true
475
+ pointAnnotationClicked = true
484
476
  val selectedMarkerID = symbol.id
485
477
  val annotation = getPointAnnotationByMarkerID(selectedMarkerID)
486
478
  annotation?.onDragStart()
@@ -493,7 +485,7 @@ open class MLRNMapView(
493
485
  }
494
486
 
495
487
  override fun onAnnotationDragFinished(symbol: Symbol) {
496
- annotationClicked = false
488
+ pointAnnotationClicked = false
497
489
  val selectedMarkerID = symbol.id
498
490
  val annotation = getPointAnnotationByMarkerID(selectedMarkerID)
499
491
  annotation?.onDragEnd()
@@ -556,9 +548,15 @@ open class MLRNMapView(
556
548
  }
557
549
 
558
550
  override fun onMapClick(latLng: LatLng): Boolean {
559
- if (annotationClicked) {
560
- annotationClicked = false
561
- return true
551
+ if (pointAnnotationClicked) {
552
+ pointAnnotationClicked = false
553
+ }
554
+
555
+ if (activePointAnnotationAnnotationId != null) {
556
+ val active = pointAnnotations.values.find { it.annotationId == activePointAnnotationAnnotationId }
557
+ if (active != null) {
558
+ deselectAnnotation(active)
559
+ }
562
560
  }
563
561
 
564
562
  val screenPoint = mapLibreMap!!.projection.toScreenLocation(latLng)
@@ -602,10 +600,10 @@ open class MLRNMapView(
602
600
  }
603
601
 
604
602
  override fun onMapLongClick(latLng: LatLng): Boolean {
605
- if (annotationClicked) {
606
- annotationClicked = false
607
- return true
603
+ if (pointAnnotationClicked) {
604
+ pointAnnotationClicked = false
608
605
  }
606
+
609
607
  val screenPoint = mapLibreMap!!.projection.toScreenLocation(latLng)
610
608
 
611
609
  val event = MapPressEvent(surfaceId, id, "onLongPress", latLng, screenPoint)
@@ -615,20 +613,22 @@ open class MLRNMapView(
615
613
  }
616
614
 
617
615
  fun onMarkerClick(symbol: Symbol) {
618
- annotationClicked = true
616
+ pointAnnotationClicked = true
619
617
  val selectedMarkerID = symbol.id
620
618
 
621
619
  var activeAnnotation: MLRNPointAnnotation? = null
622
620
  var nextActiveAnnotation: MLRNPointAnnotation? = null
623
621
 
624
622
  for (key in pointAnnotations.keys) {
625
- val annotation = pointAnnotations[key]
626
- val curMarkerID = annotation!!.mapboxID
627
- if (activeMarkerID == curMarkerID) {
628
- activeAnnotation = annotation
623
+ val pointAnnotation = pointAnnotations[key]
624
+ val currentAnnotationId = pointAnnotation!!.annotationId
625
+
626
+ if (activePointAnnotationAnnotationId == currentAnnotationId) {
627
+ activeAnnotation = pointAnnotation
629
628
  }
630
- if (selectedMarkerID == curMarkerID && activeMarkerID != curMarkerID) {
631
- nextActiveAnnotation = annotation
629
+
630
+ if (selectedMarkerID == currentAnnotationId && activePointAnnotationAnnotationId != currentAnnotationId) {
631
+ nextActiveAnnotation = pointAnnotation
632
632
  }
633
633
  }
634
634
 
@@ -642,12 +642,12 @@ open class MLRNMapView(
642
642
  }
643
643
 
644
644
  fun selectAnnotation(annotation: MLRNPointAnnotation) {
645
- activeMarkerID = annotation.mapboxID
645
+ activePointAnnotationAnnotationId = annotation.annotationId
646
646
  annotation.onSelect(true)
647
647
  }
648
648
 
649
649
  fun deselectAnnotation(annotation: MLRNPointAnnotation) {
650
- activeMarkerID = -1
650
+ activePointAnnotationAnnotationId = null
651
651
  annotation.onDeselect()
652
652
  }
653
653
 
@@ -672,6 +672,7 @@ open class MLRNMapView(
672
672
  }
673
673
 
674
674
  override fun onWillStartRenderingFrame() {
675
+ markerViewManager?.updateMarkers()
675
676
  handleMapChangedEvent("onWillStartRenderingFrame")
676
677
  }
677
678