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
@@ -1,522 +0,0 @@
1
- import MAMapKit
2
-
3
- /**
4
- * 覆盖物管理器
5
- *
6
- * 负责:
7
- * - 管理地图覆盖物(圆形、折线、多边形)
8
- * - 管理标记点(Marker)
9
- * - 处理覆盖物样式和渲染
10
- * - 支持纹理贴图
11
- */
12
- class OverlayManager {
13
- /// 地图视图弱引用
14
- private weak var mapView: MAMapView?
15
- /// 覆盖物字典 (id -> overlay)
16
- private var overlays: [String: MAOverlay] = [:]
17
- /// 覆盖物样式字典 (id -> style)
18
- private var overlayStyles: [String: [String: Any]] = [:]
19
- /// 标记点字典 (id -> annotation)
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)?
35
-
36
- /**
37
- * 初始化覆盖物管理器
38
- * @param mapView 地图视图实例
39
- */
40
- init(mapView: MAMapView) {
41
- self.mapView = mapView
42
- }
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
-
66
- // MARK: - Circle 圆形
67
-
68
- /**
69
- * 添加圆形覆盖物
70
- * @param id 圆形唯一标识
71
- * @param props 圆形属性(center, radius, fillColor, strokeColor, strokeWidth)
72
- */
73
- func addCircle(id: String, props: [String: Any]) {
74
- guard let mapView = mapView,
75
- let center = props["center"] as? [String: Double],
76
- let latitude = center["latitude"],
77
- let longitude = center["longitude"],
78
- let radius = props["radius"] as? Double else { return }
79
-
80
- let circle = MACircle(center: CLLocationCoordinate2D(latitude: latitude, longitude: longitude), radius: radius)
81
- overlayStyles[id] = props
82
- overlays[id] = circle
83
- circleIdMap[circle!] = id
84
- mapView.add(circle!)
85
- }
86
-
87
- /**
88
- * 移除圆形覆盖物
89
- * @param id 圆形唯一标识
90
- */
91
- func removeCircle(id: String) {
92
- guard let mapView = mapView, let circle = overlays[id] as? MACircle else { return }
93
- mapView.remove(circle)
94
- overlays.removeValue(forKey: id)
95
- overlayStyles.removeValue(forKey: id)
96
- circleIdMap.removeValue(forKey: circle)
97
- }
98
-
99
- /**
100
- * 更新圆形覆盖物
101
- * @param id 圆形唯一标识
102
- * @param props 新的圆形属性
103
- */
104
- func updateCircle(id: String, props: [String: Any]) {
105
- removeCircle(id: id)
106
- addCircle(id: id, props: props)
107
- }
108
-
109
- // MARK: - Marker 标记点
110
-
111
- /**
112
- * 添加标记点
113
- * @param id 标记点唯一标识
114
- * @param props 标记点属性(position, title, description)
115
- */
116
- func addMarker(id: String, props: [String: Any]) {
117
- guard let mapView = mapView,
118
- let position = props["position"] as? [String: Double],
119
- let latitude = position["latitude"],
120
- let longitude = position["longitude"] else { return }
121
-
122
- let annotation = MAPointAnnotation()
123
- annotation.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
124
- annotation.title = props["title"] as? String
125
- annotation.subtitle = props["snippet"] as? String ?? props["description"] as? String
126
-
127
- // 先保存 props 和 annotation,再添加到地图
128
- // 这样 viewFor annotation 回调时就能找到 props
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]
143
- }
144
-
145
- /**
146
- * 移除标记点
147
- * @param id 标记点唯一标识
148
- */
149
- func removeMarker(id: String) {
150
- guard let mapView = mapView, let annotation = annotations[id] else { return }
151
- mapView.removeAnnotation(annotation)
152
- annotations.removeValue(forKey: id)
153
- markerProps.removeValue(forKey: id)
154
- }
155
-
156
- /**
157
- * 更新标记点
158
- * @param id 标记点唯一标识
159
- * @param props 新的标记点属性
160
- */
161
- func updateMarker(id: String, props: [String: Any]) {
162
- removeMarker(id: id)
163
- addMarker(id: id, props: props)
164
- }
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
-
175
- // MARK: - Polyline 折线
176
-
177
- /**
178
- * 添加折线覆盖物
179
- * @param id 折线唯一标识
180
- * @param props 折线属性(points, strokeWidth, strokeColor, texture)
181
- */
182
- func addPolyline(id: String, props: [String: Any]) {
183
- guard let mapView = mapView,
184
- let points = props["points"] as? [[String: Double]] else {
185
- return
186
- }
187
-
188
- var coordinates: [CLLocationCoordinate2D] = []
189
- for point in points {
190
- guard let lat = point["latitude"], let lng = point["longitude"] else { continue }
191
- coordinates.append(CLLocationCoordinate2D(latitude: lat, longitude: lng))
192
- }
193
- guard coordinates.count >= 2 else {
194
- return
195
- }
196
-
197
- let polyline = MAPolyline(coordinates: &coordinates, count: UInt(coordinates.count))!
198
-
199
- // 先保存样式和 overlay,再添加到地图
200
- overlayStyles[id] = props
201
- overlays[id] = polyline
202
- polylineIdMap[polyline] = id
203
- mapView.add(polyline)
204
- }
205
-
206
- /**
207
- * 移除折线覆盖物
208
- * @param id 折线唯一标识
209
- */
210
- func removePolyline(id: String) {
211
- guard let mapView = mapView, let polyline = overlays[id] as? MAPolyline else { return }
212
- mapView.remove(polyline)
213
- overlays.removeValue(forKey: id)
214
- overlayStyles.removeValue(forKey: id)
215
- polylineIdMap.removeValue(forKey: polyline)
216
- }
217
-
218
- /**
219
- * 更新折线覆盖物
220
- * @param id 折线唯一标识
221
- * @param props 新的折线属性
222
- */
223
- func updatePolyline(id: String, props: [String: Any]) {
224
- removePolyline(id: id)
225
- addPolyline(id: id, props: props)
226
- }
227
-
228
- // MARK: - Polygon 多边形
229
-
230
- /**
231
- * 添加多边形覆盖物
232
- * @param id 多边形唯一标识
233
- * @param props 多边形属性(points, fillColor, strokeColor, strokeWidth)
234
- */
235
- func addPolygon(id: String, props: [String: Any]) {
236
- guard let mapView = mapView,
237
- let points = props["points"] as? [[String: Double]] else { return }
238
- var coordinates: [CLLocationCoordinate2D] = []
239
- for point in points {
240
- guard let lat = point["latitude"], let lng = point["longitude"] else { continue }
241
- coordinates.append(CLLocationCoordinate2D(latitude: lat, longitude: lng))
242
- }
243
- guard !coordinates.isEmpty else { return }
244
- let polygon = MAPolygon(coordinates: &coordinates, count: UInt(coordinates.count))
245
- overlayStyles[id] = props
246
- overlays[id] = polygon
247
- polygonIdMap[polygon!] = id
248
- mapView.add(polygon!)
249
- }
250
-
251
- /**
252
- * 移除多边形覆盖物
253
- * @param id 多边形唯一标识
254
- */
255
- func removePolygon(id: String) {
256
- guard let mapView = mapView, let polygon = overlays[id] as? MAPolygon else { return }
257
- mapView.remove(polygon)
258
- overlays.removeValue(forKey: id)
259
- overlayStyles.removeValue(forKey: id)
260
- polygonIdMap.removeValue(forKey: polygon)
261
- }
262
-
263
- /**
264
- * 更新多边形覆盖物
265
- * @param id 多边形唯一标识
266
- * @param props 新的多边形属性
267
- */
268
- func updatePolygon(id: String, props: [String: Any]) {
269
- removePolygon(id: id)
270
- addPolygon(id: id, props: props)
271
- }
272
-
273
- // MARK: - Renderer 渲染器
274
-
275
- /**
276
- * 获取覆盖物渲染器
277
- * @param overlay 覆盖物对象
278
- * @return 对应的渲染器
279
- */
280
- func getRenderer(for overlay: MAOverlay) -> MAOverlayRenderer? {
281
- let id = overlays.first(where: { $0.value === overlay })?.key
282
- let style = id != nil ? overlayStyles[id!] : nil
283
-
284
- if let circle = overlay as? MACircle {
285
- guard let renderer = MACircleRenderer(circle: circle) else {
286
- return nil
287
- }
288
-
289
- if let fillColor = style?["fillColor"] {
290
- renderer.fillColor = ColorParser.parseColor(fillColor)
291
- }
292
- if let strokeColor = style?["strokeColor"] {
293
- renderer.strokeColor = ColorParser.parseColor(strokeColor)
294
- }
295
- if let strokeWidth = style?["strokeWidth"] as? Double {
296
- renderer.lineWidth = CGFloat(strokeWidth)
297
- }
298
-
299
- return renderer
300
- } else if let polyline = overlay as? MAPolyline {
301
- let renderer = MAPolylineRenderer(polyline: polyline)!
302
-
303
- print("🔷 OverlayManager.getRenderer(Polyline): style=\(String(describing: style))")
304
-
305
- // 设置线宽
306
- if let width = style?["width"] as? Double {
307
- renderer.lineWidth = CGFloat(width)
308
-
309
- } else if let strokeWidth = style?["strokeWidth"] as? Double {
310
- renderer.lineWidth = CGFloat(strokeWidth)
311
-
312
- } else {
313
- renderer.lineWidth = 8
314
-
315
- }
316
-
317
- // 设置线条样式
318
- renderer.lineJoinType = kMALineJoinRound
319
- renderer.lineCapType = kMALineCapRound
320
-
321
- // 设置纹理或颜色
322
- if let textureUrl = style?["texture"] as? String, !textureUrl.isEmpty {
323
- loadPolylineTexture(url: textureUrl, renderer: renderer)
324
- } else {
325
- if let color = style?["color"] {
326
- let parsedColor = ColorParser.parseColor(color)
327
- renderer.strokeColor = parsedColor ?? .red
328
- } else if let strokeColor = style?["strokeColor"] {
329
- let parsedColor = ColorParser.parseColor(strokeColor)
330
- renderer.strokeColor = parsedColor ?? .red
331
- } else {
332
- renderer.strokeColor = .red
333
- }
334
- }
335
-
336
- return renderer
337
- } else if let polygon = overlay as? MAPolygon {
338
- guard let renderer = MAPolygonRenderer(polygon: polygon) else {
339
- return nil
340
- }
341
-
342
- // 设置填充颜色
343
- if let fillColor = style?["fillColor"] {
344
- let parsedColor = ColorParser.parseColor(fillColor)
345
- renderer.fillColor = parsedColor
346
-
347
- }
348
- // 设置边框颜色
349
- if let strokeColor = style?["strokeColor"] {
350
- let parsedColor = ColorParser.parseColor(strokeColor)
351
- renderer.strokeColor = parsedColor
352
-
353
- }
354
- // 设置边框宽度
355
- if let strokeWidth = style?["strokeWidth"] as? Double {
356
- renderer.lineWidth = CGFloat(strokeWidth)
357
-
358
- }
359
-
360
- return renderer
361
- }
362
-
363
- return nil
364
- }
365
-
366
- /**
367
- * 加载折线纹理图片
368
- * @param url 图片 URL (支持 http/https/file/本地资源)
369
- * @param renderer 折线渲染器
370
- */
371
- private func loadPolylineTexture(url: String, renderer: MAPolylineRenderer) {
372
- if url.hasPrefix("http://") || url.hasPrefix("https://") {
373
- // 网络图片
374
- guard let imageUrl = URL(string: url) else {
375
- return
376
- }
377
- URLSession.shared.dataTask(with: imageUrl) { [weak self] data, _, error in
378
- if let error = error {
379
- return
380
- }
381
- guard let data = data, let image = UIImage(data: data) else {
382
- return
383
- }
384
- DispatchQueue.main.async {
385
- self?.applyPolylineTexture(image: image, to: renderer)
386
- }
387
- }.resume()
388
- } else if url.hasPrefix("file://") {
389
- // 本地文件
390
- let path = String(url.dropFirst(7))
391
- if let image = UIImage(contentsOfFile: path) {
392
- applyPolylineTexture(image: image, to: renderer)
393
- }
394
- } else {
395
- // 资源文件
396
- if let image = UIImage(named: url) {
397
- applyPolylineTexture(image: image, to: renderer)
398
- }
399
- }
400
- }
401
-
402
- /**
403
- * 应用纹理到折线渲染器
404
- * @param image 纹理图片
405
- * @param renderer 折线渲染器
406
- */
407
- private func applyPolylineTexture(image: UIImage, to renderer: MAPolylineRenderer) {
408
- renderer.strokeImage = image
409
- }
410
-
411
- /**
412
- * 检查点击位置是否在多边形内
413
- */
414
- func checkPolygonPress(at coordinate: CLLocationCoordinate2D) -> Bool {
415
- for (polygon, polygonId) in polygonIdMap {
416
- let count = Int(polygon.pointCount)
417
- guard count >= 3 else { continue }
418
-
419
- var coords = [CLLocationCoordinate2D](repeating: CLLocationCoordinate2D(), count: count)
420
- polygon.getCoordinates(&coords, range: NSRange(location: 0, length: count))
421
-
422
- if isPoint(coordinate, inPolygon: coords) {
423
- onPolygonPress?([
424
- "polygonId": polygonId,
425
- "latitude": coordinate.latitude,
426
- "longitude": coordinate.longitude
427
- ])
428
- return true
429
- }
430
- }
431
- return false
432
- }
433
-
434
- /**
435
- * 检查点击位置是否在折线附近
436
- */
437
- func checkPolylinePress(at coordinate: CLLocationCoordinate2D) -> Bool {
438
- let threshold: Double = 20.0
439
- for (polyline, polylineId) in polylineIdMap {
440
- let count = Int(polyline.pointCount)
441
- guard count >= 2 else { continue }
442
-
443
- var coords = [CLLocationCoordinate2D](repeating: CLLocationCoordinate2D(), count: count)
444
- polyline.getCoordinates(&coords, range: NSRange(location: 0, length: count))
445
-
446
- if isPoint(coordinate, nearPolyline: coords, threshold: threshold) {
447
- onPolylinePress?([
448
- "polylineId": polylineId,
449
- "latitude": coordinate.latitude,
450
- "longitude": coordinate.longitude
451
- ])
452
- return true
453
- }
454
- }
455
- return false
456
- }
457
-
458
- private func isPoint(_ point: CLLocationCoordinate2D, inPolygon coords: [CLLocationCoordinate2D]) -> Bool {
459
- var inside = false
460
- var j = coords.count - 1
461
-
462
- for i in 0..<coords.count {
463
- if ((coords[i].latitude > point.latitude) != (coords[j].latitude > point.latitude)) {
464
- let slope = (coords[j].longitude - coords[i].longitude) * (point.latitude - coords[i].latitude) / (coords[j].latitude - coords[i].latitude)
465
- if point.longitude < slope + coords[i].longitude {
466
- inside = !inside
467
- }
468
- }
469
- j = i
470
- }
471
- return inside
472
- }
473
-
474
- private func isPoint(_ point: CLLocationCoordinate2D, nearPolyline coords: [CLLocationCoordinate2D], threshold: Double) -> Bool {
475
- for i in 0..<(coords.count - 1) {
476
- let distance = distanceFromPoint(point, toLineSegment: (coords[i], coords[i + 1]))
477
- if distance <= threshold {
478
- return true
479
- }
480
- }
481
- return false
482
- }
483
-
484
- private func distanceFromPoint(_ point: CLLocationCoordinate2D, toLineSegment line: (CLLocationCoordinate2D, CLLocationCoordinate2D)) -> Double {
485
- let p = CLLocation(latitude: point.latitude, longitude: point.longitude)
486
- let a = CLLocation(latitude: line.0.latitude, longitude: line.0.longitude)
487
- let b = CLLocation(latitude: line.1.latitude, longitude: line.1.longitude)
488
-
489
- let ab = a.distance(from: b)
490
- if ab == 0 { return a.distance(from: p) }
491
-
492
- let t = max(0, min(1, ((p.coordinate.latitude - a.coordinate.latitude) * (b.coordinate.latitude - a.coordinate.latitude) +
493
- (p.coordinate.longitude - a.coordinate.longitude) * (b.coordinate.longitude - a.coordinate.longitude)) /
494
- (ab * ab)))
495
-
496
- let projection = CLLocationCoordinate2D(
497
- latitude: a.coordinate.latitude + t * (b.coordinate.latitude - a.coordinate.latitude),
498
- longitude: a.coordinate.longitude + t * (b.coordinate.longitude - a.coordinate.longitude)
499
- )
500
-
501
- return p.distance(from: CLLocation(latitude: projection.latitude, longitude: projection.longitude))
502
- }
503
-
504
- /**
505
- * 清除所有覆盖物和标记点
506
- */
507
- func clear() {
508
- guard let mapView = mapView else { return }
509
- for overlay in overlays.values {
510
- mapView.remove(overlay)
511
- }
512
- for annotation in annotations.values {
513
- mapView.removeAnnotation(annotation)
514
- }
515
- overlays.removeAll()
516
- overlayStyles.removeAll()
517
- annotations.removeAll()
518
- circleIdMap.removeAll()
519
- polygonIdMap.removeAll()
520
- polylineIdMap.removeAll()
521
- }
522
- }
@@ -1,165 +0,0 @@
1
- //高德地图定位模块
2
-
3
- import { EventSubscription } from 'expo-modules-core';
4
- import ExpoGaodeMapModule from '../ExpoGaodeMapModule';
5
- import type {
6
- Coordinates,
7
- ReGeocode,
8
- LocationOptions,
9
- LocationListener,
10
- LatLng,
11
- CoordinateType,
12
- } from '../types';
13
-
14
-
15
- /**
16
- * 配置方法映射表
17
- * @type {Record<keyof LocationOptions, string>}
18
- *
19
- */
20
- const CONFIG_MAP: Record<keyof LocationOptions, string> = {
21
- withReGeocode: 'setLocatingWithReGeocode',
22
- accuracy: 'setDesiredAccuracy',
23
- mode: 'setLocationMode',
24
- onceLocation: 'setOnceLocation',
25
- interval: 'setInterval',
26
- timeout: 'setLocationTimeout',
27
- reGeocodeTimeout: 'setReGeocodeTimeout',
28
- distanceFilter: 'setDistanceFilter',
29
- sensorEnable: 'setSensorEnable',
30
- wifiScan: 'setWifiScan',
31
- gpsFirst: 'setGpsFirst',
32
- onceLocationLatest: 'setOnceLocationLatest',
33
- geoLanguage: 'setGeoLanguage',
34
- allowsBackgroundLocationUpdates: 'setAllowsBackgroundLocationUpdates',
35
- pausesLocationUpdatesAutomatically: 'setPausesLocationUpdatesAutomatically',
36
- locationCacheEnable: 'setLocationCacheEnable',
37
- httpTimeout: 'setHttpTimeOut',
38
- protocol: 'setLocationProtocol',
39
- };
40
-
41
- /**
42
- * 配置高德地图定位选项
43
- * @param {LocationOptions} options - 定位配置选项对象
44
- * @throws {Error} 当传入的配置方法不存在或不可调用时抛出错误
45
- */
46
- export function configure(options: LocationOptions): void {
47
- Object.entries(options).forEach(([key, value]) => {
48
- if (value !== undefined) {
49
- const methodName = CONFIG_MAP[key as keyof LocationOptions];
50
- const method = ExpoGaodeMapModule[methodName as keyof typeof ExpoGaodeMapModule];
51
- if (typeof method === 'function') {
52
- (method as any).call(ExpoGaodeMapModule, value);
53
- }
54
- }
55
- });
56
- }
57
-
58
-
59
- /**
60
- * 启动高德地图模块,开始连续定位
61
- * @throws 如果模块未初始化或启动失败时抛出异常
62
- */
63
- export function start(): void {
64
- ExpoGaodeMapModule.start?.();
65
- }
66
-
67
-
68
- /**
69
- * 停止高德地图相关功能,停止定位
70
- * @returns {void} 无返回值
71
- */
72
- export function stop(): void {
73
- ExpoGaodeMapModule.stop?.();
74
- }
75
-
76
-
77
- /**
78
- * 检查高德地图模块是否已启动,是否正在定位
79
- * @returns {Promise<boolean>} 返回一个Promise,解析为布尔值表示模块是否已启动
80
- */
81
- export async function isStarted(): Promise<boolean> {
82
- return ExpoGaodeMapModule.isStarted?.() || Promise.resolve(false);
83
- }
84
-
85
-
86
- /**
87
- * 获取设备当前位置信息,单次定位
88
- * @returns {Promise<Coordinates | ReGeocode>} 返回包含坐标或逆地理编码信息的Promise
89
- * @throws 如果定位服务不可用或权限被拒绝时抛出错误
90
- */
91
- export async function getCurrentLocation(): Promise<Coordinates | ReGeocode> {
92
- return ExpoGaodeMapModule.getCurrentLocation?.();
93
- }
94
-
95
-
96
- /**
97
- * 添加位置更新监听器
98
- * @param {LocationListener} listener - 位置更新时的回调函数
99
- * @returns {EventSubscription} 事件订阅对象,包含移除监听器的方法
100
- * @throws 如果底层模块不可用,返回一个空操作的订阅对象
101
- */
102
- export function addLocationListener(listener: LocationListener): EventSubscription {
103
- return ExpoGaodeMapModule.addListener?.('onLocationUpdate', listener) || {
104
- remove: () => {},
105
- } as EventSubscription;
106
- }
107
-
108
-
109
- /**
110
- * 将坐标点转换为指定坐标系下的坐标
111
- * @param {LatLng} coordinate - 需要转换的原始坐标点
112
- * @param {CoordinateType} type - 目标坐标系类型
113
- * @returns {Promise<LatLng>} 转换后的坐标点Promise
114
- * @throws 如果底层模块不可用,则返回原始坐标
115
- */
116
- export async function coordinateConvert(
117
- coordinate: LatLng,
118
- type: CoordinateType
119
- ): Promise<LatLng> {
120
- return ExpoGaodeMapModule.coordinateConvert?.(coordinate, type) || Promise.resolve(coordinate);
121
- }
122
-
123
-
124
- /**
125
- * 开始更新设备方向(罗盘朝向)
126
- * 调用原生模块方法启动方向更新功能
127
- * @throws 如果原生模块未实现此方法会抛出异常
128
- * @platform ios
129
- */
130
- export function startUpdatingHeading(): void {
131
- ExpoGaodeMapModule.startUpdatingHeading?.();
132
- }
133
-
134
-
135
- /**
136
- * 停止更新设备方向(罗盘朝向)
137
- * 调用原生模块方法停止监听设备方向变化
138
- * @throws 如果原生模块未实现此方法会抛出异常
139
- * @platform ios
140
- */
141
- export function stopUpdatingHeading(): void {
142
- ExpoGaodeMapModule.stopUpdatingHeading?.();
143
- }
144
-
145
- /**
146
- * 设置高德地图的API密钥
147
- * @param {string} key - 高德地图的API密钥
148
- * @returns {void}
149
- */
150
- export function setApiKey(key: string): void {
151
- ExpoGaodeMapModule.setApiKey?.(key);
152
- }
153
-
154
- export default {
155
- configure,
156
- start,
157
- stop,
158
- isStarted,
159
- getCurrentLocation,
160
- addLocationListener,
161
- coordinateConvert,
162
- startUpdatingHeading,
163
- stopUpdatingHeading,
164
- setApiKey,
165
- };