expo-gaode-map 1.1.7 → 2.0.0-alpha.1

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 (121) hide show
  1. package/README.en.md +32 -46
  2. package/README.md +51 -71
  3. package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapView.kt +37 -237
  4. package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapViewModule.kt +1 -49
  5. package/android/src/main/java/expo/modules/gaodemap/managers/CameraManager.kt +30 -7
  6. package/android/src/main/java/expo/modules/gaodemap/managers/UIManager.kt +1 -0
  7. package/android/src/main/java/expo/modules/gaodemap/modules/LocationManager.kt +10 -1
  8. package/android/src/main/java/expo/modules/gaodemap/overlays/CircleView.kt +38 -14
  9. package/android/src/main/java/expo/modules/gaodemap/overlays/CircleViewModule.kt +3 -3
  10. package/android/src/main/java/expo/modules/gaodemap/overlays/ClusterView.kt +8 -1
  11. package/android/src/main/java/expo/modules/gaodemap/overlays/HeatMapView.kt +4 -1
  12. package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerView.kt +322 -93
  13. package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerViewModule.kt +11 -3
  14. package/android/src/main/java/expo/modules/gaodemap/overlays/MultiPointView.kt +4 -1
  15. package/android/src/main/java/expo/modules/gaodemap/overlays/PolygonView.kt +25 -11
  16. package/android/src/main/java/expo/modules/gaodemap/overlays/PolygonViewModule.kt +3 -3
  17. package/android/src/main/java/expo/modules/gaodemap/overlays/PolylineView.kt +20 -10
  18. package/android/src/main/java/expo/modules/gaodemap/overlays/PolylineViewModule.kt +6 -2
  19. package/build/ExpoGaodeMap.types.d.ts +27 -6
  20. package/build/ExpoGaodeMap.types.d.ts.map +1 -1
  21. package/build/ExpoGaodeMap.types.js +3 -0
  22. package/build/ExpoGaodeMap.types.js.map +1 -1
  23. package/build/ExpoGaodeMapModule.d.ts +157 -10
  24. package/build/ExpoGaodeMapModule.d.ts.map +1 -1
  25. package/build/ExpoGaodeMapModule.js +4 -0
  26. package/build/ExpoGaodeMapModule.js.map +1 -1
  27. package/build/ExpoGaodeMapView.d.ts +1 -17
  28. package/build/ExpoGaodeMapView.d.ts.map +1 -1
  29. package/build/ExpoGaodeMapView.js +4 -209
  30. package/build/ExpoGaodeMapView.js.map +1 -1
  31. package/build/components/overlays/Circle.d.ts +10 -1
  32. package/build/components/overlays/Circle.d.ts.map +1 -1
  33. package/build/components/overlays/Circle.js +11 -86
  34. package/build/components/overlays/Circle.js.map +1 -1
  35. package/build/components/overlays/Cluster.d.ts.map +1 -1
  36. package/build/components/overlays/Cluster.js.map +1 -1
  37. package/build/components/overlays/Marker.d.ts +13 -1
  38. package/build/components/overlays/Marker.d.ts.map +1 -1
  39. package/build/components/overlays/Marker.js +51 -115
  40. package/build/components/overlays/Marker.js.map +1 -1
  41. package/build/components/overlays/Polygon.d.ts +7 -15
  42. package/build/components/overlays/Polygon.d.ts.map +1 -1
  43. package/build/components/overlays/Polygon.js +10 -80
  44. package/build/components/overlays/Polygon.js.map +1 -1
  45. package/build/components/overlays/Polyline.d.ts +7 -14
  46. package/build/components/overlays/Polyline.d.ts.map +1 -1
  47. package/build/components/overlays/Polyline.js +9 -66
  48. package/build/components/overlays/Polyline.js.map +1 -1
  49. package/build/index.d.ts +1 -4
  50. package/build/index.d.ts.map +1 -1
  51. package/build/index.js +2 -10
  52. package/build/index.js.map +1 -1
  53. package/build/types/index.d.ts +1 -1
  54. package/build/types/index.d.ts.map +1 -1
  55. package/build/types/index.js.map +1 -1
  56. package/build/types/map-view.types.d.ts +0 -76
  57. package/build/types/map-view.types.d.ts.map +1 -1
  58. package/build/types/map-view.types.js.map +1 -1
  59. package/build/types/overlays.types.d.ts +11 -16
  60. package/build/types/overlays.types.d.ts.map +1 -1
  61. package/build/types/overlays.types.js.map +1 -1
  62. package/docs/API.en.md +1 -21
  63. package/docs/API.md +84 -56
  64. package/docs/EXAMPLES.en.md +0 -48
  65. package/docs/EXAMPLES.md +49 -102
  66. package/docs/INITIALIZATION.md +59 -71
  67. package/docs/MIGRATION.md +423 -0
  68. package/ios/ExpoGaodeMapView.swift +317 -258
  69. package/ios/ExpoGaodeMapViewModule.swift +3 -50
  70. package/ios/managers/CameraManager.swift +23 -2
  71. package/ios/managers/UIManager.swift +10 -5
  72. package/ios/modules/LocationManager.swift +10 -0
  73. package/ios/overlays/CircleView.swift +98 -19
  74. package/ios/overlays/CircleViewModule.swift +21 -0
  75. package/ios/overlays/ClusterView.swift +33 -4
  76. package/ios/overlays/HeatMapView.swift +16 -4
  77. package/ios/overlays/MarkerView.swift +235 -146
  78. package/ios/overlays/MarkerViewModule.swift +7 -3
  79. package/ios/overlays/MultiPointView.swift +30 -1
  80. package/ios/overlays/PolygonView.swift +63 -12
  81. package/ios/overlays/PolygonViewModule.swift +17 -0
  82. package/ios/overlays/PolylineView.swift +95 -25
  83. package/ios/overlays/PolylineViewModule.swift +17 -8
  84. package/ios/utils/PermissionManager.swift +9 -14
  85. package/package.json +4 -3
  86. package/src/ExpoGaodeMap.types.ts +28 -3
  87. package/src/ExpoGaodeMapModule.ts +201 -12
  88. package/src/ExpoGaodeMapView.tsx +11 -225
  89. package/src/components/overlays/Circle.tsx +12 -104
  90. package/src/components/overlays/Cluster.tsx +0 -1
  91. package/src/components/overlays/Marker.tsx +63 -138
  92. package/src/components/overlays/Polygon.tsx +12 -92
  93. package/src/components/overlays/Polyline.tsx +11 -77
  94. package/src/index.ts +4 -29
  95. package/src/types/index.ts +1 -1
  96. package/src/types/map-view.types.ts +1 -69
  97. package/src/types/overlays.types.ts +11 -16
  98. package/android/src/main/java/expo/modules/gaodemap/managers/OverlayManager.kt +0 -574
  99. package/build/modules/AMapLocation.d.ts +0 -78
  100. package/build/modules/AMapLocation.d.ts.map +0 -1
  101. package/build/modules/AMapLocation.js +0 -132
  102. package/build/modules/AMapLocation.js.map +0 -1
  103. package/build/modules/AMapPermissions.d.ts +0 -29
  104. package/build/modules/AMapPermissions.d.ts.map +0 -1
  105. package/build/modules/AMapPermissions.js +0 -23
  106. package/build/modules/AMapPermissions.js.map +0 -1
  107. package/build/modules/AMapSDK.d.ts +0 -22
  108. package/build/modules/AMapSDK.d.ts.map +0 -1
  109. package/build/modules/AMapSDK.js +0 -25
  110. package/build/modules/AMapSDK.js.map +0 -1
  111. package/build/modules/AMapView.d.ts +0 -44
  112. package/build/modules/AMapView.d.ts.map +0 -1
  113. package/build/modules/AMapView.js +0 -65
  114. package/build/modules/AMapView.js.map +0 -1
  115. package/ios/managers/OverlayManager.swift +0 -522
  116. package/src/modules/AMapLocation.ts +0 -165
  117. package/src/modules/AMapPermissions.ts +0 -41
  118. package/src/modules/AMapSDK.ts +0 -31
  119. package/src/modules/AMapView.ts +0 -72
  120. package/test/ClockMapView.tsx +0 -532
  121. package/test/useMap.ts +0 -1360
