expo-gaode-map-navigation 1.1.5 → 1.1.6

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 (146) hide show
  1. package/README.md +213 -73
  2. package/android/build.gradle +10 -0
  3. package/android/src/main/cpp/CMakeLists.txt +24 -0
  4. package/android/src/main/cpp/cluster_jni.cpp +848 -0
  5. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapModule.kt +616 -92
  6. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapOfflineModule.kt +493 -0
  7. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapView.kt +230 -14
  8. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapViewModule.kt +37 -27
  9. package/android/src/main/java/expo/modules/gaodemap/map/MapPreloadManager.kt +494 -0
  10. package/android/src/main/java/expo/modules/gaodemap/map/companion/BitmapDescriptorCache.kt +30 -0
  11. package/android/src/main/java/expo/modules/gaodemap/map/companion/IconBitmapCache.kt +37 -0
  12. package/android/src/main/java/expo/modules/gaodemap/map/managers/UIManager.kt +76 -0
  13. package/android/src/main/java/expo/modules/gaodemap/map/modules/LocationManager.kt +15 -3
  14. package/android/src/main/java/expo/modules/gaodemap/map/modules/SDKInitializer.kt +4 -59
  15. package/android/src/main/java/expo/modules/gaodemap/map/overlays/CircleView.kt +9 -12
  16. package/android/src/main/java/expo/modules/gaodemap/map/overlays/CircleViewModule.kt +5 -6
  17. package/android/src/main/java/expo/modules/gaodemap/map/overlays/ClusterView.kt +539 -66
  18. package/android/src/main/java/expo/modules/gaodemap/map/overlays/ClusterViewModule.kt +17 -1
  19. package/android/src/main/java/expo/modules/gaodemap/map/overlays/HeatMapView.kt +165 -33
  20. package/android/src/main/java/expo/modules/gaodemap/map/overlays/HeatMapViewModule.kt +15 -3
  21. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MarkerView.kt +1249 -672
  22. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MarkerViewModule.kt +40 -17
  23. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MultiPointView.kt +177 -22
  24. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MultiPointViewModule.kt +11 -3
  25. package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolygonView.kt +57 -14
  26. package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolygonViewModule.kt +9 -5
  27. package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolylineView.kt +90 -63
  28. package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolylineViewModule.kt +7 -3
  29. package/android/src/main/java/expo/modules/gaodemap/map/services/LocationForegroundService.kt +3 -2
  30. package/android/src/main/java/expo/modules/gaodemap/map/utils/BitmapDescriptorCache.kt +20 -0
  31. package/android/src/main/java/expo/modules/gaodemap/map/utils/ClusterNative.kt +13 -0
  32. package/android/src/main/java/expo/modules/gaodemap/map/utils/ColorParser.kt +20 -0
  33. package/android/src/main/java/expo/modules/gaodemap/map/utils/GeometryUtils.kt +515 -0
  34. package/android/src/main/java/expo/modules/gaodemap/map/utils/LatLngParser.kt +91 -0
  35. package/android/src/main/java/expo/modules/gaodemap/map/utils/PermissionHelper.kt +248 -0
  36. package/build/ExpoGaodeMapNaviView.d.ts +7 -7
  37. package/build/ExpoGaodeMapNaviView.js +10 -11
  38. package/build/ExpoGaodeMapNavigationModule.d.ts +2 -1
  39. package/build/index.d.ts +35 -33
  40. package/build/index.js +70 -106
  41. package/build/map/ExpoGaodeMapModule.d.ts +2 -201
  42. package/build/map/ExpoGaodeMapModule.js +586 -18
  43. package/build/map/ExpoGaodeMapOfflineModule.d.ts +139 -0
  44. package/build/map/ExpoGaodeMapOfflineModule.js +8 -0
  45. package/build/map/ExpoGaodeMapView.js +66 -58
  46. package/build/map/components/FoldableMapView.d.ts +38 -0
  47. package/build/map/components/FoldableMapView.js +209 -0
  48. package/build/map/components/MapContext.d.ts +12 -0
  49. package/build/map/components/MapContext.js +54 -0
  50. package/build/map/components/MapUI.d.ts +18 -0
  51. package/build/map/components/MapUI.js +29 -0
  52. package/build/map/components/overlays/Circle.js +34 -3
  53. package/build/map/components/overlays/Cluster.d.ts +3 -1
  54. package/build/map/components/overlays/Cluster.js +31 -2
  55. package/build/map/components/overlays/HeatMap.d.ts +3 -1
  56. package/build/map/components/overlays/HeatMap.js +33 -3
  57. package/build/map/components/overlays/Marker.d.ts +1 -1
  58. package/build/map/components/overlays/Marker.js +37 -32
  59. package/build/map/components/overlays/MultiPoint.js +1 -1
  60. package/build/map/components/overlays/Polygon.js +30 -3
  61. package/build/map/components/overlays/Polyline.js +36 -3
  62. package/build/map/index.d.ts +25 -5
  63. package/build/map/index.js +59 -18
  64. package/build/map/types/common.types.d.ts +40 -0
  65. package/build/map/types/common.types.js +0 -4
  66. package/build/map/types/index.d.ts +3 -2
  67. package/build/map/types/map-view.types.d.ts +108 -3
  68. package/build/map/types/native-module.types.d.ts +363 -0
  69. package/build/map/types/native-module.types.js +5 -0
  70. package/build/map/types/offline.types.d.ts +132 -0
  71. package/build/map/types/offline.types.js +5 -0
  72. package/build/map/types/overlays.types.d.ts +137 -24
  73. package/build/map/utils/ErrorHandler.d.ts +110 -0
  74. package/build/map/utils/ErrorHandler.js +421 -0
  75. package/build/map/utils/GeoUtils.d.ts +20 -0
  76. package/build/map/utils/GeoUtils.js +76 -0
  77. package/build/map/utils/OfflineMapManager.d.ts +148 -0
  78. package/build/map/utils/OfflineMapManager.js +217 -0
  79. package/build/map/utils/PermissionUtils.d.ts +91 -0
  80. package/build/map/utils/PermissionUtils.js +255 -0
  81. package/build/map/utils/PlatformDetector.d.ts +102 -0
  82. package/build/map/utils/PlatformDetector.js +186 -0
  83. package/build/types/index.d.ts +1 -0
  84. package/build/types/index.js +1 -0
  85. package/build/types/native-module.types.d.ts +69 -0
  86. package/build/types/native-module.types.js +2 -0
  87. package/build/types/naviview.types.d.ts +1 -1
  88. package/expo-module.config.json +12 -10
  89. package/ios/ExpoGaodeMapNavigation.podspec +9 -0
  90. package/ios/map/ExpoGaodeMapModule.swift +485 -75
  91. package/ios/map/ExpoGaodeMapOfflineModule.swift +479 -0
  92. package/ios/map/ExpoGaodeMapView.swift +611 -62
  93. package/ios/map/ExpoGaodeMapViewModule.swift +48 -26
  94. package/ios/map/MapPreloadManager.swift +348 -0
  95. package/ios/map/cpp/ClusterEngine.cpp +110 -0
  96. package/ios/map/cpp/ClusterEngine.hpp +20 -0
  97. package/ios/map/cpp/ColorParser.cpp +135 -0
  98. package/ios/map/cpp/ColorParser.hpp +14 -0
  99. package/ios/map/cpp/GeometryEngine.cpp +574 -0
  100. package/ios/map/cpp/GeometryEngine.hpp +159 -0
  101. package/ios/map/cpp/QuadTree.cpp +92 -0
  102. package/ios/map/cpp/QuadTree.hpp +42 -0
  103. package/ios/map/cpp/README.md +55 -0
  104. package/ios/map/managers/UIManager.swift +72 -1
  105. package/ios/map/modules/LocationManager.swift +123 -166
  106. package/ios/map/overlays/CircleView.swift +16 -32
  107. package/ios/map/overlays/CircleViewModule.swift +12 -12
  108. package/ios/map/overlays/ClusterAnnotation.swift +32 -0
  109. package/ios/map/overlays/ClusterView.swift +331 -45
  110. package/ios/map/overlays/ClusterViewModule.swift +20 -6
  111. package/ios/map/overlays/HeatMapView.swift +135 -32
  112. package/ios/map/overlays/HeatMapViewModule.swift +20 -8
  113. package/ios/map/overlays/MarkerView.swift +613 -130
  114. package/ios/map/overlays/MarkerViewModule.swift +38 -18
  115. package/ios/map/overlays/MultiPointView.swift +168 -10
  116. package/ios/map/overlays/MultiPointViewModule.swift +27 -5
  117. package/ios/map/overlays/PolygonView.swift +62 -23
  118. package/ios/map/overlays/PolygonViewModule.swift +18 -12
  119. package/ios/map/overlays/PolylineView.swift +21 -13
  120. package/ios/map/overlays/PolylineViewModule.swift +18 -12
  121. package/ios/map/utils/ClusterNative.h +96 -0
  122. package/ios/map/utils/ClusterNative.mm +377 -0
  123. package/ios/map/utils/ColorParser.swift +12 -1
  124. package/ios/map/utils/CppBridging.mm +13 -0
  125. package/ios/map/utils/GeometryUtils.swift +34 -0
  126. package/ios/map/utils/LatLngParser.swift +87 -0
  127. package/ios/map/utils/PermissionManager.swift +135 -6
  128. package/package.json +3 -2
  129. package/shared/cpp/ClusterEngine.cpp +110 -0
  130. package/shared/cpp/ClusterEngine.hpp +20 -0
  131. package/shared/cpp/ColorParser.cpp +135 -0
  132. package/shared/cpp/ColorParser.hpp +14 -0
  133. package/shared/cpp/GeometryEngine.cpp +574 -0
  134. package/shared/cpp/GeometryEngine.hpp +159 -0
  135. package/shared/cpp/QuadTree.cpp +92 -0
  136. package/shared/cpp/QuadTree.hpp +42 -0
  137. package/shared/cpp/README.md +55 -0
  138. package/shared/cpp/tests/benchmark_js.js +41 -0
  139. package/shared/cpp/tests/run.sh +17 -0
  140. package/shared/cpp/tests/test_main.cpp +276 -0
  141. package/build/map/ExpoGaodeMap.types.d.ts +0 -41
  142. package/build/map/ExpoGaodeMap.types.js +0 -24
  143. package/build/map/utils/EventManager.d.ts +0 -10
  144. package/build/map/utils/EventManager.js +0 -26
  145. package/build/map/utils/ModuleLoader.d.ts +0 -73
  146. package/build/map/utils/ModuleLoader.js +0 -112
