@maplibre/maplibre-react-native 11.0.0-alpha.41 → 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 (138) 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/camera/MLRNCameraComponentView.mm +6 -0
  22. package/ios/components/map-view/MLRNMapView.m +4 -5
  23. package/lib/commonjs/components/annotations/callout/Callout.js +94 -0
  24. package/lib/commonjs/components/annotations/callout/Callout.js.map +1 -0
  25. package/lib/commonjs/components/annotations/callout/CalloutNativeComponent.ts +11 -0
  26. package/lib/commonjs/components/annotations/marker-view/MarkerView.js +70 -0
  27. package/lib/commonjs/components/annotations/marker-view/MarkerView.js.map +1 -0
  28. package/lib/commonjs/components/annotations/marker-view/MarkerViewNativeComponent.ts +30 -0
  29. package/lib/commonjs/components/annotations/point-annotation/PointAnnotation.js +88 -0
  30. package/lib/commonjs/components/annotations/point-annotation/PointAnnotation.js.map +1 -0
  31. package/lib/commonjs/components/annotations/point-annotation/PointAnnotationNativeComponent.ts +58 -0
  32. package/lib/commonjs/index.js +3 -3
  33. package/lib/commonjs/index.js.map +1 -1
  34. package/lib/commonjs/types/Anchor.js +68 -0
  35. package/lib/commonjs/types/Anchor.js.map +1 -0
  36. package/lib/commonjs/utils/animated/Animated.js +4 -0
  37. package/lib/commonjs/utils/animated/Animated.js.map +1 -1
  38. package/lib/module/components/annotations/callout/Callout.js +88 -0
  39. package/lib/module/components/annotations/callout/Callout.js.map +1 -0
  40. package/lib/module/components/annotations/callout/CalloutNativeComponent.ts +11 -0
  41. package/lib/module/components/annotations/marker-view/MarkerView.js +64 -0
  42. package/lib/module/components/annotations/marker-view/MarkerView.js.map +1 -0
  43. package/lib/module/components/annotations/marker-view/MarkerViewNativeComponent.ts +30 -0
  44. package/lib/module/components/annotations/point-annotation/PointAnnotation.js +83 -0
  45. package/lib/module/components/annotations/point-annotation/PointAnnotation.js.map +1 -0
  46. package/lib/module/components/annotations/point-annotation/PointAnnotationNativeComponent.ts +58 -0
  47. package/lib/module/index.js +3 -3
  48. package/lib/module/index.js.map +1 -1
  49. package/lib/module/types/Anchor.js +64 -0
  50. package/lib/module/types/Anchor.js.map +1 -0
  51. package/lib/module/utils/animated/Animated.js +4 -0
  52. package/lib/module/utils/animated/Animated.js.map +1 -1
  53. package/lib/typescript/{module/src/components/annotations → commonjs/src/components/annotations/callout}/Callout.d.ts +9 -9
  54. package/lib/typescript/commonjs/src/components/annotations/callout/Callout.d.ts.map +1 -0
  55. package/lib/typescript/commonjs/src/components/annotations/callout/CalloutNativeComponent.d.ts +6 -0
  56. package/lib/typescript/commonjs/src/components/annotations/callout/CalloutNativeComponent.d.ts.map +1 -0
  57. package/lib/typescript/commonjs/src/components/annotations/marker-view/MarkerView.d.ts +52 -0
  58. package/lib/typescript/commonjs/src/components/annotations/marker-view/MarkerView.d.ts.map +1 -0
  59. package/lib/typescript/commonjs/src/components/annotations/marker-view/MarkerViewNativeComponent.d.ts +21 -0
  60. package/lib/typescript/commonjs/src/components/annotations/marker-view/MarkerViewNativeComponent.d.ts.map +1 -0
  61. package/lib/typescript/commonjs/src/components/annotations/point-annotation/PointAnnotation.d.ts +95 -0
  62. package/lib/typescript/commonjs/src/components/annotations/point-annotation/PointAnnotation.d.ts.map +1 -0
  63. package/lib/typescript/commonjs/src/components/annotations/point-annotation/PointAnnotationNativeComponent.d.ts +43 -0
  64. package/lib/typescript/commonjs/src/components/annotations/point-annotation/PointAnnotationNativeComponent.d.ts.map +1 -0
  65. package/lib/typescript/commonjs/src/index.d.ts +4 -4
  66. package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
  67. package/lib/typescript/commonjs/src/types/Anchor.d.ts +17 -0
  68. package/lib/typescript/commonjs/src/types/Anchor.d.ts.map +1 -0
  69. package/lib/typescript/commonjs/src/utils/animated/Animated.d.ts +1 -0
  70. package/lib/typescript/commonjs/src/utils/animated/Animated.d.ts.map +1 -1
  71. package/lib/typescript/{commonjs/src/components/annotations → module/src/components/annotations/callout}/Callout.d.ts +9 -9
  72. package/lib/typescript/module/src/components/annotations/callout/Callout.d.ts.map +1 -0
  73. package/lib/typescript/module/src/components/annotations/callout/CalloutNativeComponent.d.ts +6 -0
  74. package/lib/typescript/module/src/components/annotations/callout/CalloutNativeComponent.d.ts.map +1 -0
  75. package/lib/typescript/module/src/components/annotations/marker-view/MarkerView.d.ts +52 -0
  76. package/lib/typescript/module/src/components/annotations/marker-view/MarkerView.d.ts.map +1 -0
  77. package/lib/typescript/module/src/components/annotations/marker-view/MarkerViewNativeComponent.d.ts +21 -0
  78. package/lib/typescript/module/src/components/annotations/marker-view/MarkerViewNativeComponent.d.ts.map +1 -0
  79. package/lib/typescript/module/src/components/annotations/point-annotation/PointAnnotation.d.ts +95 -0
  80. package/lib/typescript/module/src/components/annotations/point-annotation/PointAnnotation.d.ts.map +1 -0
  81. package/lib/typescript/module/src/components/annotations/point-annotation/PointAnnotationNativeComponent.d.ts +43 -0
  82. package/lib/typescript/module/src/components/annotations/point-annotation/PointAnnotationNativeComponent.d.ts.map +1 -0
  83. package/lib/typescript/module/src/index.d.ts +4 -4
  84. package/lib/typescript/module/src/index.d.ts.map +1 -1
  85. package/lib/typescript/module/src/types/Anchor.d.ts +17 -0
  86. package/lib/typescript/module/src/types/Anchor.d.ts.map +1 -0
  87. package/lib/typescript/module/src/utils/animated/Animated.d.ts +1 -0
  88. package/lib/typescript/module/src/utils/animated/Animated.d.ts.map +1 -1
  89. package/package.json +3 -1
  90. package/src/components/annotations/callout/Callout.tsx +145 -0
  91. package/src/components/annotations/callout/CalloutNativeComponent.ts +11 -0
  92. package/src/components/annotations/marker-view/MarkerView.tsx +124 -0
  93. package/src/components/annotations/marker-view/MarkerViewNativeComponent.ts +30 -0
  94. package/src/components/annotations/point-annotation/PointAnnotation.tsx +219 -0
  95. package/src/components/annotations/point-annotation/PointAnnotationNativeComponent.ts +58 -0
  96. package/src/index.ts +15 -4
  97. package/src/types/Anchor.ts +44 -0
  98. package/src/utils/animated/Animated.tsx +6 -0
  99. package/android/src/main/java/org/maplibre/reactnative/components/annotations/MLRNCallout.java +0 -11
  100. package/android/src/main/java/org/maplibre/reactnative/components/annotations/MLRNCalloutManager.java +0 -18
  101. package/android/src/main/java/org/maplibre/reactnative/components/annotations/MLRNMarkerView.java +0 -112
  102. package/android/src/main/java/org/maplibre/reactnative/components/annotations/MLRNMarkerViewManager.java +0 -45
  103. package/android/src/main/java/org/maplibre/reactnative/components/annotations/MLRNPointAnnotation.java +0 -361
  104. package/android/src/main/java/org/maplibre/reactnative/components/annotations/MLRNPointAnnotationManager.java +0 -84
  105. package/android/src/main/java/org/maplibre/reactnative/components/annotations/MarkerView.java +0 -23
  106. package/android/src/main/java/org/maplibre/reactnative/components/annotations/MarkerViewManager.java +0 -69
  107. package/ios/components/annotations/MLRNCalloutManager.h +0 -5
  108. package/ios/components/annotations/MLRNCalloutManager.m +0 -12
  109. package/ios/components/annotations/MLRNPointAnnotation.h +0 -33
  110. package/ios/components/annotations/MLRNPointAnnotationManager.h +0 -5
  111. package/ios/components/annotations/MLRNPointAnnotationManager.m +0 -27
  112. package/lib/commonjs/components/annotations/Callout.js +0 -101
  113. package/lib/commonjs/components/annotations/Callout.js.map +0 -1
  114. package/lib/commonjs/components/annotations/MarkerView.js +0 -60
  115. package/lib/commonjs/components/annotations/MarkerView.js.map +0 -1
  116. package/lib/commonjs/components/annotations/PointAnnotation.js +0 -114
  117. package/lib/commonjs/components/annotations/PointAnnotation.js.map +0 -1
  118. package/lib/module/components/annotations/Callout.js +0 -96
  119. package/lib/module/components/annotations/Callout.js.map +0 -1
  120. package/lib/module/components/annotations/MarkerView.js +0 -55
  121. package/lib/module/components/annotations/MarkerView.js.map +0 -1
  122. package/lib/module/components/annotations/PointAnnotation.js +0 -110
  123. package/lib/module/components/annotations/PointAnnotation.js.map +0 -1
  124. package/lib/typescript/commonjs/src/components/annotations/Callout.d.ts.map +0 -1
  125. package/lib/typescript/commonjs/src/components/annotations/MarkerView.d.ts +0 -44
  126. package/lib/typescript/commonjs/src/components/annotations/MarkerView.d.ts.map +0 -1
  127. package/lib/typescript/commonjs/src/components/annotations/PointAnnotation.d.ts +0 -90
  128. package/lib/typescript/commonjs/src/components/annotations/PointAnnotation.d.ts.map +0 -1
  129. package/lib/typescript/module/src/components/annotations/Callout.d.ts.map +0 -1
  130. package/lib/typescript/module/src/components/annotations/MarkerView.d.ts +0 -44
  131. package/lib/typescript/module/src/components/annotations/MarkerView.d.ts.map +0 -1
  132. package/lib/typescript/module/src/components/annotations/PointAnnotation.d.ts +0 -90
  133. package/lib/typescript/module/src/components/annotations/PointAnnotation.d.ts.map +0 -1
  134. package/src/components/annotations/Callout.tsx +0 -139
  135. package/src/components/annotations/MarkerView.tsx +0 -86
  136. package/src/components/annotations/PointAnnotation.tsx +0 -240
  137. /package/ios/components/annotations/{MLRNCallout.h → callout/MLRNCallout.h} +0 -0
  138. /package/ios/components/annotations/{MLRNCallout.m → callout/MLRNCallout.m} +0 -0