@@ -49,10 +49,6 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
49
49
  var showsBuildings: Bool = false
50
50
  /// 是否显示室内地图
51
51
  var showsIndoorMap: Bool = false
52
- /// 最大缩放级别
53
- var maxZoomLevel: CGFloat = 20
54
- /// 最小缩放级别
55
- var minZoomLevel: CGFloat = 3
56
52
 
57
53
  // MARK: - 事件派发器
58
54
 
@@ -60,30 +56,25 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
60
56
  let onMapLongPress = EventDispatcher()
61
57
  let onLoad = EventDispatcher()
62
58
  let onLocation = EventDispatcher()
63
- let onMarkerPress = EventDispatcher()
64
- let onMarkerDragStart = EventDispatcher()
65
- let onMarkerDrag = EventDispatcher()
66
- let onMarkerDragEnd = EventDispatcher()
67
- let onCirclePress = EventDispatcher()
68
- let onPolygonPress = EventDispatcher()
69
- let onPolylinePress = EventDispatcher()
70
59
 
71
60
  // MARK: - 私有属性
72
61
 
73
62
  /// 高德地图视图实例
74
- private var mapView: MAMapView!
63
+ var mapView: MAMapView!
75
64
  /// 相机管理器
76
65
  private var cameraManager: CameraManager!
77
66
  /// UI 管理器
78
67
  private var uiManager: UIManager!
79
- /// 覆盖物管理器
80
- private var overlayManager: OverlayManager!
81
68
  /// 地图是否已加载完成
82
69
  private var isMapLoaded = false
