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.
- package/README.en.md +32 -46
- package/README.md +51 -71
- package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapView.kt +37 -237
- package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapViewModule.kt +1 -49
- package/android/src/main/java/expo/modules/gaodemap/managers/CameraManager.kt +30 -7
- package/android/src/main/java/expo/modules/gaodemap/managers/UIManager.kt +1 -0
- package/android/src/main/java/expo/modules/gaodemap/modules/LocationManager.kt +10 -1
- package/android/src/main/java/expo/modules/gaodemap/overlays/CircleView.kt +38 -14
- package/android/src/main/java/expo/modules/gaodemap/overlays/CircleViewModule.kt +3 -3
- package/android/src/main/java/expo/modules/gaodemap/overlays/ClusterView.kt +8 -1
- package/android/src/main/java/expo/modules/gaodemap/overlays/HeatMapView.kt +4 -1
- package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerView.kt +322 -93
- package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerViewModule.kt +11 -3
- package/android/src/main/java/expo/modules/gaodemap/overlays/MultiPointView.kt +4 -1
- package/android/src/main/java/expo/modules/gaodemap/overlays/PolygonView.kt +25 -11
- package/android/src/main/java/expo/modules/gaodemap/overlays/PolygonViewModule.kt +3 -3
- package/android/src/main/java/expo/modules/gaodemap/overlays/PolylineView.kt +20 -10
- package/android/src/main/java/expo/modules/gaodemap/overlays/PolylineViewModule.kt +6 -2
- package/build/ExpoGaodeMap.types.d.ts +27 -6
- package/build/ExpoGaodeMap.types.d.ts.map +1 -1
- package/build/ExpoGaodeMap.types.js +3 -0
- package/build/ExpoGaodeMap.types.js.map +1 -1
- package/build/ExpoGaodeMapModule.d.ts +157 -10
- package/build/ExpoGaodeMapModule.d.ts.map +1 -1
- package/build/ExpoGaodeMapModule.js +4 -0
- package/build/ExpoGaodeMapModule.js.map +1 -1
- package/build/ExpoGaodeMapView.d.ts +1 -17
- package/build/ExpoGaodeMapView.d.ts.map +1 -1
- package/build/ExpoGaodeMapView.js +4 -209
- package/build/ExpoGaodeMapView.js.map +1 -1
- package/build/components/overlays/Circle.d.ts +10 -1
- package/build/components/overlays/Circle.d.ts.map +1 -1
- package/build/components/overlays/Circle.js +11 -86
- package/build/components/overlays/Circle.js.map +1 -1
- package/build/components/overlays/Cluster.d.ts.map +1 -1
- package/build/components/overlays/Cluster.js.map +1 -1
- package/build/components/overlays/Marker.d.ts +13 -1
- package/build/components/overlays/Marker.d.ts.map +1 -1
- package/build/components/overlays/Marker.js +51 -115
- package/build/components/overlays/Marker.js.map +1 -1
- package/build/components/overlays/Polygon.d.ts +7 -15
- package/build/components/overlays/Polygon.d.ts.map +1 -1
- package/build/components/overlays/Polygon.js +10 -80
- package/build/components/overlays/Polygon.js.map +1 -1
- package/build/components/overlays/Polyline.d.ts +7 -14
- package/build/components/overlays/Polyline.d.ts.map +1 -1
- package/build/components/overlays/Polyline.js +9 -66
- package/build/components/overlays/Polyline.js.map +1 -1
- package/build/index.d.ts +1 -4
- package/build/index.d.ts.map +1 -1
- package/build/index.js +2 -10
- package/build/index.js.map +1 -1
- package/build/types/index.d.ts +1 -1
- package/build/types/index.d.ts.map +1 -1
- package/build/types/index.js.map +1 -1
- package/build/types/map-view.types.d.ts +0 -76
- package/build/types/map-view.types.d.ts.map +1 -1
- package/build/types/map-view.types.js.map +1 -1
- package/build/types/overlays.types.d.ts +11 -16
- package/build/types/overlays.types.d.ts.map +1 -1
- package/build/types/overlays.types.js.map +1 -1
- package/docs/API.en.md +1 -21
- package/docs/API.md +84 -56
- package/docs/EXAMPLES.en.md +0 -48
- package/docs/EXAMPLES.md +49 -102
- package/docs/INITIALIZATION.md +59 -71
- package/docs/MIGRATION.md +423 -0
- package/ios/ExpoGaodeMapView.swift +317 -258
- package/ios/ExpoGaodeMapViewModule.swift +3 -50
- package/ios/managers/CameraManager.swift +23 -2
- package/ios/managers/UIManager.swift +10 -5
- package/ios/modules/LocationManager.swift +10 -0
- package/ios/overlays/CircleView.swift +98 -19
- package/ios/overlays/CircleViewModule.swift +21 -0
- package/ios/overlays/ClusterView.swift +33 -4
- package/ios/overlays/HeatMapView.swift +16 -4
- package/ios/overlays/MarkerView.swift +235 -146
- package/ios/overlays/MarkerViewModule.swift +7 -3
- package/ios/overlays/MultiPointView.swift +30 -1
- package/ios/overlays/PolygonView.swift +63 -12
- package/ios/overlays/PolygonViewModule.swift +17 -0
- package/ios/overlays/PolylineView.swift +95 -25
- package/ios/overlays/PolylineViewModule.swift +17 -8
- package/ios/utils/PermissionManager.swift +9 -14
- package/package.json +4 -3
- package/src/ExpoGaodeMap.types.ts +28 -3
- package/src/ExpoGaodeMapModule.ts +201 -12
- package/src/ExpoGaodeMapView.tsx +11 -225
- package/src/components/overlays/Circle.tsx +12 -104
- package/src/components/overlays/Cluster.tsx +0 -1
- package/src/components/overlays/Marker.tsx +63 -138
- package/src/components/overlays/Polygon.tsx +12 -92
- package/src/components/overlays/Polyline.tsx +11 -77
- package/src/index.ts +4 -29
- package/src/types/index.ts +1 -1
- package/src/types/map-view.types.ts +1 -69
- package/src/types/overlays.types.ts +11 -16
- package/android/src/main/java/expo/modules/gaodemap/managers/OverlayManager.kt +0 -574
- package/build/modules/AMapLocation.d.ts +0 -78
- package/build/modules/AMapLocation.d.ts.map +0 -1
- package/build/modules/AMapLocation.js +0 -132
- package/build/modules/AMapLocation.js.map +0 -1
- package/build/modules/AMapPermissions.d.ts +0 -29
- package/build/modules/AMapPermissions.d.ts.map +0 -1
- package/build/modules/AMapPermissions.js +0 -23
- package/build/modules/AMapPermissions.js.map +0 -1
- package/build/modules/AMapSDK.d.ts +0 -22
- package/build/modules/AMapSDK.d.ts.map +0 -1
- package/build/modules/AMapSDK.js +0 -25
- package/build/modules/AMapSDK.js.map +0 -1
- package/build/modules/AMapView.d.ts +0 -44
- package/build/modules/AMapView.d.ts.map +0 -1
- package/build/modules/AMapView.js +0 -65
- package/build/modules/AMapView.js.map +0 -1
- package/ios/managers/OverlayManager.swift +0 -522
- package/src/modules/AMapLocation.ts +0 -165
- package/src/modules/AMapPermissions.ts +0 -41
- package/src/modules/AMapSDK.ts +0 -31
- package/src/modules/AMapView.ts +0 -72
- package/test/ClockMapView.tsx +0 -532
- 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
|
-
|
|
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
|
-
//
|
|
149
|
-
collectAndSetupMarkerViews()
|
|
134
|
+
// 🔑 移除自动调用 setupAllOverlayViews(),避免频繁触发
|
|
135
|
+
// layoutSubviews 会在任何视图变化时调用,导致不必要的批量刷新
|
|
150
136
|
}
|
|
151
137
|
|
|
152
138
|
/**
|
|
153
|
-
*
|
|
139
|
+
* 视图被添加到窗口时调用
|
|
140
|
+
* 这是确保覆盖物在新架构下正确连接的关键时机
|
|
154
141
|
*/
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
-
|
|
171
|
-
//
|
|
172
|
-
|
|
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
|
-
//
|
|
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
|
-
//
|
|
395
|
-
if checkCirclePress(at: coordinate) {
|
|
396
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
|
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
|
-
|
|
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 {
|
|
595
|
+
guard let polygon = polygonView.polygon else {
|
|
596
|
+
continue
|
|
597
|
+
}
|
|
467
598
|
|
|
468
599
|
// 使用射线法判断点是否在多边形内
|
|
469
600
|
if isPoint(coordinate, inPolygon: polygon) {
|
|
470
|
-
polygonView.
|
|
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
|
-
|
|
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 {
|
|
620
|
+
guard let polyline = polylineView.polyline else {
|
|
621
|
+
continue
|
|
622
|
+
}
|
|
489
623
|
|
|
490
624
|
if isPoint(coordinate, nearPolyline: polyline, threshold: threshold) {
|
|
491
|
-
polylineView.
|
|
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
|
-
//
|
|
596
|
-
|
|
597
|
-
|
|
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
|
-
*
|
|
741
|
+
* 从 overlayContainer 中查找对应的视图
|
|
668
742
|
*/
|
|
669
743
|
public func mapView(_ mapView: MAMapView, rendererFor overlay: MAOverlay) -> MAOverlayRenderer {
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
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 =
|
|
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
|
|
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
|
-
//
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
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 {
|
|
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
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
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
|
}
|