expo-gaode-map 1.0.2 → 1.0.4
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.md +1 -0
- package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapModule.kt +87 -5
- package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapView.kt +132 -1
- package/android/src/main/java/expo/modules/gaodemap/managers/OverlayManager.kt +271 -6
- package/android/src/main/java/expo/modules/gaodemap/overlays/CircleView.kt +40 -51
- package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerView.kt +3 -0
- package/android/src/main/java/expo/modules/gaodemap/overlays/PolygonView.kt +22 -2
- package/android/src/main/java/expo/modules/gaodemap/overlays/PolylineView.kt +83 -17
- package/build/ExpoGaodeMapView.d.ts +46 -1
- package/build/ExpoGaodeMapView.d.ts.map +1 -1
- package/build/ExpoGaodeMapView.js +134 -1
- package/build/ExpoGaodeMapView.js.map +1 -1
- package/build/components/overlays/Circle.d.ts +0 -20
- package/build/components/overlays/Circle.d.ts.map +1 -1
- package/build/components/overlays/Circle.js +28 -45
- package/build/components/overlays/Circle.js.map +1 -1
- package/build/components/overlays/Marker.d.ts +2 -16
- package/build/components/overlays/Marker.d.ts.map +1 -1
- package/build/components/overlays/Marker.js +60 -37
- package/build/components/overlays/Marker.js.map +1 -1
- package/build/components/overlays/Polygon.d.ts +1 -0
- package/build/components/overlays/Polygon.d.ts.map +1 -1
- package/build/components/overlays/Polygon.js +38 -47
- package/build/components/overlays/Polygon.js.map +1 -1
- package/build/components/overlays/Polyline.d.ts +1 -0
- package/build/components/overlays/Polyline.d.ts.map +1 -1
- package/build/components/overlays/Polyline.js +38 -12
- package/build/components/overlays/Polyline.js.map +1 -1
- package/build/types/map-view.types.d.ts +42 -0
- 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 +31 -1
- package/build/types/overlays.types.d.ts.map +1 -1
- package/build/types/overlays.types.js.map +1 -1
- package/docs/API.md +121 -7
- package/docs/EXAMPLES.md +86 -2
- package/docs/INITIALIZATION.md +14 -4
- package/expo-module.config.json +1 -1
- package/ios/ExpoGaodeMapModule.swift +132 -18
- package/ios/ExpoGaodeMapView.swift +361 -12
- package/ios/managers/OverlayManager.swift +188 -12
- package/ios/modules/LocationManager.swift +3 -0
- package/ios/overlays/CircleView.swift +41 -12
- package/ios/overlays/MarkerView.swift +55 -3
- package/ios/overlays/PolygonView.swift +27 -5
- package/ios/overlays/PolylineView.swift +37 -4
- package/ios/utils/ColorParser.swift +0 -5
- package/ios/utils/PermissionManager.swift +62 -7
- package/package.json +1 -1
- package/src/ExpoGaodeMapView.tsx +194 -1
- package/src/components/overlays/Circle.tsx +31 -48
- package/src/components/overlays/Marker.tsx +69 -42
- package/src/components/overlays/Polygon.tsx +46 -49
- package/src/components/overlays/Polyline.tsx +46 -15
- package/src/types/map-view.types.ts +35 -0
- package/src/types/overlays.types.ts +36 -1
|
@@ -18,6 +18,20 @@ class OverlayManager {
|
|
|
18
18
|
private var overlayStyles: [String: [String: Any]] = [:]
|
|
19
19
|
/// 标记点字典 (id -> annotation)
|
|
20
20
|
private var annotations: [String: MAPointAnnotation] = [:]
|
|
21
|
+
/// 标记点属性字典 (id -> props)
|
|
22
|
+
private var markerProps: [String: [String: Any]] = [:]
|
|
23
|
+
/// Circle 点击回调
|
|
24
|
+
var onCirclePress: (([String: Any]) -> Void)?
|
|
25
|
+
/// Circle ID 映射 (overlay -> id)
|
|
26
|
+
private var circleIdMap: [MACircle: String] = [:]
|
|
27
|
+
/// Polygon ID 映射 (overlay -> id)
|
|
28
|
+
private var polygonIdMap: [MAPolygon: String] = [:]
|
|
29
|
+
/// Polyline ID 映射 (overlay -> id)
|
|
30
|
+
private var polylineIdMap: [MAPolyline: String] = [:]
|
|
31
|
+
/// Polygon 点击回调
|
|
32
|
+
var onPolygonPress: (([String: Any]) -> Void)?
|
|
33
|
+
/// Polyline 点击回调
|
|
34
|
+
var onPolylinePress: (([String: Any]) -> Void)?
|
|
21
35
|
|
|
22
36
|
/**
|
|
23
37
|
* 初始化覆盖物管理器
|
|
@@ -27,6 +41,28 @@ class OverlayManager {
|
|
|
27
41
|
self.mapView = mapView
|
|
28
42
|
}
|
|
29
43
|
|
|
44
|
+
/**
|
|
45
|
+
* 检查点击位置是否在圆形内
|
|
46
|
+
*/
|
|
47
|
+
func checkCirclePress(at coordinate: CLLocationCoordinate2D) -> Bool {
|
|
48
|
+
for (circle, circleId) in circleIdMap {
|
|
49
|
+
let circleCenter = circle.coordinate
|
|
50
|
+
let fromLocation = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
|
|
51
|
+
let toLocation = CLLocation(latitude: circleCenter.latitude, longitude: circleCenter.longitude)
|
|
52
|
+
let distance = fromLocation.distance(from: toLocation)
|
|
53
|
+
|
|
54
|
+
if distance <= circle.radius {
|
|
55
|
+
onCirclePress?([
|
|
56
|
+
"circleId": circleId,
|
|
57
|
+
"latitude": coordinate.latitude,
|
|
58
|
+
"longitude": coordinate.longitude
|
|
59
|
+
])
|
|
60
|
+
return true
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return false
|
|
64
|
+
}
|
|
65
|
+
|
|
30
66
|
// MARK: - Circle 圆形
|
|
31
67
|
|
|
32
68
|
/**
|
|
@@ -43,8 +79,9 @@ class OverlayManager {
|
|
|
43
79
|
|
|
44
80
|
let circle = MACircle(center: CLLocationCoordinate2D(latitude: latitude, longitude: longitude), radius: radius)
|
|
45
81
|
overlayStyles[id] = props
|
|
46
|
-
mapView.add(circle!)
|
|
47
82
|
overlays[id] = circle
|
|
83
|
+
circleIdMap[circle!] = id
|
|
84
|
+
mapView.add(circle!)
|
|
48
85
|
}
|
|
49
86
|
|
|
50
87
|
/**
|
|
@@ -52,10 +89,11 @@ class OverlayManager {
|
|
|
52
89
|
* @param id 圆形唯一标识
|
|
53
90
|
*/
|
|
54
91
|
func removeCircle(id: String) {
|
|
55
|
-
guard let mapView = mapView, let circle = overlays[id] else { return }
|
|
92
|
+
guard let mapView = mapView, let circle = overlays[id] as? MACircle else { return }
|
|
56
93
|
mapView.remove(circle)
|
|
57
94
|
overlays.removeValue(forKey: id)
|
|
58
95
|
overlayStyles.removeValue(forKey: id)
|
|
96
|
+
circleIdMap.removeValue(forKey: circle)
|
|
59
97
|
}
|
|
60
98
|
|
|
61
99
|
/**
|
|
@@ -84,9 +122,24 @@ class OverlayManager {
|
|
|
84
122
|
let annotation = MAPointAnnotation()
|
|
85
123
|
annotation.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
|
|
86
124
|
annotation.title = props["title"] as? String
|
|
87
|
-
annotation.subtitle = props["description"] as? String
|
|
88
|
-
|
|
125
|
+
annotation.subtitle = props["snippet"] as? String ?? props["description"] as? String
|
|
126
|
+
|
|
127
|
+
// 先保存 props 和 annotation,再添加到地图
|
|
128
|
+
// 这样 viewFor annotation 回调时就能找到 props
|
|
89
129
|
annotations[id] = annotation
|
|
130
|
+
markerProps[id] = props
|
|
131
|
+
|
|
132
|
+
mapView.addAnnotation(annotation)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* 根据 annotation 获取 marker 属性
|
|
137
|
+
* @param annotation 标记点对象
|
|
138
|
+
* @return 对应的属性字典
|
|
139
|
+
*/
|
|
140
|
+
func getMarkerProps(for annotation: MAAnnotation) -> [String: Any]? {
|
|
141
|
+
guard let id = getMarkerId(for: annotation) else { return nil }
|
|
142
|
+
return markerProps[id]
|
|
90
143
|
}
|
|
91
144
|
|
|
92
145
|
/**
|
|
@@ -97,6 +150,7 @@ class OverlayManager {
|
|
|
97
150
|
guard let mapView = mapView, let annotation = annotations[id] else { return }
|
|
98
151
|
mapView.removeAnnotation(annotation)
|
|
99
152
|
annotations.removeValue(forKey: id)
|
|
153
|
+
markerProps.removeValue(forKey: id)
|
|
100
154
|
}
|
|
101
155
|
|
|
102
156
|
/**
|
|
@@ -109,6 +163,15 @@ class OverlayManager {
|
|
|
109
163
|
addMarker(id: id, props: props)
|
|
110
164
|
}
|
|
111
165
|
|
|
166
|
+
/**
|
|
167
|
+
* 根据 annotation 获取 markerId
|
|
168
|
+
* @param annotation 标记点对象
|
|
169
|
+
* @return 对应的 markerId,如果未找到返回 nil
|
|
170
|
+
*/
|
|
171
|
+
func getMarkerId(for annotation: MAAnnotation) -> String? {
|
|
172
|
+
return annotations.first(where: { $0.value === annotation })?.key
|
|
173
|
+
}
|
|
174
|
+
|
|
112
175
|
// MARK: - Polyline 折线
|
|
113
176
|
|
|
114
177
|
/**
|
|
@@ -136,6 +199,7 @@ class OverlayManager {
|
|
|
136
199
|
// 先保存样式和 overlay,再添加到地图
|
|
137
200
|
overlayStyles[id] = props
|
|
138
201
|
overlays[id] = polyline
|
|
202
|
+
polylineIdMap[polyline] = id
|
|
139
203
|
mapView.add(polyline)
|
|
140
204
|
}
|
|
141
205
|
|
|
@@ -144,10 +208,11 @@ class OverlayManager {
|
|
|
144
208
|
* @param id 折线唯一标识
|
|
145
209
|
*/
|
|
146
210
|
func removePolyline(id: String) {
|
|
147
|
-
guard let mapView = mapView, let polyline = overlays[id] else { return }
|
|
211
|
+
guard let mapView = mapView, let polyline = overlays[id] as? MAPolyline else { return }
|
|
148
212
|
mapView.remove(polyline)
|
|
149
213
|
overlays.removeValue(forKey: id)
|
|
150
214
|
overlayStyles.removeValue(forKey: id)
|
|
215
|
+
polylineIdMap.removeValue(forKey: polyline)
|
|
151
216
|
}
|
|
152
217
|
|
|
153
218
|
/**
|
|
@@ -178,8 +243,9 @@ class OverlayManager {
|
|
|
178
243
|
guard !coordinates.isEmpty else { return }
|
|
179
244
|
let polygon = MAPolygon(coordinates: &coordinates, count: UInt(coordinates.count))
|
|
180
245
|
overlayStyles[id] = props
|
|
181
|
-
mapView.add(polygon!)
|
|
182
246
|
overlays[id] = polygon
|
|
247
|
+
polygonIdMap[polygon!] = id
|
|
248
|
+
mapView.add(polygon!)
|
|
183
249
|
}
|
|
184
250
|
|
|
185
251
|
/**
|
|
@@ -187,10 +253,11 @@ class OverlayManager {
|
|
|
187
253
|
* @param id 多边形唯一标识
|
|
188
254
|
*/
|
|
189
255
|
func removePolygon(id: String) {
|
|
190
|
-
guard let mapView = mapView, let polygon = overlays[id] else { return }
|
|
256
|
+
guard let mapView = mapView, let polygon = overlays[id] as? MAPolygon else { return }
|
|
191
257
|
mapView.remove(polygon)
|
|
192
258
|
overlays.removeValue(forKey: id)
|
|
193
259
|
overlayStyles.removeValue(forKey: id)
|
|
260
|
+
polygonIdMap.removeValue(forKey: polygon)
|
|
194
261
|
}
|
|
195
262
|
|
|
196
263
|
/**
|
|
@@ -219,15 +286,12 @@ class OverlayManager {
|
|
|
219
286
|
return nil
|
|
220
287
|
}
|
|
221
288
|
|
|
222
|
-
// 设置填充颜色
|
|
223
289
|
if let fillColor = style?["fillColor"] {
|
|
224
290
|
renderer.fillColor = ColorParser.parseColor(fillColor)
|
|
225
291
|
}
|
|
226
|
-
// 设置边框颜色
|
|
227
292
|
if let strokeColor = style?["strokeColor"] {
|
|
228
293
|
renderer.strokeColor = ColorParser.parseColor(strokeColor)
|
|
229
294
|
}
|
|
230
|
-
// 设置边框宽度
|
|
231
295
|
if let strokeWidth = style?["strokeWidth"] as? Double {
|
|
232
296
|
renderer.lineWidth = CGFloat(strokeWidth)
|
|
233
297
|
}
|
|
@@ -236,13 +300,18 @@ class OverlayManager {
|
|
|
236
300
|
} else if let polyline = overlay as? MAPolyline {
|
|
237
301
|
let renderer = MAPolylineRenderer(polyline: polyline)!
|
|
238
302
|
|
|
303
|
+
print("🔷 OverlayManager.getRenderer(Polyline): style=\(String(describing: style))")
|
|
304
|
+
|
|
239
305
|
// 设置线宽
|
|
240
306
|
if let width = style?["width"] as? Double {
|
|
241
307
|
renderer.lineWidth = CGFloat(width)
|
|
308
|
+
|
|
242
309
|
} else if let strokeWidth = style?["strokeWidth"] as? Double {
|
|
243
310
|
renderer.lineWidth = CGFloat(strokeWidth)
|
|
311
|
+
|
|
244
312
|
} else {
|
|
245
313
|
renderer.lineWidth = 8
|
|
314
|
+
|
|
246
315
|
}
|
|
247
316
|
|
|
248
317
|
// 设置线条样式
|
|
@@ -251,16 +320,20 @@ class OverlayManager {
|
|
|
251
320
|
|
|
252
321
|
// 设置纹理或颜色
|
|
253
322
|
if let textureUrl = style?["texture"] as? String, !textureUrl.isEmpty {
|
|
323
|
+
print("🔷 OverlayManager: 加载纹理 \(textureUrl)")
|
|
254
324
|
loadPolylineTexture(url: textureUrl, renderer: renderer)
|
|
255
325
|
} else {
|
|
256
326
|
if let color = style?["color"] {
|
|
257
327
|
let parsedColor = ColorParser.parseColor(color)
|
|
258
328
|
renderer.strokeColor = parsedColor ?? .red
|
|
329
|
+
print("🔷 OverlayManager: color=\(color) -> \(String(describing: parsedColor))")
|
|
259
330
|
} else if let strokeColor = style?["strokeColor"] {
|
|
260
331
|
let parsedColor = ColorParser.parseColor(strokeColor)
|
|
261
332
|
renderer.strokeColor = parsedColor ?? .red
|
|
333
|
+
print("🔷 OverlayManager: strokeColor=\(strokeColor) -> \(String(describing: parsedColor))")
|
|
262
334
|
} else {
|
|
263
335
|
renderer.strokeColor = .red
|
|
336
|
+
print("🔷 OverlayManager: 使用默认红色")
|
|
264
337
|
}
|
|
265
338
|
}
|
|
266
339
|
|
|
@@ -270,17 +343,24 @@ class OverlayManager {
|
|
|
270
343
|
return nil
|
|
271
344
|
}
|
|
272
345
|
|
|
346
|
+
print("🔶 OverlayManager.getRenderer(Polygon): style=\(String(describing: style))")
|
|
347
|
+
|
|
273
348
|
// 设置填充颜色
|
|
274
349
|
if let fillColor = style?["fillColor"] {
|
|
275
|
-
|
|
350
|
+
let parsedColor = ColorParser.parseColor(fillColor)
|
|
351
|
+
renderer.fillColor = parsedColor
|
|
352
|
+
|
|
276
353
|
}
|
|
277
354
|
// 设置边框颜色
|
|
278
355
|
if let strokeColor = style?["strokeColor"] {
|
|
279
|
-
|
|
356
|
+
let parsedColor = ColorParser.parseColor(strokeColor)
|
|
357
|
+
renderer.strokeColor = parsedColor
|
|
358
|
+
|
|
280
359
|
}
|
|
281
360
|
// 设置边框宽度
|
|
282
361
|
if let strokeWidth = style?["strokeWidth"] as? Double {
|
|
283
362
|
renderer.lineWidth = CGFloat(strokeWidth)
|
|
363
|
+
|
|
284
364
|
}
|
|
285
365
|
|
|
286
366
|
return renderer
|
|
@@ -334,6 +414,99 @@ class OverlayManager {
|
|
|
334
414
|
renderer.strokeImage = image
|
|
335
415
|
}
|
|
336
416
|
|
|
417
|
+
/**
|
|
418
|
+
* 检查点击位置是否在多边形内
|
|
419
|
+
*/
|
|
420
|
+
func checkPolygonPress(at coordinate: CLLocationCoordinate2D) -> Bool {
|
|
421
|
+
for (polygon, polygonId) in polygonIdMap {
|
|
422
|
+
let count = Int(polygon.pointCount)
|
|
423
|
+
guard count >= 3 else { continue }
|
|
424
|
+
|
|
425
|
+
var coords = [CLLocationCoordinate2D](repeating: CLLocationCoordinate2D(), count: count)
|
|
426
|
+
polygon.getCoordinates(&coords, range: NSRange(location: 0, length: count))
|
|
427
|
+
|
|
428
|
+
if isPoint(coordinate, inPolygon: coords) {
|
|
429
|
+
onPolygonPress?([
|
|
430
|
+
"polygonId": polygonId,
|
|
431
|
+
"latitude": coordinate.latitude,
|
|
432
|
+
"longitude": coordinate.longitude
|
|
433
|
+
])
|
|
434
|
+
return true
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
return false
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* 检查点击位置是否在折线附近
|
|
442
|
+
*/
|
|
443
|
+
func checkPolylinePress(at coordinate: CLLocationCoordinate2D) -> Bool {
|
|
444
|
+
let threshold: Double = 20.0
|
|
445
|
+
for (polyline, polylineId) in polylineIdMap {
|
|
446
|
+
let count = Int(polyline.pointCount)
|
|
447
|
+
guard count >= 2 else { continue }
|
|
448
|
+
|
|
449
|
+
var coords = [CLLocationCoordinate2D](repeating: CLLocationCoordinate2D(), count: count)
|
|
450
|
+
polyline.getCoordinates(&coords, range: NSRange(location: 0, length: count))
|
|
451
|
+
|
|
452
|
+
if isPoint(coordinate, nearPolyline: coords, threshold: threshold) {
|
|
453
|
+
onPolylinePress?([
|
|
454
|
+
"polylineId": polylineId,
|
|
455
|
+
"latitude": coordinate.latitude,
|
|
456
|
+
"longitude": coordinate.longitude
|
|
457
|
+
])
|
|
458
|
+
return true
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
return false
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
private func isPoint(_ point: CLLocationCoordinate2D, inPolygon coords: [CLLocationCoordinate2D]) -> Bool {
|
|
465
|
+
var inside = false
|
|
466
|
+
var j = coords.count - 1
|
|
467
|
+
|
|
468
|
+
for i in 0..<coords.count {
|
|
469
|
+
if ((coords[i].latitude > point.latitude) != (coords[j].latitude > point.latitude)) {
|
|
470
|
+
let slope = (coords[j].longitude - coords[i].longitude) * (point.latitude - coords[i].latitude) / (coords[j].latitude - coords[i].latitude)
|
|
471
|
+
if point.longitude < slope + coords[i].longitude {
|
|
472
|
+
inside = !inside
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
j = i
|
|
476
|
+
}
|
|
477
|
+
return inside
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
private func isPoint(_ point: CLLocationCoordinate2D, nearPolyline coords: [CLLocationCoordinate2D], threshold: Double) -> Bool {
|
|
481
|
+
for i in 0..<(coords.count - 1) {
|
|
482
|
+
let distance = distanceFromPoint(point, toLineSegment: (coords[i], coords[i + 1]))
|
|
483
|
+
if distance <= threshold {
|
|
484
|
+
return true
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
return false
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
private func distanceFromPoint(_ point: CLLocationCoordinate2D, toLineSegment line: (CLLocationCoordinate2D, CLLocationCoordinate2D)) -> Double {
|
|
491
|
+
let p = CLLocation(latitude: point.latitude, longitude: point.longitude)
|
|
492
|
+
let a = CLLocation(latitude: line.0.latitude, longitude: line.0.longitude)
|
|
493
|
+
let b = CLLocation(latitude: line.1.latitude, longitude: line.1.longitude)
|
|
494
|
+
|
|
495
|
+
let ab = a.distance(from: b)
|
|
496
|
+
if ab == 0 { return a.distance(from: p) }
|
|
497
|
+
|
|
498
|
+
let t = max(0, min(1, ((p.coordinate.latitude - a.coordinate.latitude) * (b.coordinate.latitude - a.coordinate.latitude) +
|
|
499
|
+
(p.coordinate.longitude - a.coordinate.longitude) * (b.coordinate.longitude - a.coordinate.longitude)) /
|
|
500
|
+
(ab * ab)))
|
|
501
|
+
|
|
502
|
+
let projection = CLLocationCoordinate2D(
|
|
503
|
+
latitude: a.coordinate.latitude + t * (b.coordinate.latitude - a.coordinate.latitude),
|
|
504
|
+
longitude: a.coordinate.longitude + t * (b.coordinate.longitude - a.coordinate.longitude)
|
|
505
|
+
)
|
|
506
|
+
|
|
507
|
+
return p.distance(from: CLLocation(latitude: projection.latitude, longitude: projection.longitude))
|
|
508
|
+
}
|
|
509
|
+
|
|
337
510
|
/**
|
|
338
511
|
* 清除所有覆盖物和标记点
|
|
339
512
|
*/
|
|
@@ -348,5 +521,8 @@ class OverlayManager {
|
|
|
348
521
|
overlays.removeAll()
|
|
349
522
|
overlayStyles.removeAll()
|
|
350
523
|
annotations.removeAll()
|
|
524
|
+
circleIdMap.removeAll()
|
|
525
|
+
polygonIdMap.removeAll()
|
|
526
|
+
polylineIdMap.removeAll()
|
|
351
527
|
}
|
|
352
528
|
}
|
|
@@ -179,6 +179,9 @@ class LocationManager: NSObject, AMapLocationManagerDelegate {
|
|
|
179
179
|
locationManager?.locationTimeout = 1
|
|
180
180
|
locationManager?.reGeocodeTimeout = 1
|
|
181
181
|
locationManager?.locatingWithReGeocode = true
|
|
182
|
+
|
|
183
|
+
// iOS 9 之前:防止后台被系统挂起(默认关闭,用户可通过 setPausesLocationUpdatesAutomatically 配置)
|
|
184
|
+
locationManager?.pausesLocationUpdatesAutomatically = false
|
|
182
185
|
}
|
|
183
186
|
|
|
184
187
|
// MARK: - AMapLocationManagerDelegate
|
|
@@ -10,6 +10,9 @@ import MAMapKit
|
|
|
10
10
|
* - 响应属性变化并更新渲染
|
|
11
11
|
*/
|
|
12
12
|
class CircleView: ExpoView {
|
|
13
|
+
/// 事件派发器
|
|
14
|
+
let onPress = EventDispatcher()
|
|
15
|
+
|
|
13
16
|
/// 圆心坐标
|
|
14
17
|
var circleCenter: [String: Double] = [:]
|
|
15
18
|
/// 半径(米)
|
|
@@ -30,7 +33,6 @@ class CircleView: ExpoView {
|
|
|
30
33
|
|
|
31
34
|
required init(appContext: AppContext? = nil) {
|
|
32
35
|
super.init(appContext: appContext)
|
|
33
|
-
circle = MACircle()
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
/**
|
|
@@ -39,19 +41,39 @@ class CircleView: ExpoView {
|
|
|
39
41
|
*/
|
|
40
42
|
func setMap(_ map: MAMapView) {
|
|
41
43
|
self.mapView = map
|
|
42
|
-
|
|
43
|
-
map.add(circle)
|
|
44
|
-
}
|
|
44
|
+
updateCircle()
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
48
|
* 更新圆形覆盖物
|
|
49
49
|
*/
|
|
50
50
|
private func updateCircle() {
|
|
51
|
-
guard let
|
|
52
|
-
let
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
guard let mapView = mapView,
|
|
52
|
+
let latitude = circleCenter["latitude"],
|
|
53
|
+
let longitude = circleCenter["longitude"],
|
|
54
|
+
radius > 0 else {
|
|
55
|
+
print("❌ CircleView.updateCircle: 条件不满足")
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
print("🔵 CircleView.updateCircle: center=(\(latitude),\(longitude)), radius=\(radius)")
|
|
60
|
+
print("🔵 CircleView.updateCircle: fillColor=\(String(describing: fillColor)), strokeColor=\(String(describing: strokeColor)), strokeWidth=\(strokeWidth)")
|
|
61
|
+
|
|
62
|
+
if circle == nil {
|
|
63
|
+
let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
|
|
64
|
+
circle = MACircle(center: coordinate, radius: radius)
|
|
65
|
+
mapView.add(circle!)
|
|
66
|
+
print("🔵 CircleView.updateCircle: 创建新圆形")
|
|
67
|
+
} else {
|
|
68
|
+
circle?.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
|
|
69
|
+
circle?.radius = radius
|
|
70
|
+
mapView.remove(circle!)
|
|
71
|
+
mapView.add(circle!)
|
|
72
|
+
print("🔵 CircleView.updateCircle: 更新现有圆形")
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
renderer = nil
|
|
76
|
+
print("🔵 CircleView.updateCircle: renderer 已清空")
|
|
55
77
|
}
|
|
56
78
|
|
|
57
79
|
/**
|
|
@@ -61,9 +83,15 @@ class CircleView: ExpoView {
|
|
|
61
83
|
func getRenderer() -> MAOverlayRenderer {
|
|
62
84
|
if renderer == nil, let circle = circle {
|
|
63
85
|
renderer = MACircleRenderer(circle: circle)
|
|
64
|
-
|
|
65
|
-
|
|
86
|
+
let parsedFillColor = ColorParser.parseColor(fillColor)
|
|
87
|
+
let parsedStrokeColor = ColorParser.parseColor(strokeColor)
|
|
88
|
+
renderer?.fillColor = parsedFillColor ?? UIColor.clear
|
|
89
|
+
renderer?.strokeColor = parsedStrokeColor ?? UIColor.clear
|
|
66
90
|
renderer?.lineWidth = CGFloat(strokeWidth)
|
|
91
|
+
print("🔵 CircleView.getRenderer: 创建新 renderer")
|
|
92
|
+
print("🔵 CircleView.getRenderer: fillColor=\(String(describing: parsedFillColor)), strokeColor=\(String(describing: parsedStrokeColor)), lineWidth=\(strokeWidth)")
|
|
93
|
+
} else {
|
|
94
|
+
print("🔵 CircleView.getRenderer: 使用缓存的 renderer")
|
|
67
95
|
}
|
|
68
96
|
return renderer!
|
|
69
97
|
}
|
|
@@ -74,7 +102,6 @@ class CircleView: ExpoView {
|
|
|
74
102
|
*/
|
|
75
103
|
func setCenter(_ center: [String: Double]) {
|
|
76
104
|
circleCenter = center
|
|
77
|
-
renderer = nil
|
|
78
105
|
updateCircle()
|
|
79
106
|
}
|
|
80
107
|
|
|
@@ -84,7 +111,6 @@ class CircleView: ExpoView {
|
|
|
84
111
|
*/
|
|
85
112
|
func setRadius(_ radius: Double) {
|
|
86
113
|
self.radius = radius
|
|
87
|
-
renderer = nil
|
|
88
114
|
updateCircle()
|
|
89
115
|
}
|
|
90
116
|
|
|
@@ -93,6 +119,7 @@ class CircleView: ExpoView {
|
|
|
93
119
|
* @param color 颜色值
|
|
94
120
|
*/
|
|
95
121
|
func setFillColor(_ color: Any?) {
|
|
122
|
+
print("🔵 CircleView.setFillColor: \(String(describing: color))")
|
|
96
123
|
fillColor = color
|
|
97
124
|
renderer = nil
|
|
98
125
|
updateCircle()
|
|
@@ -103,6 +130,7 @@ class CircleView: ExpoView {
|
|
|
103
130
|
* @param color 颜色值
|
|
104
131
|
*/
|
|
105
132
|
func setStrokeColor(_ color: Any?) {
|
|
133
|
+
print("🔵 CircleView.setStrokeColor: \(String(describing: color))")
|
|
106
134
|
strokeColor = color
|
|
107
135
|
renderer = nil
|
|
108
136
|
updateCircle()
|
|
@@ -113,6 +141,7 @@ class CircleView: ExpoView {
|
|
|
113
141
|
* @param width 宽度值
|
|
114
142
|
*/
|
|
115
143
|
func setStrokeWidth(_ width: Float) {
|
|
144
|
+
print("🔵 CircleView.setStrokeWidth: \(width)")
|
|
116
145
|
strokeWidth = width
|
|
117
146
|
renderer = nil
|
|
118
147
|
updateCircle()
|
|
@@ -3,13 +3,20 @@ import MAMapKit
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* 标记点视图
|
|
6
|
-
*
|
|
6
|
+
*
|
|
7
7
|
* 负责:
|
|
8
8
|
* - 在地图上显示标记点
|
|
9
9
|
* - 管理标记点属性(位置、标题、描述)
|
|
10
10
|
* - 支持拖拽功能
|
|
11
|
+
* - 支持自定义 children 视图
|
|
11
12
|
*/
|
|
12
13
|
class MarkerView: ExpoView {
|
|
14
|
+
// MARK: - 事件派发器
|
|
15
|
+
let onPress = EventDispatcher()
|
|
16
|
+
let onDragStart = EventDispatcher()
|
|
17
|
+
let onDrag = EventDispatcher()
|
|
18
|
+
let onDragEnd = EventDispatcher()
|
|
19
|
+
|
|
13
20
|
/// 标记点位置
|
|
14
21
|
var position: [String: Double] = [:]
|
|
15
22
|
/// 标题
|
|
@@ -18,11 +25,27 @@ class MarkerView: ExpoView {
|
|
|
18
25
|
var markerDescription: String = ""
|
|
19
26
|
/// 是否可拖拽
|
|
20
27
|
var draggable: Bool = false
|
|
28
|
+
/// 图标 URI
|
|
29
|
+
var iconUri: String?
|
|
30
|
+
/// 图标宽度
|
|
31
|
+
var iconWidth: Double = 40
|
|
32
|
+
/// 图标高度
|
|
33
|
+
var iconHeight: Double = 40
|
|
34
|
+
/// 中心偏移
|
|
35
|
+
var centerOffset: [String: Double]?
|
|
36
|
+
/// 是否显示动画
|
|
37
|
+
var animatesDrop: Bool = false
|
|
38
|
+
/// 大头针颜色
|
|
39
|
+
var pinColor: String = "red"
|
|
40
|
+
/// 是否显示气泡
|
|
41
|
+
var canShowCallout: Bool = true
|
|
21
42
|
|
|
22
43
|
/// 地图视图弱引用
|
|
23
44
|
private var mapView: MAMapView?
|
|
24
45
|
/// 标记点对象
|
|
25
|
-
|
|
46
|
+
var annotation: MAPointAnnotation?
|
|
47
|
+
/// 标记点视图
|
|
48
|
+
private var annotationView: MAAnnotationView?
|
|
26
49
|
|
|
27
50
|
required init(appContext: AppContext? = nil) {
|
|
28
51
|
super.init(appContext: appContext)
|
|
@@ -60,6 +83,9 @@ class MarkerView: ExpoView {
|
|
|
60
83
|
|
|
61
84
|
mapView.addAnnotation(annotation)
|
|
62
85
|
self.annotation = annotation
|
|
86
|
+
|
|
87
|
+
// 获取 annotationView
|
|
88
|
+
annotationView = mapView.view(for: annotation)
|
|
63
89
|
}
|
|
64
90
|
|
|
65
91
|
/**
|
|
@@ -95,7 +121,33 @@ class MarkerView: ExpoView {
|
|
|
95
121
|
*/
|
|
96
122
|
func setDraggable(_ draggable: Bool) {
|
|
97
123
|
self.draggable = draggable
|
|
98
|
-
|
|
124
|
+
updateAnnotation()
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
func setIcon(_ source: [String: Any]?) {
|
|
128
|
+
if let dict = source {
|
|
129
|
+
// 处理 require() 返回的对象
|
|
130
|
+
if let uri = dict["uri"] as? String {
|
|
131
|
+
self.iconUri = uri
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
updateAnnotation()
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
func setCenterOffset(_ offset: [String: Double]) {
|
|
138
|
+
self.centerOffset = offset
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
func setAnimatesDrop(_ animate: Bool) {
|
|
142
|
+
self.animatesDrop = animate
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
func setPinColor(_ color: String) {
|
|
146
|
+
self.pinColor = color
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
func setCanShowCallout(_ show: Bool) {
|
|
150
|
+
self.canShowCallout = show
|
|
99
151
|
}
|
|
100
152
|
|
|
101
153
|
/**
|
|
@@ -10,6 +10,8 @@ import MAMapKit
|
|
|
10
10
|
* - 响应属性变化并更新渲染
|
|
11
11
|
*/
|
|
12
12
|
class PolygonView: ExpoView {
|
|
13
|
+
let onPress = EventDispatcher()
|
|
14
|
+
|
|
13
15
|
/// 多边形点数组
|
|
14
16
|
var points: [[String: Double]] = []
|
|
15
17
|
/// 填充颜色
|
|
@@ -43,17 +45,29 @@ class PolygonView: ExpoView {
|
|
|
43
45
|
* 更新多边形覆盖物
|
|
44
46
|
*/
|
|
45
47
|
private func updatePolygon() {
|
|
46
|
-
guard let mapView = mapView else {
|
|
48
|
+
guard let mapView = mapView else {
|
|
49
|
+
print("❌ PolygonView.updatePolygon: mapView 为空")
|
|
50
|
+
return
|
|
51
|
+
}
|
|
47
52
|
if let old = polygon { mapView.remove(old) }
|
|
48
53
|
|
|
49
54
|
var coords = points.compactMap { point -> CLLocationCoordinate2D? in
|
|
50
55
|
guard let lat = point["latitude"], let lng = point["longitude"] else { return nil }
|
|
51
56
|
return CLLocationCoordinate2D(latitude: lat, longitude: lng)
|
|
52
57
|
}
|
|
53
|
-
guard !coords.isEmpty else {
|
|
58
|
+
guard !coords.isEmpty else {
|
|
59
|
+
print("❌ PolygonView.updatePolygon: 点数组为空")
|
|
60
|
+
return
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
print("🔶 PolygonView.updatePolygon: points=\(coords.count)个点")
|
|
64
|
+
print("🔶 PolygonView.updatePolygon: fillColor=\(String(describing: fillColor)), strokeColor=\(String(describing: strokeColor)), strokeWidth=\(strokeWidth)")
|
|
54
65
|
|
|
55
66
|
polygon = MAPolygon(coordinates: &coords, count: UInt(coords.count))
|
|
56
67
|
mapView.add(polygon!)
|
|
68
|
+
|
|
69
|
+
renderer = nil
|
|
70
|
+
print("🔶 PolygonView.updatePolygon: renderer 已清空")
|
|
57
71
|
}
|
|
58
72
|
|
|
59
73
|
/**
|
|
@@ -63,9 +77,15 @@ class PolygonView: ExpoView {
|
|
|
63
77
|
func getRenderer() -> MAOverlayRenderer {
|
|
64
78
|
if renderer == nil, let polygon = polygon {
|
|
65
79
|
renderer = MAPolygonRenderer(polygon: polygon)
|
|
66
|
-
|
|
67
|
-
|
|
80
|
+
let parsedFillColor = ColorParser.parseColor(fillColor)
|
|
81
|
+
let parsedStrokeColor = ColorParser.parseColor(strokeColor)
|
|
82
|
+
renderer?.fillColor = parsedFillColor ?? UIColor.clear
|
|
83
|
+
renderer?.strokeColor = parsedStrokeColor ?? UIColor.clear
|
|
68
84
|
renderer?.lineWidth = CGFloat(strokeWidth)
|
|
85
|
+
print("🔶 PolygonView.getRenderer: 创建新 renderer")
|
|
86
|
+
print("🔶 PolygonView.getRenderer: fillColor=\(String(describing: parsedFillColor)), strokeColor=\(String(describing: parsedStrokeColor)), lineWidth=\(strokeWidth)")
|
|
87
|
+
} else {
|
|
88
|
+
print("🔶 PolygonView.getRenderer: 使用缓存的 renderer")
|
|
69
89
|
}
|
|
70
90
|
return renderer!
|
|
71
91
|
}
|
|
@@ -76,7 +96,6 @@ class PolygonView: ExpoView {
|
|
|
76
96
|
*/
|
|
77
97
|
func setPoints(_ points: [[String: Double]]) {
|
|
78
98
|
self.points = points
|
|
79
|
-
renderer = nil
|
|
80
99
|
updatePolygon()
|
|
81
100
|
}
|
|
82
101
|
|
|
@@ -85,6 +104,7 @@ class PolygonView: ExpoView {
|
|
|
85
104
|
* @param color 颜色值
|
|
86
105
|
*/
|
|
87
106
|
func setFillColor(_ color: Any?) {
|
|
107
|
+
print("🔶 PolygonView.setFillColor: \(String(describing: color))")
|
|
88
108
|
fillColor = color
|
|
89
109
|
renderer = nil
|
|
90
110
|
updatePolygon()
|
|
@@ -95,6 +115,7 @@ class PolygonView: ExpoView {
|
|
|
95
115
|
* @param color 颜色值
|
|
96
116
|
*/
|
|
97
117
|
func setStrokeColor(_ color: Any?) {
|
|
118
|
+
print("🔶 PolygonView.setStrokeColor: \(String(describing: color))")
|
|
98
119
|
strokeColor = color
|
|
99
120
|
renderer = nil
|
|
100
121
|
updatePolygon()
|
|
@@ -105,6 +126,7 @@ class PolygonView: ExpoView {
|
|
|
105
126
|
* @param width 宽度值
|
|
106
127
|
*/
|
|
107
128
|
func setStrokeWidth(_ width: Float) {
|
|
129
|
+
print("🔶 PolygonView.setStrokeWidth: \(width)")
|
|
108
130
|
strokeWidth = width
|
|
109
131
|
renderer = nil
|
|
110
132
|
updatePolygon()
|