83
70
  /// 是否正在处理 annotation 选择事件
84
71
  private var isHandlingAnnotationSelect = false
85
72
  /// MarkerView 的隐藏容器(用于渲染 children)
86
73
  private var markerContainer: UIView!
74
+ /// 其他覆盖物(Circle, Polyline...)的隐藏容器
75
+ private var overlayContainer: UIView!
76
+ /// 显式跟踪所有覆盖物视图(新架构下 subviews 可能不可靠)
77
+ private var overlayViews: [UIView] = []
87
78
 
88
79
  // MARK: - 初始化
89
80
 
@@ -106,10 +97,19 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
106
97
  markerContainer.isUserInteractionEnabled = false
107
98
  markerContainer.alpha = 0
108
99
 
109
- // 先添加隐藏容器(在最底层)
100
+ // 创建其他覆盖物的隐藏容器
101
+ overlayContainer = UIView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
102
+ overlayContainer.isHidden = true
103
+ overlayContainer.isUserInteractionEnabled = false
104
+ overlayContainer.alpha = 0
105
+
106
+ // 视图层级:
107
+ // 1. self (ExpoGaodeMapView)
108
+ // 2. - markerContainer (隐藏)
109
+ // 3. - overlayContainer (隐藏)
110
+ // 4. - mapView (可见,在最上层)
110
111
  addSubview(markerContainer)
111
-
112
- // 再添加 mapView(在隐藏容器之上,确保地图可以接收触摸)
112
+ addSubview(overlayContainer)
113
113
  addSubview(mapView)
114
114
 
115
115
  cameraManager = CameraManager(mapView: mapView)
@@ -125,70 +125,267 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
125
125
  ])
126
126
  }
127
127
 
128
- overlayManager = OverlayManager(mapView: mapView)
129
-
130
- // 设置覆盖物点击回调
131
- overlayManager.onCirclePress = { [weak self] event in
132
- self?.onCirclePress(event)
133
- }
134
- overlayManager.onPolygonPress = { [weak self] event in
135
- self?.onPolygonPress(event)
136
- }
137
- overlayManager.onPolylinePress = { [weak self] event in
138
- self?.onPolylinePress(event)
139
- }
140
-
141
128
  setupDefaultConfig()
142
129
  }
143
130
 
144
131
  override func layoutSubviews() {
145
132
  super.layoutSubviews()
146
133
  mapView.frame = bounds
147
-
148
- // 收集并设置 MarkerView
149
- collectAndSetupMarkerViews()
134
+ // 🔑 移除自动调用 setupAllOverlayViews(),避免频繁触发
135
+ // layoutSubviews 会在任何视图变化时调用,导致不必要的批量刷新
150
136
  }
151
137
 
152
138
  /**
153
- * 收集所有 MarkerView 子视图并设置地图
139
+ * 视图被添加到窗口时调用
140
+ * 这是确保覆盖物在新架构下正确连接的关键时机
154
141
  */