@@ -96,9 +96,7 @@ dependencies {
96
96
  implementation("org.maplibre.gl:android-plugin-annotation-v9:${getConfigurableExtOrDefault('pluginVersion')}") {
97
97
  exclude(group: "org.maplibre.gl", module: "android-sdk")
98
98
  }
99
- implementation("org.maplibre.gl:android-plugin-markerview-v9:${getConfigurableExtOrDefault('pluginVersion')}") {
100
- exclude(group: "org.maplibre.gl", module: "android-sdk")
101
- }
99
+ // Note: markerview plugin removed - using native implementation instead
102
100
 
103
101
  // Dependencies
104
102
  implementation "org.maplibre.gl:android-sdk-turf:${getConfigurableExtOrDefault('turfVersion')}"
@@ -6,9 +6,9 @@ import com.facebook.react.bridge.ReactApplicationContext
6
6
  import com.facebook.react.module.model.ReactModuleInfo
7
7
  import com.facebook.react.module.model.ReactModuleInfoProvider
8
8
  import com.facebook.react.uimanager.ViewManager
9
- import org.maplibre.reactnative.components.annotations.MLRNCalloutManager
10
- import org.maplibre.reactnative.components.annotations.MLRNMarkerViewManager
11
- import org.maplibre.reactnative.components.annotations.MLRNPointAnnotationManager
9
+ import org.maplibre.reactnative.components.annotations.callout.MLRNCalloutManager
10
+ import org.maplibre.reactnative.components.annotations.markerview.MLRNMarkerViewManager
11
+ import org.maplibre.reactnative.components.annotations.pointannotation.MLRNPointAnnotationManager
12
12
  import org.maplibre.reactnative.components.camera.MLRNCameraManager
13
13
  import org.maplibre.reactnative.components.camera.MLRNCameraModule
14
14
  import org.maplibre.reactnative.components.images.MLRNImagesManager
@@ -0,0 +1,7 @@
1
+ package org.maplibre.reactnative.components.annotations.callout
2
+
3
+ import android.content.Context
4
+ import com.facebook.react.views.view.ReactViewGroup
5
+
6
+ class MLRNCallout(context: Context) : ReactViewGroup(context) {
7
+ }
@@ -0,0 +1,29 @@
1
+ package org.maplibre.reactnative.components.annotations.callout
2
+
3
+ import com.facebook.react.module.annotations.ReactModule
4
+ import com.facebook.react.uimanager.ThemedReactContext
5
+ import com.facebook.react.uimanager.ViewGroupManager
6
+ import com.facebook.react.uimanager.ViewManagerDelegate
7
+ import com.facebook.react.viewmanagers.MLRNCalloutManagerDelegate
8
+ import com.facebook.react.viewmanagers.MLRNCalloutManagerInterface
9
+
10
+ @ReactModule(name = MLRNCalloutManager.REACT_CLASS)
11
+ class MLRNCalloutManager :
12
+ ViewGroupManager<MLRNCallout>(),
13
+ MLRNCalloutManagerInterface<MLRNCallout> {
14
+
15
+ private val delegate: MLRNCalloutManagerDelegate<MLRNCallout, MLRNCalloutManager> =
16
+ MLRNCalloutManagerDelegate(this)
17
+
18
+ override fun getDelegate(): ViewManagerDelegate<MLRNCallout> = delegate
19
+
20
+ companion object {
21
+ const val REACT_CLASS: String = "MLRNCallout"
22
+ }
23
+
24
+ override fun getName(): String = REACT_CLASS
25
+
26
+ override fun createViewInstance(reactContext: ThemedReactContext): MLRNCallout {
27
+ return MLRNCallout(reactContext)
28
+ }
29
+ }
@@ -0,0 +1,220 @@
1
+ package org.maplibre.reactnative.components.annotations.markerview
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.content.Context
5
+ import android.view.View
6
+ import android.view.ViewGroup
7
+ import android.widget.FrameLayout
8
+ import com.facebook.react.uimanager.ViewGroupManager
9
+ import org.maplibre.geojson.Point
10
+ import org.maplibre.reactnative.components.AbstractMapFeature
11
+ import org.maplibre.reactnative.components.mapview.MLRNMapView
12
+ import org.maplibre.reactnative.utils.GeoJSONUtils
13
+
14
+ @SuppressLint("ViewConstructor")
15
+ class MLRNMarkerView(context: Context) : AbstractMapFeature(context), View.OnLayoutChangeListener {
16
+ private var mMapView: MLRNMapView? = null
17
+ private var mChildView: View? = null
18
+ private var mWrapperView: MLRNMarkerViewContent? = null
19
+ private var mMarkerViewManager: MarkerViewManager? = null
20
+ private var mMarkerInfo: MarkerViewManager.MarkerInfo? = null
21
+ private var mCoordinate: Point? = null
22
+ private var mAnchor: FloatArray? = null
23
+ private var mOffset: FloatArray? = null
24
+ private var mAddedToMap = false
25
+ private var mLastWidth = 0
26
+ private var mLastHeight = 0
27
+ private var mLastZIndex: Int? = null
28
+
29
+ private fun ViewGroup.disableClipping() {
30
+ clipChildren = false
31
+ clipToPadding = false
32
+ clipToOutline = false
33
+ }
34
+
35
+ private fun disableClippingRecursively(view: View) {
36
+ if (view is ViewGroup) {
37
+ view.disableClipping()
38
+ view.setOnHierarchyChangeListener(object : ViewGroup.OnHierarchyChangeListener {
39
+ override fun onChildViewAdded(parent: View?, child: View?) {
40
+ child?.let { disableClippingRecursively(it) }
41
+ }
42
+ override fun onChildViewRemoved(parent: View?, child: View?) {}
43
+ })
44
+ for (i in 0 until view.childCount) {
45
+ disableClippingRecursively(view.getChildAt(i))
46
+ }
47
+ }
48
+ }
49
+
50
+ override fun addView(childView: View, childPosition: Int) {
51
+ if (childPosition != 0) return
52
+
53
+ mChildView = childView
54
+ childView.addOnLayoutChangeListener(this)
55
+ disableClippingRecursively(childView)
56
+
57
+ val offscreenContainer = mMapView?.offscreenAnnotationViewContainer()
58
+ offscreenContainer?.disableClipping()
59
+ offscreenContainer?.addView(childView)
60
+ }
61
+
62
+ override fun removeView(view: View?) {
63
+ if (view == mChildView) {
64
+ removeChildView()
65
+ }
66
+ }
67
+
68
+ override fun removeViewAt(index: Int) {
69
+ if (index == 0 && mChildView != null) {
70
+ removeChildView()
71
+ }
72
+ }
73
+
74
+ private fun removeChildView() {
75
+ mChildView?.removeOnLayoutChangeListener(this)
76
+ (mChildView?.parent as? android.view.ViewGroup)?.removeView(mChildView)
77
+ mChildView = null
78
+ }
79
+
80
+ override fun getChildCount(): Int {
81
+ return if (mChildView != null) 1 else 0
82
+ }
83
+
84
+ override fun getChildAt(index: Int): View? {
85
+ return if (index == 0) mChildView else null
86
+ }
87
+
88
+ fun setLngLat(lngLat: DoubleArray?) {
89
+ if (lngLat == null || lngLat.size < 2) return
90
+ val point = Point.fromLngLat(lngLat[0], lngLat[1])
91
+ mCoordinate = point
92
+ val latLng = GeoJSONUtils.toLatLng(point)
93
+ if (latLng != null && mMarkerInfo != null && mMarkerViewManager != null) {
94
+ mMarkerViewManager!!.updateMarkerCoordinate(mMarkerInfo!!, latLng)
95
+ }
96
+ }
97
+
98
+ fun setAnchor(x: Float, y: Float) {
99
+ mAnchor = floatArrayOf(x, y)
100
+ if (mMarkerInfo != null && mMarkerViewManager != null) {
101
+ mMarkerViewManager!!.updateMarkerAnchor(mMarkerInfo!!, x, y)
102
+ }
103
+ }
104
+
105
+ fun setOffset(x: Float, y: Float) {
106
+ mOffset = floatArrayOf(x, y)
107
+ val scale = resources.displayMetrics.density
108
+ val pixelOffsetX = x * scale
109
+ val pixelOffsetY = y * scale
110
+ if (mMarkerInfo != null && mMarkerViewManager != null) {
111
+ mMarkerViewManager!!.updateMarkerOffset(mMarkerInfo!!, pixelOffsetX, pixelOffsetY)
112
+ }
113
+ }
114
+
115
+ fun updateZIndex(zIndex: Float) {
116
+ mWrapperView?.translationZ = zIndex
117
+ }
118
+
119
+ override fun addToMap(mapView: MLRNMapView) {
120
+ mMapView = mapView
121
+ if (mChildView != null && !mChildView!!.isAttachedToWindow) {
122
+ val offscreenContainer = mMapView?.offscreenAnnotationViewContainer()
123
+ offscreenContainer?.disableClipping()
124
+ offscreenContainer?.addView(mChildView)
125
+ }
126
+ tryAddToMarkerViewManager()
127
+ }
128
+
129
+ private fun tryAddToMarkerViewManager() {
130
+ if (mAddedToMap || mMapView == null || mChildView == null) return
131
+ if (mChildView!!.width == 0 || mChildView!!.height == 0) return
132
+
133
+ mAddedToMap = true
134
+
135
+ mMapView?.getMapAsync { mapLibreMap ->
136
+ val latLng = GeoJSONUtils.toLatLng(mCoordinate)
137
+ mMarkerViewManager = mMapView?.getMarkerViewManager(mapLibreMap)
138
+
139
+ if (latLng != null && mChildView != null && mMarkerViewManager != null) {
140
+ mMapView?.offscreenAnnotationViewContainer()?.removeView(mChildView)
141
+ disableClippingRecursively(mChildView!!)
142
+
143
+ mWrapperView = MLRNMarkerViewContent(context).apply {
144
+ layoutParams = FrameLayout.LayoutParams(
145
+ FrameLayout.LayoutParams.WRAP_CONTENT,
146
+ FrameLayout.LayoutParams.WRAP_CONTENT
147
+ )
148
+ addView(mChildView)
149
+ }
150
+ mWrapperView!!.setLayerType(View.LAYER_TYPE_HARDWARE, null)
151
+
152
+ mLastZIndex = ViewGroupManager.getViewZIndex(this@MLRNMarkerView)
153
+ if (mLastZIndex != null) {
154
+ mWrapperView!!.translationZ = mLastZIndex!!.toFloat()
155
+ }
156
+
157
+ val scale = resources.displayMetrics.density
158
+ val pixelOffsetX = (mOffset?.get(0) ?: 0f) * scale
159
+ val pixelOffsetY = (mOffset?.get(1) ?: 0f) * scale
160
+
161
+ mMarkerInfo = mMarkerViewManager!!.addMarker(
162
+ view = mWrapperView!!,
163
+ latLng = latLng,
164
+ anchorX = mAnchor?.get(0) ?: 0f,
165
+ anchorY = mAnchor?.get(1) ?: 0f,
166
+ offsetX = pixelOffsetX,
167
+ offsetY = pixelOffsetY
168
+ )
169
+ }
170
+ }
171
+ }
172
+
173
+ override fun removeFromMap(mapView: MLRNMapView) {
174
+ if (mMarkerInfo != null && mMarkerViewManager != null) {
175
+ mMarkerViewManager!!.removeMarker(mMarkerInfo!!)
176
+ mMarkerInfo = null
177
+ mMarkerViewManager = null
178
+ }
179
+ mChildView?.removeOnLayoutChangeListener(this)
180
+ mWrapperView?.removeAllViews()
181
+ mWrapperView = null
182
+ if (mChildView != null && !mAddedToMap) {
183
+ mMapView?.offscreenAnnotationViewContainer()?.removeView(mChildView)
184
+ }
185
+ mAddedToMap = false
186
+ }
187
+
188
+ override fun onLayoutChange(
189
+ v: View, left: Int, top: Int, right: Int, bottom: Int,
190
+ oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int
191
+ ) {
192
+ if (left == 0 && top == 0 && right == 0 && bottom == 0) return
193
+
194
+ val width = right - left
195
+ val height = bottom - top
196
+
197
+ if (!mAddedToMap) {
198
+ tryAddToMarkerViewManager()
199
+ return
200
+ }
201
+
202
+ val currentZIndex = ViewGroupManager.getViewZIndex(this@MLRNMarkerView)
203
+ if (currentZIndex != mLastZIndex) {
204
+ mLastZIndex = currentZIndex
205
+ if (currentZIndex != null) {
206
+ mWrapperView?.translationZ = currentZIndex.toFloat()
207
+ }
208
+ }
209
+
210
+ if (width == mLastWidth && height == mLastHeight) return
211
+
212
+ mLastWidth = width
213
+ mLastHeight = height
214
+ mChildView?.layoutParams?.let { params ->
215
+ params.width = width
216
+ params.height = height
217
+ }
218
+ mMarkerViewManager?.updateMarkers()
219
+ }
220
+ }
@@ -0,0 +1,50 @@
1
+ package org.maplibre.reactnative.components.annotations.markerview
2
+
3
+ import android.content.Context
4
+ import android.view.MotionEvent
5
+ import android.view.ViewGroup
6
+ import com.facebook.react.views.view.ReactViewGroup
7
+
8
+ /**
9
+ * Custom ReactViewGroup that allows content to render outside its bounds (#642).
10
+ * This is used as a wrapper for MarkerView content to prevent clipping.
11
+ *
12
+ * Based on rnmapbox/maps implementation:
13
+ * https://github.com/rnmapbox/maps/blob/main/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewContent.kt
14
+ */
15
+ class MLRNMarkerViewContent(context: Context) : ReactViewGroup(context) {
16
+
17
+ init {
18
+ allowRenderingOutside()
19
+ }
20
+
21
+ override fun onAttachedToWindow() {
22
+ super.onAttachedToWindow()
23
+ configureParentClipping()
24
+ }
25
+
26
+ private fun configureParentClipping() {
27
+ val parent = parent
28
+ if (parent is ViewGroup) {
29
+ parent.allowRenderingOutside()
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Request that the parent (MapView) not intercept touch events when touching marker content.
35
+ * This allows TouchableOpacity, Pressable, etc. to receive touch events properly (#557, #1018).
36
+ */
37
+ override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
38
+ // Request that parent (MapView) doesn't intercept this touch sequence
39
+ parent?.requestDisallowInterceptTouchEvent(true)
40
+ return super.onInterceptTouchEvent(event)
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Extension function to disable all forms of clipping on a ViewGroup
46
+ */
47
+ private fun ViewGroup.allowRenderingOutside() {
48
+ clipChildren = false
49
+ clipToPadding = false
50
+ }
@@ -0,0 +1,81 @@
1
+ package org.maplibre.reactnative.components.annotations.markerview
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.MLRNMarkerViewManagerDelegate
15
+ import com.facebook.react.viewmanagers.MLRNMarkerViewManagerInterface
16
+
17
+ @ReactModule(name = MLRNMarkerViewManager.REACT_CLASS)
18
+ class MLRNMarkerViewManager(private val reactApplicationContext: ReactApplicationContext) :
19
+ ViewGroupManager<MLRNMarkerView>(),
20
+ MLRNMarkerViewManagerInterface<MLRNMarkerView> {
21
+
22
+ private val delegate: MLRNMarkerViewManagerDelegate<MLRNMarkerView, MLRNMarkerViewManager> =
23
+ MLRNMarkerViewManagerDelegate(this)
24
+
25
+ override fun getDelegate(): ViewManagerDelegate<MLRNMarkerView> = delegate
26
+
27
+ companion object {
28
+ const val REACT_CLASS: String = "MLRNMarkerView"
29
+ }
30
+
31
+ override fun getName(): String = REACT_CLASS
32
+
33
+ override fun createViewInstance(reactContext: ThemedReactContext): MLRNMarkerView {
34
+ return MLRNMarkerView(reactContext)
35
+ }
36
+
37
+ override fun addView(parent: MLRNMarkerView, child: View, index: Int) {
38
+ parent.addView(child, index)
39
+ }
40
+
41
+ override fun removeViewAt(parent: MLRNMarkerView, index: Int) {
42
+ parent.removeViewAt(index)
43
+ }
44
+
45
+ override fun getChildCount(parent: MLRNMarkerView): Int {
46
+ return parent.childCount
47
+ }
48
+
49
+ override fun getChildAt(parent: MLRNMarkerView, index: Int): View? {
50
+ return parent.getChildAt(index)
51
+ }
52
+
53
+ @ReactProp(name = "lngLat")
54
+ override fun setLngLat(markerView: MLRNMarkerView, lngLat: Dynamic) {
55
+ if (lngLat.type == ReadableType.Array) {
56
+ val arr = lngLat.asArray()
57
+ if (arr != null && arr.size() >= 2) {
58
+ markerView.setLngLat(doubleArrayOf(arr.getDouble(0), arr.getDouble(1)))
59
+ }
60
+ }
61
+ }
62
+
63
+ @ReactProp(name = "anchor")
64
+ override fun setAnchor(markerView: MLRNMarkerView, map: ReadableMap?) {
65
+ if (map != null) {
66
+ markerView.setAnchor(map.getDouble("x").toFloat(), map.getDouble("y").toFloat())
67
+ }
68
+ }
69
+
70
+ @ReactProp(name = "offset")
71
+ override fun setOffset(markerView: MLRNMarkerView, map: ReadableMap?) {
72
+ if (map != null) {
73
+ markerView.setOffset(map.getDouble("x").toFloat(), map.getDouble("y").toFloat())
74
+ }
75
+ }
76
+
77
+ override fun setZIndex(view: MLRNMarkerView, zIndex: Float) {
78
+ super.setZIndex(view, zIndex)
79
+ view.updateZIndex(zIndex)
80
+ }
81
+ }
@@ -0,0 +1,127 @@
1
+ package org.maplibre.reactnative.components.annotations.markerview
2
+
3
+ import android.graphics.PointF
4
+ import android.view.View
5
+ import android.view.ViewGroup
6
+ import android.widget.FrameLayout
7
+ import org.maplibre.android.geometry.LatLng
8
+ import org.maplibre.android.maps.MapLibreMap
9
+ import org.maplibre.android.maps.MapView
10
+
11
+ class MarkerViewManager(
12
+ private val mapView: MapView,
13
+ private val map: MapLibreMap
14
+ ) {
15
+ data class MarkerInfo(
16
+ val view: View,
17
+ var latLng: LatLng,
18
+ var anchorX: Float = 0f,
19
+ var anchorY: Float = 0f,
20
+ var offsetX: Float = 0f,
21
+ var offsetY: Float = 0f
22
+ )
23
+
24
+ private val markers = mutableListOf<MarkerInfo>()
25
+ private var isDestroyed = false
26
+
27
+ fun addMarker(
28
+ view: View,
29
+ latLng: LatLng,
30
+ anchorX: Float = 0f,
31
+ anchorY: Float = 0f,
32
+ offsetX: Float = 0f,
33
+ offsetY: Float = 0f
34
+ ): MarkerInfo {
35
+ val markerInfo = MarkerInfo(view, latLng, anchorX, anchorY, offsetX, offsetY)
36
+ markers.add(markerInfo)
37
+
38
+ if (view is ViewGroup) {
39
+ view.clipChildren = false
40
+ view.clipToPadding = false
41
+ view.clipToOutline = false
42
+ }
43
+
44
+ if (view.parent == null) {
45
+ mapView.clipChildren = false
46
+ mapView.clipToPadding = false
47
+ mapView.clipToOutline = false
48
+ mapView.addView(view)
49
+ }
50
+
51
+ updateMarkerPosition(markerInfo)
52
+
53
+ return markerInfo
54
+ }
55
+
56
+ fun removeMarker(markerInfo: MarkerInfo) {
57
+ markers.remove(markerInfo)
58
+ mapView.removeView(markerInfo.view)
59
+ }
60
+
61
+ fun removeMarkerByView(view: View) {
62
+ markers.find { it.view == view }?.let { removeMarker(it) }
63
+ }
64
+
65
+ fun updateMarkers() {
66
+ if (isDestroyed) return
67
+
68
+ for (marker in markers) {
69
+ updateMarkerPosition(marker)
70
+ }
71
+ }
72
+
73
+ private fun updateMarkerPosition(marker: MarkerInfo) {
74
+ val view = marker.view
75
+ val screenPos: PointF = map.projection.toScreenLocation(marker.latLng)
76
+ val viewWidth = if (view.width > 0) view.width.toFloat() else view.measuredWidth.toFloat()
77
+ val viewHeight = if (view.height > 0) view.height.toFloat() else view.measuredHeight.toFloat()
78
+ val anchorOffsetX = viewWidth * marker.anchorX
79
+ val anchorOffsetY = viewHeight * marker.anchorY
80
+ view.x = screenPos.x - anchorOffsetX + marker.offsetX
81
+ view.y = screenPos.y - anchorOffsetY + marker.offsetY
82
+ }
83
+
84
+ fun findMarkerByView(view: View): MarkerInfo? {
85
+ return markers.find { it.view == view }
86
+ }
87
+
88
+ fun updateMarkerCoordinate(markerInfo: MarkerInfo, latLng: LatLng) {
89
+ markerInfo.latLng = latLng
90
+ updateMarkerPosition(markerInfo)
91
+ }
92
+
93
+ fun updateMarkerAnchor(markerInfo: MarkerInfo, anchorX: Float, anchorY: Float) {
94
+ markerInfo.anchorX = anchorX
95
+ markerInfo.anchorY = anchorY
96
+ updateMarkerPosition(markerInfo)
97
+ }
98
+
99
+ fun updateMarkerOffset(markerInfo: MarkerInfo, offsetX: Float, offsetY: Float) {
100
+ markerInfo.offsetX = offsetX
101
+ markerInfo.offsetY = offsetY
102
+ updateMarkerPosition(markerInfo)
103
+ }
104
+
105
+ fun removeViews() {
106
+ for (marker in markers) {
107
+ mapView.removeView(marker.view)
108
+ }
109
+ }
110
+
111
+ fun restoreViews() {
112
+ for (marker in markers) {
113
+ if (marker.view.parent == null) {
114
+ mapView.addView(marker.view)
115
+ }
116
+ }
117
+ updateMarkers()
118
+ }
119
+
120
+ fun onDestroy() {
121
+ isDestroyed = true
122
+ for (marker in markers) {
123
+ mapView.removeView(marker.view)
124
+ }
125
+ markers.clear()
126
+ }
127
+ }