@@ -1,6 +1,8 @@
1
1
  import Foundation
2
2
  import AMapLocationKit
3
+ import AMapFoundationKit
3
4
  import CoreLocation
5
+ import ExpoModulesCore
4
6
 
5
7
  /**
6
8
  * 定位管理器
@@ -11,128 +13,87 @@ import CoreLocation
11
13
  * - 方向传感器管理
12
14
  * - 定位结果回调
13
15
  */
16
+
14
17
  class LocationManager: NSObject, AMapLocationManagerDelegate {
15
- /// 高德定位管理器实例
18
+
19
+ // 高德定位对象
16
20
  var locationManager: AMapLocationManager?
17
- /// 定位是否已启动
21
+
22
+ // 连续定位是否已开启
18
23
  private var isLocationStarted = false
19
- /// 定位更新回调
24
+
25
+ // 连续定位 event 回调(给 JS map listener 用)
20
26
  var onLocationUpdate: (([String: Any]) -> Void)?
21
- /// 方向更新回调
22
27
  var onHeadingUpdate: (([String: Any]) -> Void)?
23
-
28
+
24
29
  override init() {
25
30
  super.init()
26
31
  initLocationManager()
27
32
  }
28
-
29
- // MARK: - 定位控制
30
-
31
- /**
32
- * 开始连续定位
33
- */
33
+
34
+ // MARK: - 连续定位控制
35
+
34
36
  func start() {
35
37
  locationManager?.startUpdatingLocation()
36
38
  isLocationStarted = true
37
39
  }
38
-
39
- /**
40
- * 停止定位
41
- */
40
+
42
41
  func stop() {
43
42
  locationManager?.stopUpdatingLocation()
44
43
  isLocationStarted = false
45
44
  }
46
-
47
- /**
48
- * 检查定位是否已启动
49
- * @return 是否正在定位
50
- */
45
+
51
46
  func isStarted() -> Bool {
52
47
  return isLocationStarted
53
48
  }
54
-
55
- // MARK: - 定位配置
56
-
57
- /**
58
- * 设置是否返回逆地理信息
59
- * @param isReGeocode 是否返回逆地理信息
60
- */
49
+
50
+ // MARK: - 高德定位配置 API
51
+
61
52
  func setLocatingWithReGeocode(_ isReGeocode: Bool) {
62
53
  locationManager?.locatingWithReGeocode = isReGeocode
63
54
  }
64
-
65
- /**
66
- * 设置定位距离过滤器(米)
67
- * @param distance 最小距离变化才触发定位更新
68
- */
55
+
69
56
  func setDistanceFilter(_ distance: Double) {
70
57
  locationManager?.distanceFilter = distance
71
58
  }
72
-
73
- /**
74
- * 设置定位超时时间(秒)
75
- * @param timeout 超时时间
76
- */
59
+
77
60
  func setLocationTimeout(_ timeout: Int) {
78
61
  locationManager?.locationTimeout = timeout
79
62
  }
80
-
81
- /**
82
- * 设置逆地理超时时间(秒)
83
- * @param timeout 超时时间
84
- */
63
+
85
64
  func setReGeocodeTimeout(_ timeout: Int) {
86
65
  locationManager?.reGeocodeTimeout = timeout
87
66
  }
88
-
89
- /**
90
- * 设置定位精度
91
- * @param accuracy 精度级别
92
- * - 0: 最适合导航
93
- * - 1: 最佳精度
94
- * - 2: 10米精度
95
- * - 3: 100米精度
96
- * - 4: 1公里精度
97
- * - 5: 3公里精度
98
- */
67
+
99
68
  func setDesiredAccuracy(_ accuracy: Int) {
100
- let accuracyValue: CLLocationAccuracy
69
+ let value: CLLocationAccuracy
101
70
  switch accuracy {
102
- case 0: accuracyValue = kCLLocationAccuracyBestForNavigation
103
- case 1: accuracyValue = kCLLocationAccuracyBest
104
- case 2: accuracyValue = kCLLocationAccuracyNearestTenMeters
105
- case 3: accuracyValue = kCLLocationAccuracyHundredMeters
106
- case 4: accuracyValue = kCLLocationAccuracyKilometer
107
- case 5: accuracyValue = kCLLocationAccuracyThreeKilometers
108
- default: accuracyValue = kCLLocationAccuracyBest
71
+ case 0: value = kCLLocationAccuracyBestForNavigation
72
+ case 1: value = kCLLocationAccuracyBest
73
+ case 2: value = kCLLocationAccuracyNearestTenMeters
74
+ case 3: value = kCLLocationAccuracyHundredMeters
75
+ case 4: value = kCLLocationAccuracyKilometer
76
+ case 5: value = kCLLocationAccuracyThreeKilometers
77
+ default: value = kCLLocationAccuracyBest
109
78
  }
110
- locationManager?.desiredAccuracy = accuracyValue
79
+ locationManager?.desiredAccuracy = value
111
80
  }
112
-
113
- /**
114
- * 设置是否自动暂停定位更新
115
- * @param pauses 是否自动暂停
116
- */
81
+
117
82
  func setPausesLocationUpdatesAutomatically(_ pauses: Bool) {
118
83
  locationManager?.pausesLocationUpdatesAutomatically = pauses
119
84
  }
120
-
121
- /**
122
- * 设置是否允许后台定位
123
- * @param allows 是否允许后台定位
124
- */
85
+
125
86
  func setAllowsBackgroundLocationUpdates(_ allows: Bool) {
87
+ if allows {
88
+ let backgroundModes = Bundle.main.object(forInfoDictionaryKey: "UIBackgroundModes") as? [String]
89
+ if backgroundModes?.contains("location") != true {
90
+ log.warn("⚠️ [ExpoGaodeMap] iOS 后台定位未正确配置,setAllowsBackgroundLocationUpdates(true) 可能不会生效,请检查 Info.plist 是否包含 UIBackgroundModes: location,或者在 app.json 中配置 enableBackgroundLocation: true,然后重新执行 npx expo prebuild")
91
+ return
92
+ }
93
+ }
126
94
  locationManager?.allowsBackgroundLocationUpdates = allows
127
95
  }
128
-
129
- /**
130
- * 设置逆地理语言
131
- * @param language 语言类型
132
- * - 0: 默认
133
- * - 1: 中文
134
- * - 2: 英文
135
- */
96
+
136
97
  func setGeoLanguage(_ language: Int) {
137
98
  switch language {
138
99
  case 0: locationManager?.reGeocodeLanguage = .default
@@ -141,71 +102,41 @@ class LocationManager: NSObject, AMapLocationManagerDelegate {
141
102
  default: break
142
103
  }
143
104
  }
144
-
145
- // MARK: - 方向传感器
146
-
147
- /**
148
- * 开始更新设备方向
149
- */
105
+
106
+ // MARK: - 方向
107
+
150
108
  func startUpdatingHeading() {
151
109
  locationManager?.startUpdatingHeading()
152
110
  }
153
-
154
- /**
155
- * 停止更新设备方向
156
- */
111
+
157
112
  func stopUpdatingHeading() {
158
113
  locationManager?.stopUpdatingHeading()
159
114
  }
160
-
161
- // MARK: - 生命周期
162
-
163
- /**
164
- * 销毁定位管理器
165
- */
166
- func destroy() {
167
- locationManager?.stopUpdatingLocation()
168
- locationManager?.stopUpdatingHeading()
169
- locationManager?.delegate = nil
170
- locationManager = nil
171
- onLocationUpdate = nil
172
- onHeadingUpdate = nil
173
- }
174
-
175
- /**
176
- * 初始化定位管理器
177
- */
115
+
116
+ // MARK: - 初始化
117
+
178
118
  private func initLocationManager() {
179
119
  locationManager = AMapLocationManager()
180
120
  locationManager?.delegate = self
181
- // 推荐配置:百米精度,快速定位
121
+
122
+ // 默认配置
182
123
  locationManager?.desiredAccuracy = kCLLocationAccuracyHundredMeters
183
124
  locationManager?.distanceFilter = 10
184
- // 增加超时时间,避免首次授权时超时(首次定位建议10秒以上)
185
- locationManager?.locationTimeout = 10 // 10秒超时
186
- locationManager?.reGeocodeTimeout = 5 // 5秒超时
125
+ locationManager?.locationTimeout = 10
126
+ locationManager?.reGeocodeTimeout = 5
187
127
  locationManager?.locatingWithReGeocode = true
188
-
189
- // iOS 9 之前:防止后台被系统挂起(默认关闭,用户可通过 setPausesLocationUpdatesAutomatically 配置)
190
128
  locationManager?.pausesLocationUpdatesAutomatically = false
191
129
  }
192
-
193
- // MARK: - AMapLocationManagerDelegate
194
-
195
- /**
196
- * 定位更新回调
197
- * @param manager 定位管理器
198
- * @param location 位置信息
199
- * @param reGeocode 逆地理信息
200
- */
201
- func amapLocationManager(_ manager: AMapLocationManager!, didUpdate location: CLLocation!, reGeocode: AMapLocationReGeocode!) {
202
- // 🔑 坐标验证:防止无效坐标
203
- guard location.coordinate.latitude >= -90 && location.coordinate.latitude <= 90,
204
- location.coordinate.longitude >= -180 && location.coordinate.longitude <= 180 else {
205
- return
206
- }
207
-
208
- var locationData: [String: Any] = [
130
+
131
+ // MARK: - Delegate(连续定位回调)
132
+
133
+ func amapLocationManager(_ manager: AMapLocationManager!,
134
+ didUpdate location: CLLocation!,
135
+ reGeocode: AMapLocationReGeocode!) {
136
+
137
+ guard let location = location else { return }
138
+
139
+ var data: [String: Any] = [
209
140
  "latitude": location.coordinate.latitude,
210
141
  "longitude": location.coordinate.longitude,
211
142
  "accuracy": location.horizontalAccuracy,
@@ -214,28 +145,23 @@ class LocationManager: NSObject, AMapLocationManagerDelegate {
214
145
  "speed": location.speed,
215
146
  "timestamp": location.timestamp.timeIntervalSince1970 * 1000
216
147
  ]
217
-
218
- // 添加逆地理信息
219
- if let reGeocode = reGeocode {
220
- locationData["address"] = reGeocode.formattedAddress
221
- locationData["province"] = reGeocode.province
222
- locationData["city"] = reGeocode.city
223
- locationData["district"] = reGeocode.district
224
- locationData["street"] = reGeocode.street
225
- locationData["streetNumber"] = reGeocode.number
226
- locationData["country"] = reGeocode.country
227
- locationData["cityCode"] = reGeocode.citycode
228
- locationData["adCode"] = reGeocode.adcode
148
+
149
+ if let geo = reGeocode {
150
+ data["address"] = geo.formattedAddress
151
+ data["province"] = geo.province
152
+ data["city"] = geo.city
153
+ data["district"] = geo.district
154
+ data["street"] = geo.street
155
+ data["streetNumber"] = geo.number
156
+ data["country"] = geo.country
157
+ data["cityCode"] = geo.citycode
158
+ data["adCode"] = geo.adcode
229
159
  }
230
-
231
- onLocationUpdate?(locationData)
160
+
161
+ // 触发连续定位回调
162
+ onLocationUpdate?(data)
232
163
  }
233
-
234
- /**
235
- * 方向更新回调
236
- * @param manager 定位管理器
237
- * @param heading 方向信息
238
- */
164
+
239
165
  func amapLocationManager(_ manager: AMapLocationManager!, didUpdate heading: CLHeading!) {
240
166
  let headingData: [String: Any] = [
241
167
  "heading": heading.trueHeading,
@@ -244,22 +170,53 @@ class LocationManager: NSObject, AMapLocationManagerDelegate {
244
170
  ]
245
171
  onHeadingUpdate?(headingData)
246
172
  }
247
-
248
- /**
249
- * 需要定位权限回调
250
- * @param manager 定位管理器
251
- * @param locationManager 系统定位管理器
252
- */
253
- func amapLocationManager(_ manager: AMapLocationManager!, doRequireLocationAuth locationManager: CLLocationManager!) {
254
- locationManager.requestAlwaysAuthorization()
173
+
174
+ func amapLocationManager(_ manager: AMapLocationManager!, didFailWithError error: Error!) {
175
+ // 定位失败 - 静默处理(连续定位会自动重试)
255
176
  }
256
-
177
+
178
+ // MARK: - 工具方法
179
+
257
180
  /**
258
- * 定位失败回调
259
- * @param manager 定位管理器
260
- * @param error 错误信息
181
+ * 坐标转换
182
+ * @param coordinate 原始坐标
183
+ * @param type 坐标类型 (0: GPS/Google, 1: MapBar, 2: Baidu, 3: MapABC/SoSo)
184
+ * @param promise Promise
261
185
  */
262
- func amapLocationManager(_ manager: AMapLocationManager!, didFailWithError error: Error!) {
263
- // 定位失败 - 静默处理
186
+ func coordinateConvert(_ coordinate: [String: Double], type: Int, promise: Promise) {
187
+ guard let lat = coordinate["latitude"],
188
+ let lon = coordinate["longitude"] else {
189
+ promise.reject("INVALID_ARGUMENT", "Invalid coordinate")
190
+ return
191
+ }
192
+
193
+ let coord = CLLocationCoordinate2D(latitude: lat, longitude: lon)
194
+ var amapType: AMapCoordinateType
195
+
196
+ // 根据文档映射
197
+ switch type {
198
+ case 0: amapType = AMapCoordinateType.GPS
199
+ case 1: amapType = AMapCoordinateType.mapBar
200
+ case 2: amapType = AMapCoordinateType.baidu
201
+ case 3: amapType = AMapCoordinateType.mapABC
202
+ default: amapType = AMapCoordinateType.GPS
203
+ }
204
+
205
+ let converted = AMapCoordinateConvert(coord, amapType)
206
+
207
+ promise.resolve([
208
+ "latitude": converted.latitude,
209
+ "longitude": converted.longitude
210
+ ])
211
+ }
212
+
213
+ // MARK: - 销毁
214
+ func destroy() {
215
+ locationManager?.stopUpdatingLocation()
216
+ locationManager?.stopUpdatingHeading()
217
+ locationManager?.delegate = nil
218
+ locationManager = nil
219
+ onLocationUpdate = nil
220
+ onHeadingUpdate = nil
264
221
  }
265
- }
222
+ }
@@ -1,5 +1,7 @@
1
1
  import ExpoModulesCore
2
2
  import AMapNaviKit
3
+ import CoreLocation
4
+
3
5
 
4
6
  /**
5
7
  * 圆形覆盖物视图
@@ -9,18 +11,18 @@ import AMapNaviKit
9
11
  * - 管理圆形的样式(填充色、边框色、边框宽度)
10
12
  * - 响应属性变化并更新渲染
11
13
  */
12
- class NaviCircleView: ExpoView {
14
+ class CircleView: ExpoView {
13
15
  /// 事件派发器 - 使用 onCirclePress 避免与 MarkerPress 冲突
14
16
  let onCirclePress = EventDispatcher()
15
17
 
16
18
  /// 圆心坐标
17
- var circleCenter: [String: Double] = [:]
19
+ var circleCenter: [String: Double]?
18
20
  /// 半径(米)
19
21
  var radius: Double = 0
20
22
  /// 填充颜色
21
- var fillColor: Any?
23
+ var fillColor: String?
22
24
  /// 边框颜色
23
- var strokeColor: Any?
25
+ var strokeColor: String?
24
26
  /// 边框宽度
25
27
  var strokeWidth: Float = 0
26
28
  /// z-index 图层顺序
@@ -89,34 +91,17 @@ class NaviCircleView: ExpoView {
89
91
  return
90
92
  }
91
93
 
92
- guard let latitude = circleCenter["latitude"],
93
- let longitude = circleCenter["longitude"],
94
+ guard let center = LatLngParser.parseLatLng(circleCenter),
94
95
  radius > 0 else {
95
96
  return
96
97
  }
97
98
 
98
- // 🔑 坐标验证:防止无效坐标导致崩溃
99
- guard latitude >= -90 && latitude <= 90,
100
- longitude >= -180 && longitude <= 180 else {
101
- return
99
+ if let old = circle {
100
+ mapView.remove(old)
102
101
  }
103
102
 
104
- // 🔑 半径验证:防止负数或过大的半径
105
- let validRadius = max(0.1, min(radius, 1000000))
106
-
107
- if circle == nil {
108
- let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
109
- circle = MACircle(center: coordinate, radius: validRadius)
110
- mapView.add(circle!)
111
- } else {
112
- // 先移除旧的
113
- mapView.remove(circle!)
114
- // 更新属性
115
- circle?.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
116
- circle?.radius = validRadius
117
- // 重新添加
118
- mapView.add(circle!)
119
- }
103
+ circle = MACircle(center: center, radius: radius)
104
+ mapView.add(circle!)
120
105
 
121
106
  renderer = nil
122
107
  }
@@ -142,11 +127,10 @@ class NaviCircleView: ExpoView {
142
127
  }
143
128
 
144
129
  /**
145
- * 设置中心点
146
- * @param center 中心点坐标 {latitude, longitude}
130
+ * 设置圆心
147
131
  */
148
- func setCenter(_ center: [String: Double]) {
149
- circleCenter = center
132
+ func setCenter(_ center: [String: Double]?) {
133
+ self.circleCenter = center
150
134
  updateCircle()
151
135
  }
152
136
 
@@ -163,7 +147,7 @@ class NaviCircleView: ExpoView {
163
147
  * 设置填充颜色
164
148
  * @param color 颜色值
165
149
  */
166
- func setFillColor(_ color: Any?) {
150
+ func setFillColor(_ color: String?) {
167
151
  fillColor = color
168
152
  renderer = nil
169
153
  updateCircle()
@@ -173,7 +157,7 @@ class NaviCircleView: ExpoView {
173
157
  * 设置边框颜色
174
158
  * @param color 颜色值
175
159
  */
176
- func setStrokeColor(_ color: Any?) {
160
+ func setStrokeColor(_ color: String?) {
177
161
  strokeColor = color
178
162
  renderer = nil
179
163
  updateCircle()
@@ -1,43 +1,43 @@
1
1
  import ExpoModulesCore
2
2
 
3
- public class NaviCircleViewModule: Module {
3
+ public class CircleViewModule: Module {
4
4
  public func definition() -> ModuleDefinition {
5
- Name("NaviCircleView")
5
+ Name("CircleView")
6
6
 
7
- View(NaviCircleView.self) {
7
+ View(CircleView.self) {
8
8
  Events("onCirclePress")
9
9
 
10
- Prop("center") { (view: NaviCircleView, center: [String: Double]) in
10
+ Prop("center") { (view: CircleView, center: [String: Double]?) in
11
11
  view.setCenter(center)
12
12
  }
13
13
 
14
- Prop("radius") { (view: NaviCircleView, radius: Double) in
14
+ Prop("radius") { (view: CircleView, radius: Double) in
15
15
  view.setRadius(radius)
16
16
  }
17
17
 
18
- Prop("fillColor") { (view: NaviCircleView, color: String) in
18
+ Prop("fillColor") { (view: CircleView, color: String?) in
19
19
  view.setFillColor(color)
20
20
  }
21
21
 
22
- Prop("strokeColor") { (view: NaviCircleView, color: String) in
22
+ Prop("strokeColor") { (view: CircleView, color: String?) in
23
23
  view.setStrokeColor(color)
24
24
  }
25
25
 
26
- Prop("strokeWidth") { (view: NaviCircleView, width: Double) in
26
+ Prop("strokeWidth") { (view: CircleView, width: Double) in
27
27
  view.setStrokeWidth(Float(width))
28
28
  }
29
29
 
30
- Prop("zIndex") { (view: NaviCircleView, zIndex: Double) in
30
+ Prop("zIndex") { (view: CircleView, zIndex: Double) in
31
31
  view.setZIndex(zIndex)
32
32
  }
33
33
 
34
- OnViewDidUpdateProps { (view: NaviCircleView) in
34
+ OnViewDidUpdateProps { (view: CircleView) in
35
35
  // 属性更新完成后,如果还没连接地图,尝试连接
36
36
  if !view.isMapConnected() {
37
- // 查找父视图 NaviMapView
37
+ // 查找父视图 ExpoGaodeMapView
38
38
  var parent = view.superview
39
39
  while parent != nil {
40
- if let mapView = parent as? NaviMapView {
40
+ if let mapView = parent as? ExpoGaodeMapView {
41
41
  view.setMap(mapView.mapView)
42
42
  return
43
43
  }
@@ -0,0 +1,32 @@
1
+ import Foundation
2
+ import CoreLocation
3
+ import AMapNaviKit
4
+
5
+ class ClusterAnnotation: NSObject, MAAnnotation {
6
+ @objc dynamic var coordinate: CLLocationCoordinate2D
7
+ var count: Int
8
+ var pois: [[String: Any]]
9
+
10
+ // MAAnnotation required properties
11
+ var title: String?
12
+ var subtitle: String?
13
+
14
+ init(coordinate: CLLocationCoordinate2D, count: Int, pois: [[String: Any]]) {
15
+ self.coordinate = coordinate
16
+ self.count = count
17
+ self.pois = pois
18
+ self.title = "\(count)个点"
19
+ super.init()
20
+ }
21
+
22
+ override func isEqual(_ object: Any?) -> Bool {
23
+ guard let other = object as? ClusterAnnotation else { return false }
24
+ return self.coordinate.latitude == other.coordinate.latitude &&
25
+ self.coordinate.longitude == other.coordinate.longitude &&
26
+ self.count == other.count
27
+ }
28
+
29
+ override var hash: Int {
30
+ return "\(coordinate.latitude),\(coordinate.longitude),\(count)".hashValue
31
+ }
32
+ }