155
- private func collectAndSetupMarkerViews() {
156
- // 从隐藏容器中收集 MarkerView
157
- for subview in markerContainer.subviews {
158
- if let markerView = subview as? MarkerView {
142
+ override func didMoveToWindow() {
143
+ super.didMoveToWindow()
144
+ if window != nil {
145
+
146
+ // 🔑 只在首次添加到窗口时批量设置,后续添加通过 didAddSubview 单独处理
147
+ setupAllOverlayViews()
148
+ }
149
+ }
150
+
151
+ /**
152
+ * 遍历所有容器,确保每个覆盖物视图都已连接到地图实例
153
+ * 这个函数是幂等的,重复调用是安全的
154
+ */
155
+ private func setupAllOverlayViews() {
156
+ // 统一从 overlayViews 数组设置所有覆盖物(包括 MarkerView)
157
+ for view in overlayViews {
158
+ if let markerView = view as? MarkerView {
159
159
  markerView.setMap(mapView)
160
+ } else if let circleView = view as? CircleView {
161
+ circleView.setMap(mapView)
162
+ } else if let polylineView = view as? PolylineView {
163
+ polylineView.setMap(mapView)
164
+ } else if let polygonView = view as? PolygonView {
165
+ polygonView.setMap(mapView)
166
+ } else if let heatMapView = view as? HeatMapView {
167
+ heatMapView.setMap(mapView)
168
+ } else if let multiPointView = view as? MultiPointView {
169
+ multiPointView.setMap(mapView)
170
+ } else if let clusterView = view as? ClusterView {
171
+ clusterView.setMap(mapView)
160
172
  }
161
173
  }
162
174
  }
163
175
 
164
176
  /**
165
- * 添加子视图时自动连接到地图
166
- * 将地图实例传递给覆盖物子视图
177
+ * 重写 addSubview
178
+ * 根据视图类型,将其分配到正确的隐藏容器中
167
179
  */
168
180
  override func addSubview(_ view: UIView) {
181
+ // 🔑 关键修复:旧架构下统一不移动任何覆盖物视图,避免破坏 React Native 布局
182
+ // 所有覆盖物都隐藏并添加到 overlayViews 数组追踪
169
183
  if let markerView = view as? MarkerView {
170
- // ✅ 关键修复:将 MarkerView 添加到隐藏容器中,而不是主视图
171
- // 这样 MarkerView 完全不会影响地图的触摸事件
172
- markerContainer.addSubview(markerView)
184
+ overlayContainer.addSubview(markerView)
185
+ // 🔑 关键:MarkerView 不能隐藏,否则 children 无法渲染成图片
186
+ // 通过 hitTest 返回 nil 已经确保不阻挡地图交互
187
+ overlayViews.append(markerView)
173
188
  markerView.setMap(mapView)
189
+
174
190
  return
175
191
  }
176
192
 
177
- // 其他视图正常添加
178
- super.addSubview(view)
179
-
180
193
  if let circleView = view as? CircleView {
194
+ overlayContainer.addSubview(circleView)
195
+ circleView.alpha = 0
196
+ circleView.isHidden = true
197
+ overlayViews.append(circleView)
181
198
  circleView.setMap(mapView)
199
+
200
+ return
182
201
  } else if let polylineView = view as? PolylineView {
202
+ overlayContainer.addSubview(polylineView)
203
+ polylineView.alpha = 0
204
+ polylineView.isHidden = true
205
+ overlayViews.append(polylineView)
183
206
  polylineView.setMap(mapView)
207
+
208
+ return
184
209
  } else if let polygonView = view as? PolygonView {
210
+ overlayContainer.addSubview(polygonView)
211
+ polygonView.alpha = 0
212
+ polygonView.isHidden = true
213
+ overlayViews.append(polygonView)
185
214
  polygonView.setMap(mapView)
215
+
216
+ return
186
217
  } else if let heatMapView = view as? HeatMapView {
218
+ overlayContainer.addSubview(heatMapView)
219
+ heatMapView.alpha = 0
220
+ heatMapView.isHidden = true
221
+ overlayViews.append(heatMapView)
187
222
  heatMapView.setMap(mapView)
223
+
224
+ return
188
225
  } else if let multiPointView = view as? MultiPointView {
226
+ overlayContainer.addSubview(multiPointView)
227
+ multiPointView.alpha = 0
228
+ multiPointView.isHidden = true
229
+ overlayViews.append(multiPointView)
189
230
  multiPointView.setMap(mapView)
231
+
232
+ return
190
233
  } else if let clusterView = view as? ClusterView {
234
+ overlayContainer.addSubview(clusterView)
235
+ clusterView.alpha = 0
236
+ clusterView.isHidden = true
237
+ overlayViews.append(clusterView)
191
238
  clusterView.setMap(mapView)
239
+
240
+ return
241
+ }
242
+
243
+ // 其他非地图组件的视图正常添加
244
+ super.addSubview(view)
245
+ }
246
+
247
+ /**
248
+ * 🔑 关键方法:在新架构下捕获子视图添加
249
+ * 当 Fabric 将子视图添加到此视图时,会触发 didAddSubview
250
+ */
251
+ override func didAddSubview(_ subview: UIView) {
252
+ super.didAddSubview(subview)
253
+
254
+
255
+
256
+ // 跳过我们自己创建的容器和地图视图
257
+ if subview === markerContainer || subview === overlayContainer || subview === mapView {
258
+
259
+ return
260
+ }
261
+
262
+ // 🔑 处理 MarkerView - 新架构下直接连接,旧架构下已在 addSubview 处理
263
+ if let markerView = subview as? MarkerView {
264
+ // 检查是否已经在容器中(旧架构下 addSubview 已经处理过)
265
+ if markerView.superview === overlayContainer {
266
+
267
+ return
268
+ }
269
+
270
+ // 🔑 新架构下也不能隐藏 MarkerView,否则 children 无法渲染
271
+ overlayViews.append(markerView)
272
+ markerView.setMap(mapView)
273
+ // 🔑 关键修复:不再调用 setupAllOverlayViews(),避免所有覆盖物重新设置
274
+ return
275
+ }
276
+
277
+ // 🔑 其他覆盖物不移动视图,只设置连接和隐藏
278
+ if let circleView = subview as? CircleView {
279
+ if circleView.superview === overlayContainer {
280
+
281
+ return
282
+ }
283
+
284
+ circleView.alpha = 0
285
+ circleView.isHidden = true
286
+ overlayViews.append(circleView)
287
+ circleView.setMap(mapView)
288
+ // 🔑 关键修复:不再调用 setupAllOverlayViews()
289
+ return
290
+ } else if let polylineView = subview as? PolylineView {
291
+ if polylineView.superview === overlayContainer {
292
+
293
+ return
294
+ }
295
+
296
+ polylineView.alpha = 0
297
+ polylineView.isHidden = true
298
+ overlayViews.append(polylineView)
299
+ polylineView.setMap(mapView)
300
+ // 🔑 关键修复:不再调用 setupAllOverlayViews()
301
+ return
302
+ } else if let polygonView = subview as? PolygonView {
303
+ if polygonView.superview === overlayContainer {
304
+
305
+ return
306
+ }
307
+
308
+ polygonView.alpha = 0
309
+ polygonView.isHidden = true
310
+ overlayViews.append(polygonView)
311
+ polygonView.setMap(mapView)
312
+ // 🔑 关键修复:不再调用 setupAllOverlayViews()
313
+ return
314
+ } else if let heatMapView = subview as? HeatMapView {
315
+ if heatMapView.superview === overlayContainer {
316
+
317
+ return
318
+ }
319
+
320
+ heatMapView.alpha = 0
321
+ heatMapView.isHidden = true
322
+ overlayViews.append(heatMapView)
323
+ heatMapView.setMap(mapView)
324
+ // 🔑 关键修复:不再调用 setupAllOverlayViews()
325
+ return
326
+ } else if let multiPointView = subview as? MultiPointView {
327
+ if multiPointView.superview === overlayContainer {
328
+
329
+ return
330
+ }
331
+
332
+ multiPointView.alpha = 0
333
+ multiPointView.isHidden = true
334
+ overlayViews.append(multiPointView)
335
+ multiPointView.setMap(mapView)
336
+ // 🔑 关键修复:不再调用 setupAllOverlayViews()
337
+ return
338
+ } else if let clusterView = subview as? ClusterView {
339
+ if clusterView.superview === overlayContainer {
340
+
341
+ return
342
+ }
343
+
344
+ clusterView.alpha = 0
345
+ clusterView.isHidden = true
346
+ overlayViews.append(clusterView)
347
+ clusterView.setMap(mapView)
348
+ // 🔑 关键修复:不再调用 setupAllOverlayViews()
349
+ return
350
+ }
351
+
352
+
353
+ }
354
+
355
+ /**
356
+ * 🔑 关键方法:在视图即将被移除时清理覆盖物
357
+ * 新架构下需要手动清理 overlayViews 数组和地图覆盖物
358
+ */
359
+ override func willRemoveSubview(_ subview: UIView) {
360
+ super.willRemoveSubview(subview)
361
+
362
+ // 🔑 处理 MarkerView - 新架构下也需要从数组中移除
363
+ if let markerView = subview as? MarkerView {
364
+ overlayViews.removeAll { $0 === markerView }
365
+ if let annotation = markerView.annotation {
366
+ mapView.removeAnnotation(annotation)
367
+ }
368
+ } else if let circleView = subview as? CircleView {
369
+ overlayViews.removeAll { $0 === circleView }
370
+ if let circle = circleView.circle {
371
+ mapView.remove(circle)
372
+ }
373
+ } else if let polylineView = subview as? PolylineView {
374
+ overlayViews.removeAll { $0 === polylineView }
375
+ if let polyline = polylineView.polyline {
376
+ mapView.remove(polyline)
377
+ }
378
+ } else if let polygonView = subview as? PolygonView {
379
+ overlayViews.removeAll { $0 === polygonView }
380
+ if let polygon = polygonView.polygon {
381
+ mapView.remove(polygon)
382
+ }
383
+ } else if let heatMapView = subview as? HeatMapView {
384
+ overlayViews.removeAll { $0 === heatMapView }
385
+ } else if let multiPointView = subview as? MultiPointView {
386
+ overlayViews.removeAll { $0 === multiPointView }
387
+ } else if let clusterView = subview as? ClusterView {
388
+ overlayViews.removeAll { $0 === clusterView }
192
389
  }
193
390
  }
194
391
 
@@ -229,8 +426,7 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
229
426
  uiManager.setShowsBuildings(showsBuildings)
230
427
  uiManager.setShowsIndoorMap(showsIndoorMap)
231
428
 
232
- // 收集并设置所有 MarkerView
233
- collectAndSetupMarkerViews()
429
+ // applyProps 时不再需要手动收集视图,因为 addSubview 已经处理了
234
430
  }
235
431
 
236
432
  // MARK: - 缩放控制
@@ -265,55 +461,6 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
265
461
  return cameraManager.getCameraPosition()
266
462
  }
267
463
 
268
- // MARK: - 覆盖物管理
269
-
270
- func addCircle(id: String, props: [String: Any]) {
271
- overlayManager.addCircle(id: id, props: props)
272
- }
273
-
274
- func removeCircle(id: String) {
275
- overlayManager.removeCircle(id: id)
276
- }
277
-
278
- func updateCircle(id: String, props: [String: Any]) {
279
- overlayManager.updateCircle(id: id, props: props)
280
- }
281
-
282
- func addMarker(id: String, props: [String: Any]) {
283
- overlayManager.addMarker(id: id, props: props)
284
- }
285
-
286
- func removeMarker(id: String) {
287
- overlayManager.removeMarker(id: id)
288
- }
289
-
290
- func updateMarker(id: String, props: [String: Any]) {
291
- overlayManager.updateMarker(id: id, props: props)
292
- }
293
-
294
- func addPolyline(id: String, props: [String: Any]) {
295
- overlayManager.addPolyline(id: id, props: props)
296
- }
297
-
298
- func removePolyline(id: String) {
299
- overlayManager.removePolyline(id: id)
300
- }
301
-
302
- func updatePolyline(id: String, props: [String: Any]) {
303
- overlayManager.updatePolyline(id: id, props: props)
304
- }
305
-
306
- func addPolygon(id: String, props: [String: Any]) {
307
- overlayManager.addPolygon(id: id, props: props)
308
- }
309
-
310
- func removePolygon(id: String) {
311
- overlayManager.removePolygon(id: id)
312
- }
313
-
314
- func updatePolygon(id: String, props: [String: Any]) {
315
- overlayManager.updatePolygon(id: id, props: props)
316
- }
317
464
 
318
465
  // MARK: - 图层控制
319
466
 
@@ -360,6 +507,8 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
360
507
  uiManager.setUserLocationRepresentation(config)
361
508
  }
362
509
 
510
+
511
+
363
512
  /**
364
513
  * 析构函数 - 清理资源
365
514
  */
@@ -391,35 +540,10 @@ extension ExpoGaodeMapView {
391
540
  return
392
541
  }
393
542
 
394
- // 检查是否点击了圆形 (声明式 CircleView)
395
- if checkCirclePress(at: coordinate) {
396
- return
397
- }
398
-
399
- // 检查是否点击了圆形 (命令式 API)
400
- if overlayManager.checkCirclePress(at: coordinate) {
401
- return
402
- }
403
-
404
- // 检查是否点击了多边形 (声明式)
405
- if checkPolygonPress(at: coordinate) {
406
- return
407
- }
408
-
409
- // 检查是否点击了多边形 (命令式 API)
410
- if overlayManager.checkPolygonPress(at: coordinate) {
411
- return
412
- }
413
-
414
- // 检查是否点击了折线 (声明式)
415
- if checkPolylinePress(at: coordinate) {
416
- return
417
- }
418
-
419
- // 检查是否点击了折线 (命令式 API)
420
- if overlayManager.checkPolylinePress(at: coordinate) {
421
- return
422
- }
543
+ // 检查声明式覆盖物点击
544
+ if checkCirclePress(at: coordinate) { return }
545
+ if checkPolygonPress(at: coordinate) { return }
546
+ if checkPolylinePress(at: coordinate) { return }
423
547
 
424
548
  onMapPress(["latitude": coordinate.latitude, "longitude": coordinate.longitude])
425
549
  }
@@ -428,16 +552,20 @@ extension ExpoGaodeMapView {
428
552
  * 检查点击位置是否在圆形内
429
553
  */
430
554
  private func checkCirclePress(at coordinate: CLLocationCoordinate2D) -> Bool {
431
- let circleViews = subviews.compactMap { $0 as? CircleView }
555
+ // overlayViews 数组中查找 CircleView
556
+ let circleViews = overlayViews.compactMap { $0 as? CircleView }
432
557
 
433
558
  for circleView in circleViews {
434
- guard let circle = circleView.circle else { continue }
559
+ guard let circle = circleView.circle else {
560
+ continue
561
+ }
435
562
 
436
563
  let circleCenter = circle.coordinate
437
564
  let distance = calculateDistance(from: coordinate, to: circleCenter)
438
565
 
439
566
  if distance <= circle.radius {
440
- circleView.onPress([
567
+ // 🔑 关键修复:直接调用 circleView 的 onCirclePress,它会自动派发到 React Native
568
+ circleView.onCirclePress([
441
569
  "latitude": coordinate.latitude,
442
570
  "longitude": coordinate.longitude
443
571
  ])
@@ -460,14 +588,17 @@ extension ExpoGaodeMapView {
460
588
  * 检查点击位置是否在多边形内
461
589
  */
462
590
  private func checkPolygonPress(at coordinate: CLLocationCoordinate2D) -> Bool {
463
- let polygonViews = subviews.compactMap { $0 as? PolygonView }
591
+ // overlayViews 数组中查找 PolygonView
592
+ let polygonViews = overlayViews.compactMap { $0 as? PolygonView }
464
593
 
465
594
  for polygonView in polygonViews {
466
- guard let polygon = polygonView.polygon else { continue }
595
+ guard let polygon = polygonView.polygon else {
596
+ continue
597
+ }
467
598
 
468
599
  // 使用射线法判断点是否在多边形内
469
600
  if isPoint(coordinate, inPolygon: polygon) {
470
- polygonView.onPress([
601
+ polygonView.onPolygonPress([
471
602
  "latitude": coordinate.latitude,
472
603
  "longitude": coordinate.longitude
473
604
  ])
@@ -481,14 +612,17 @@ extension ExpoGaodeMapView {
481
612
  * 检查点击位置是否在折线附近
482
613
  */
483
614
  private func checkPolylinePress(at coordinate: CLLocationCoordinate2D) -> Bool {
484
- let polylineViews = subviews.compactMap { $0 as? PolylineView }
615
+ // overlayViews 数组中查找 PolylineView
616
+ let polylineViews = overlayViews.compactMap { $0 as? PolylineView }
485
617
  let threshold: Double = 20.0 // 20米容差
486
618
 
487
619
  for polylineView in polylineViews {
488
- guard let polyline = polylineView.polyline else { continue }
620
+ guard let polyline = polylineView.polyline else {
621
+ continue
622
+ }
489
623
 
490
624
  if isPoint(coordinate, nearPolyline: polyline, threshold: threshold) {
491
- polylineView.onPress([
625
+ polylineView.onPolylinePress([
492
626
  "latitude": coordinate.latitude,
493
627
  "longitude": coordinate.longitude
494
628
  ])
@@ -592,92 +726,35 @@ extension ExpoGaodeMapView {
592
726
  }
593
727
 
594
728
  if annotation.isKind(of: MAPointAnnotation.self) {
595
- // 首先检查是否是声明式 MarkerView annotation
596
- // 从隐藏容器中查找 MarkerView
597
- for subview in markerContainer.subviews {
598
- if let markerView = subview as? MarkerView, markerView.annotation === annotation {
729
+ // 🔑 统一从 overlayViews 数组查找 MarkerView(新旧架构统一)
730
+ for view in overlayViews {
731
+ if let markerView = view as? MarkerView, markerView.annotation === annotation {
599
732
  return markerView.getAnnotationView(for: mapView, annotation: annotation)
600
733
  }
601
734
  }
602
-
603
- // 如果不是声明式的,检查是否是命令式 API 的 Marker
604
- guard let props = overlayManager.getMarkerProps(for: annotation) else {
605
- return nil
606
- }
607
-
608
- let iconUri = props["icon"] as? String
609
- let iconWidth = props["iconWidth"] as? Double ?? 40
610
- let iconHeight = props["iconHeight"] as? Double ?? 40
611
- let pinColor = props["pinColor"] as? String ?? "red"
612
- let draggable = props["draggable"] as? Bool ?? false
613
-
614
- // 如果有自定义图标,使用 MAAnnotationView
615
- if let iconUri = iconUri, !iconUri.isEmpty {
616
- var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "custom_marker")
617
- if annotationView == nil {
618
- annotationView = MAAnnotationView(annotation: annotation, reuseIdentifier: "custom_marker")
619
- }
620
- annotationView?.annotation = annotation
621
- annotationView?.canShowCallout = true
622
- annotationView?.isDraggable = draggable
623
-
624
- // 加载图标
625
- loadMarkerIcon(iconUri: iconUri) { image in
626
- if let img = image {
627
- // 调整图标大小
628
- let size = CGSize(width: iconWidth, height: iconHeight)
629
- UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
630
- img.draw(in: CGRect(origin: .zero, size: size))
631
- let resizedImage = UIGraphicsGetImageFromCurrentImageContext()
632
- UIGraphicsEndImageContext()
633
-
634
- annotationView?.image = resizedImage
635
- // 设置中心点偏移,使标注底部中间点成为经纬度对应点
636
- annotationView?.centerOffset = CGPoint(x: 0, y: -iconHeight / 2)
637
- }
638
- }
639
-
640
- return annotationView
641
- }
642
-
643
- // 使用大头针样式
644
- guard let pinView = MAPinAnnotationView(annotation: annotation, reuseIdentifier: "pin_marker") else {
645
- return nil
646
- }
647
- pinView.canShowCallout = true
648
- pinView.animatesDrop = true
649
- pinView.isDraggable = draggable
650
-
651
- // 设置大头针颜色
652
- if pinColor == "green" {
653
- pinView.pinColor = .green
654
- } else if pinColor == "purple" {
655
- pinView.pinColor = .purple
656
- } else {
657
- pinView.pinColor = .red
658
- }
659
-
660
- return pinView
661
735
  }
662
736
  return nil
663
737
  }
664
738
 
665
739
  /**
666
740
  * 创建覆盖物渲染器
667
- * 优先使用子视图的渲染器,否则使用 OverlayManager 的渲染器
741
+ * overlayContainer 中查找对应的视图
668
742
  */
669
743
  public func mapView(_ mapView: MAMapView, rendererFor overlay: MAOverlay) -> MAOverlayRenderer {
670
- for subview in subviews {
671
- if let circleView = subview as? CircleView, let circle = circleView.circle, circle === overlay {
672
- return circleView.getRenderer()
673
- } else if let polylineView = subview as? PolylineView, polylineView.polyline === overlay {
744
+ // overlayViews 数组中查找
745
+ for view in overlayViews {
746
+ if let circleView = view as? CircleView, let circle = circleView.circle {
747
+ if circle === overlay {
748
+ return circleView.getRenderer()
749
+ }
750
+ } else if let polylineView = view as? PolylineView, let polyline = polylineView.polyline, polyline === overlay {
674
751
  return polylineView.getRenderer()
675
- } else if let polygonView = subview as? PolygonView, polygonView.polygon === overlay {
752
+ } else if let polygonView = view as? PolygonView, let polygon = polygonView.polygon, polygon === overlay {
676
753
  return polygonView.getRenderer()
677
754
  }
678
755
  }
679
756
 
680
- return overlayManager.getRenderer(for: overlay) ?? MAOverlayRenderer(overlay: overlay)
757
+ return MAOverlayRenderer(overlay: overlay)
681
758
  }
682
759
 
683
760
  /**
@@ -691,13 +768,18 @@ extension ExpoGaodeMapView {
691
768
  // 标记正在处理 annotation 选择,阻止地图点击事件
692
769
  isHandlingAnnotationSelect = true
693
770
 
694
- // 查找对应的 markerId
695
- if let markerId = overlayManager.getMarkerId(for: annotation) {
696
- onMarkerPress([
697
- "markerId": markerId,
698
- "latitude": annotation.coordinate.latitude,
699
- "longitude": annotation.coordinate.longitude
700
- ])
771
+ // 🔑 统一从 overlayViews 查找 MarkerView(新旧架构统一)
772
+ for view in overlayViews {
773
+ if let markerView = view as? MarkerView {
774
+ if markerView.annotation === annotation {
775
+ let eventData: [String: Any] = [
776
+ "latitude": annotation.coordinate.latitude,
777
+ "longitude": annotation.coordinate.longitude
778
+ ]
779
+ markerView.onMarkerPress(eventData)
780
+ return
781
+ }
782
+ }
701
783
  }
702
784
 
703
785
  // 不要立即取消选中,让气泡有机会显示
@@ -708,55 +790,32 @@ extension ExpoGaodeMapView {
708
790
  * 标注拖拽状态变化
709
791
  */
710
792
  public func mapView(_ mapView: MAMapView, annotationView view: MAAnnotationView, didChange newState: MAAnnotationViewDragState, fromOldState oldState: MAAnnotationViewDragState) {
711
- guard let annotation = view.annotation else { return }
712
-
713
- if let markerId = overlayManager.getMarkerId(for: annotation) {
714
- let coord = annotation.coordinate
715
- let event: [String: Any] = [
716
- "markerId": markerId,
717
- "latitude": coord.latitude,
718
- "longitude": coord.longitude
719
- ]
720
-
721
- switch newState {
722
- case .starting:
723
- onMarkerDragStart(event)
724
- case .dragging:
725
- onMarkerDrag(event)
726
- case .ending, .canceling:
727
- onMarkerDragEnd(event)
728
- default:
729
- break
730
- }
793
+ guard let annotation = view.annotation else {
794
+ return
731
795
  }
732
- }
733
-
734
- /**
735
- * 加载标记图标
736
- * @param iconUri 图标 URI (支持 http/https/file/本地资源)
737
- * @param completion 加载完成回调
738
- */
739
- private func loadMarkerIcon(iconUri: String, completion: @escaping (UIImage?) -> Void) {
740
- if iconUri.hasPrefix("http://") || iconUri.hasPrefix("https://") {
741
- // 网络图片
742
- guard let url = URL(string: iconUri) else {
743
- completion(nil)
796
+
797
+ let coord = annotation.coordinate
798
+ let event: [String: Any] = [
799
+ "latitude": coord.latitude,
800
+ "longitude": coord.longitude
801
+ ]
802
+
803
+ // 🔑 统一从 overlayViews 查找 MarkerView(新旧架构统一)
804
+ for view in overlayViews {
805
+ if let markerView = view as? MarkerView, markerView.annotation === annotation {
806
+ switch newState {
807
+ case .starting:
808
+ markerView.onMarkerDragStart(event)
809
+ case .dragging:
810
+ markerView.onMarkerDrag(event)
811
+ case .ending, .canceling:
812
+ markerView.onMarkerDragEnd(event)
813
+ default:
814
+ break
815
+ }
744
816
  return
745
817
  }
746
- URLSession.shared.dataTask(with: url) { data, _, _ in
747
- guard let data = data, let image = UIImage(data: data) else {
748
- DispatchQueue.main.async { completion(nil) }
749
- return
750
- }
751
- DispatchQueue.main.async { completion(image) }
752
- }.resume()
753
- } else if iconUri.hasPrefix("file://") {
754
- // 本地文件
755
- let path = String(iconUri.dropFirst(7))
756
- completion(UIImage(contentsOfFile: path))
757
- } else {
758
- // 资源文件名
759
- completion(UIImage(named: iconUri))
760
818
  }
819
+
761
820
  }
762
821
  }