expo-gaode-map-navigation 1.1.5-next.1 → 1.1.5-next.3
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/android/build.gradle +10 -0
- package/android/src/main/cpp/CMakeLists.txt +24 -0
- package/android/src/main/cpp/cluster_jni.cpp +848 -0
- package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapModule.kt +616 -92
- package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapOfflineModule.kt +493 -0
- package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapView.kt +230 -14
- package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapViewModule.kt +37 -27
- package/android/src/main/java/expo/modules/gaodemap/map/MapPreloadManager.kt +494 -0
- package/android/src/main/java/expo/modules/gaodemap/map/companion/BitmapDescriptorCache.kt +30 -0
- package/android/src/main/java/expo/modules/gaodemap/map/companion/IconBitmapCache.kt +37 -0
- package/android/src/main/java/expo/modules/gaodemap/map/managers/UIManager.kt +76 -0
- package/android/src/main/java/expo/modules/gaodemap/map/modules/LocationManager.kt +15 -3
- package/android/src/main/java/expo/modules/gaodemap/map/modules/SDKInitializer.kt +4 -59
- package/android/src/main/java/expo/modules/gaodemap/map/overlays/CircleView.kt +9 -12
- package/android/src/main/java/expo/modules/gaodemap/map/overlays/CircleViewModule.kt +5 -6
- package/android/src/main/java/expo/modules/gaodemap/map/overlays/ClusterView.kt +539 -66
- package/android/src/main/java/expo/modules/gaodemap/map/overlays/ClusterViewModule.kt +17 -1
- package/android/src/main/java/expo/modules/gaodemap/map/overlays/HeatMapView.kt +165 -33
- package/android/src/main/java/expo/modules/gaodemap/map/overlays/HeatMapViewModule.kt +15 -3
- package/android/src/main/java/expo/modules/gaodemap/map/overlays/MarkerView.kt +1249 -672
- package/android/src/main/java/expo/modules/gaodemap/map/overlays/MarkerViewModule.kt +40 -17
- package/android/src/main/java/expo/modules/gaodemap/map/overlays/MultiPointView.kt +177 -22
- package/android/src/main/java/expo/modules/gaodemap/map/overlays/MultiPointViewModule.kt +11 -3
- package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolygonView.kt +57 -14
- package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolygonViewModule.kt +9 -5
- package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolylineView.kt +90 -63
- package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolylineViewModule.kt +7 -3
- package/android/src/main/java/expo/modules/gaodemap/map/services/LocationForegroundService.kt +3 -2
- package/android/src/main/java/expo/modules/gaodemap/map/utils/BitmapDescriptorCache.kt +20 -0
- package/android/src/main/java/expo/modules/gaodemap/map/utils/ClusterNative.kt +13 -0
- package/android/src/main/java/expo/modules/gaodemap/map/utils/ColorParser.kt +20 -0
- package/android/src/main/java/expo/modules/gaodemap/map/utils/GeometryUtils.kt +515 -0
- package/android/src/main/java/expo/modules/gaodemap/map/utils/LatLngParser.kt +91 -0
- package/android/src/main/java/expo/modules/gaodemap/map/utils/PermissionHelper.kt +248 -0
- package/build/ExpoGaodeMapNaviView.d.ts +7 -7
- package/build/ExpoGaodeMapNaviView.js +8 -8
- package/build/ExpoGaodeMapNavigationModule.d.ts +2 -1
- package/build/index.d.ts +35 -33
- package/build/index.js +70 -106
- package/build/map/ExpoGaodeMapModule.d.ts +2 -201
- package/build/map/ExpoGaodeMapModule.js +584 -14
- package/build/map/ExpoGaodeMapOfflineModule.d.ts +139 -0
- package/build/map/ExpoGaodeMapOfflineModule.js +8 -0
- package/build/map/ExpoGaodeMapView.js +66 -58
- package/build/map/components/FoldableMapView.d.ts +38 -0
- package/build/map/components/FoldableMapView.js +209 -0
- package/build/map/components/MapContext.d.ts +12 -0
- package/build/map/components/MapContext.js +54 -0
- package/build/map/components/MapUI.d.ts +18 -0
- package/build/map/components/MapUI.js +29 -0
- package/build/map/components/overlays/Circle.js +34 -3
- package/build/map/components/overlays/Cluster.d.ts +3 -1
- package/build/map/components/overlays/Cluster.js +31 -2
- package/build/map/components/overlays/HeatMap.d.ts +3 -1
- package/build/map/components/overlays/HeatMap.js +33 -3
- package/build/map/components/overlays/Marker.d.ts +1 -1
- package/build/map/components/overlays/Marker.js +37 -32
- package/build/map/components/overlays/MultiPoint.js +1 -1
- package/build/map/components/overlays/Polygon.js +30 -3
- package/build/map/components/overlays/Polyline.js +36 -3
- package/build/map/index.d.ts +25 -5
- package/build/map/index.js +59 -18
- package/build/map/types/common.types.d.ts +40 -0
- package/build/map/types/common.types.js +0 -4
- package/build/map/types/index.d.ts +3 -2
- package/build/map/types/map-view.types.d.ts +108 -3
- package/build/map/types/native-module.types.d.ts +363 -0
- package/build/map/types/native-module.types.js +5 -0
- package/build/map/types/offline.types.d.ts +132 -0
- package/build/map/types/offline.types.js +5 -0
- package/build/map/types/overlays.types.d.ts +137 -24
- package/build/map/utils/ErrorHandler.d.ts +110 -0
- package/build/map/utils/ErrorHandler.js +421 -0
- package/build/map/utils/GeoUtils.d.ts +20 -0
- package/build/map/utils/GeoUtils.js +76 -0
- package/build/map/utils/OfflineMapManager.d.ts +148 -0
- package/build/map/utils/OfflineMapManager.js +217 -0
- package/build/map/utils/PermissionUtils.d.ts +91 -0
- package/build/map/utils/PermissionUtils.js +255 -0
- package/build/map/utils/PlatformDetector.d.ts +102 -0
- package/build/map/utils/PlatformDetector.js +186 -0
- package/build/types/index.d.ts +1 -0
- package/build/types/index.js +1 -0
- package/build/types/native-module.types.d.ts +69 -0
- package/build/types/native-module.types.js +2 -0
- package/build/types/naviview.types.d.ts +1 -1
- package/expo-module.config.json +12 -10
- package/ios/ExpoGaodeMapNavigation.podspec +9 -0
- package/ios/map/ExpoGaodeMapModule.swift +485 -75
- package/ios/map/ExpoGaodeMapOfflineModule.swift +479 -0
- package/ios/map/ExpoGaodeMapView.swift +611 -62
- package/ios/map/ExpoGaodeMapViewModule.swift +48 -26
- package/ios/map/MapPreloadManager.swift +348 -0
- package/ios/map/cpp/ClusterEngine.cpp +110 -0
- package/ios/map/cpp/ClusterEngine.hpp +20 -0
- package/ios/map/cpp/ColorParser.cpp +135 -0
- package/ios/map/cpp/ColorParser.hpp +14 -0
- package/ios/map/cpp/GeometryEngine.cpp +574 -0
- package/ios/map/cpp/GeometryEngine.hpp +159 -0
- package/ios/map/cpp/QuadTree.cpp +92 -0
- package/ios/map/cpp/QuadTree.hpp +42 -0
- package/ios/map/cpp/README.md +55 -0
- package/ios/map/cpp/tests/benchmark_js.js +41 -0
- package/ios/map/cpp/tests/run.sh +17 -0
- package/ios/map/cpp/tests/test_main.cpp +276 -0
- package/ios/map/managers/UIManager.swift +72 -1
- package/ios/map/modules/LocationManager.swift +114 -165
- package/ios/map/overlays/CircleView.swift +16 -32
- package/ios/map/overlays/CircleViewModule.swift +12 -12
- package/ios/map/overlays/ClusterAnnotation.swift +32 -0
- package/ios/map/overlays/ClusterView.swift +331 -45
- package/ios/map/overlays/ClusterViewModule.swift +20 -6
- package/ios/map/overlays/HeatMapView.swift +135 -32
- package/ios/map/overlays/HeatMapViewModule.swift +20 -8
- package/ios/map/overlays/MarkerView.swift +613 -130
- package/ios/map/overlays/MarkerViewModule.swift +38 -18
- package/ios/map/overlays/MultiPointView.swift +168 -10
- package/ios/map/overlays/MultiPointViewModule.swift +27 -5
- package/ios/map/overlays/PolygonView.swift +62 -23
- package/ios/map/overlays/PolygonViewModule.swift +18 -12
- package/ios/map/overlays/PolylineView.swift +21 -13
- package/ios/map/overlays/PolylineViewModule.swift +18 -12
- package/ios/map/utils/ClusterNative.h +96 -0
- package/ios/map/utils/ClusterNative.mm +377 -0
- package/ios/map/utils/ColorParser.swift +12 -1
- package/ios/map/utils/CppBridging.mm +13 -0
- package/ios/map/utils/GeometryUtils.swift +34 -0
- package/ios/map/utils/LatLngParser.swift +87 -0
- package/ios/map/utils/PermissionManager.swift +135 -6
- package/package.json +1 -1
- package/build/map/ExpoGaodeMap.types.d.ts +0 -41
- package/build/map/ExpoGaodeMap.types.js +0 -24
- package/build/map/utils/EventManager.d.ts +0 -10
- package/build/map/utils/EventManager.js +0 -26
- package/build/map/utils/ModuleLoader.d.ts +0 -73
- package/build/map/utils/ModuleLoader.js +0 -112
|
@@ -17,6 +17,9 @@ class UIManager: NSObject, MAMapViewDelegate {
|
|
|
17
17
|
/// 定位变化回调
|
|
18
18
|
var onLocationChanged: ((_ latitude: Double, _ longitude: Double, _ accuracy: Double) -> Void)?
|
|
19
19
|
|
|
20
|
+
/// 缓存的自定义样式配置
|
|
21
|
+
private var cachedCustomStyleOptions: MAMapCustomStyleOptions?
|
|
22
|
+
|
|
20
23
|
init(mapView: MAMapView) {
|
|
21
24
|
self.mapView = mapView
|
|
22
25
|
super.init()
|
|
@@ -36,6 +39,13 @@ class UIManager: NSObject, MAMapViewDelegate {
|
|
|
36
39
|
case 3: mapView.mapType = .navi
|
|
37
40
|
default: mapView.mapType = .standard
|
|
38
41
|
}
|
|
42
|
+
|
|
43
|
+
// 🔑 关键修复:切换地图类型后重新应用自定义样式
|
|
44
|
+
// 某些地图类型切换可能会重置样式设置
|
|
45
|
+
if let cachedOptions = cachedCustomStyleOptions {
|
|
46
|
+
mapView.setCustomMapStyleOptions(cachedOptions)
|
|
47
|
+
mapView.customMapStyleEnabled = true
|
|
48
|
+
}
|
|
39
49
|
}
|
|
40
50
|
|
|
41
51
|
// MARK: - 控件显示
|
|
@@ -109,7 +119,8 @@ class UIManager: NSObject, MAMapViewDelegate {
|
|
|
109
119
|
}
|
|
110
120
|
mapView.showsUserLocation = true
|
|
111
121
|
if followUser {
|
|
112
|
-
|
|
122
|
+
// 🔑 使用 followWithHeading 模式以支持方向指示器
|
|
123
|
+
mapView.userTrackingMode = .followWithHeading
|
|
113
124
|
} else {
|
|
114
125
|
mapView.userTrackingMode = .none
|
|
115
126
|
}
|
|
@@ -146,6 +157,12 @@ class UIManager: NSObject, MAMapViewDelegate {
|
|
|
146
157
|
guard let mapView = mapView else { return }
|
|
147
158
|
let representation = MAUserLocationRepresentation()
|
|
148
159
|
|
|
160
|
+
// 是否显示定位蓝点 (showMyLocation) - 对应 Android 的 showMyLocation
|
|
161
|
+
// iOS 通过 mapView.showsUserLocation 控制,这里提供统一的 API
|
|
162
|
+
if let showMyLocation = config["showMyLocation"] as? Bool {
|
|
163
|
+
mapView.showsUserLocation = showMyLocation
|
|
164
|
+
}
|
|
165
|
+
|
|
149
166
|
// 精度圈是否显示
|
|
150
167
|
if let showsAccuracyRing = config["showsAccuracyRing"] as? Bool {
|
|
151
168
|
representation.showsAccuracyRing = showsAccuracyRing
|
|
@@ -265,4 +282,58 @@ class UIManager: NSObject, MAMapViewDelegate {
|
|
|
265
282
|
func setShowsIndoorMap(_ show: Bool) {
|
|
266
283
|
mapView?.isShowsIndoorMap = show
|
|
267
284
|
}
|
|
285
|
+
|
|
286
|
+
// MARK: - 自定义地图样式
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* 设置自定义地图样式
|
|
290
|
+
* @param styleData 样式数据,支持以下格式:
|
|
291
|
+
* - styleId: String - 在线样式ID(从高德开放平台获取)
|
|
292
|
+
* - styleDataPath: String - 本地样式文件路径
|
|
293
|
+
* - extraStyleDataPath: String - 额外样式文件路径(可选)
|
|
294
|
+
*/
|
|
295
|
+
func setCustomMapStyle(_ styleData: [String: Any]) {
|
|
296
|
+
guard let mapView = mapView else { return }
|
|
297
|
+
|
|
298
|
+
// 在线样式 ID
|
|
299
|
+
if let styleId = styleData["styleId"] as? String, !styleId.isEmpty {
|
|
300
|
+
let customStyle = MAMapCustomStyleOptions()
|
|
301
|
+
customStyle.styleId = styleId
|
|
302
|
+
|
|
303
|
+
// 🔑 缓存样式配置
|
|
304
|
+
cachedCustomStyleOptions = customStyle
|
|
305
|
+
|
|
306
|
+
mapView.setCustomMapStyleOptions(customStyle)
|
|
307
|
+
mapView.customMapStyleEnabled = true
|
|
308
|
+
return
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// 本地样式文件
|
|
312
|
+
if let styleDataPath = styleData["styleDataPath"] as? String, !styleDataPath.isEmpty {
|
|
313
|
+
// 读取样式文件数据
|
|
314
|
+
if let stylePath = Bundle.main.path(forResource: styleDataPath, ofType: nil),
|
|
315
|
+
let styleFileData = try? Data(contentsOf: URL(fileURLWithPath: stylePath)) {
|
|
316
|
+
let customStyle = MAMapCustomStyleOptions()
|
|
317
|
+
customStyle.styleData = styleFileData
|
|
318
|
+
|
|
319
|
+
// 额外样式文件(可选)
|
|
320
|
+
if let extraPath = styleData["extraStyleDataPath"] as? String, !extraPath.isEmpty,
|
|
321
|
+
let extraFilePath = Bundle.main.path(forResource: extraPath, ofType: nil),
|
|
322
|
+
let extraFileData = try? Data(contentsOf: URL(fileURLWithPath: extraFilePath)) {
|
|
323
|
+
customStyle.styleExtraData = extraFileData
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// 🔑 缓存样式配置
|
|
327
|
+
cachedCustomStyleOptions = customStyle
|
|
328
|
+
|
|
329
|
+
mapView.setCustomMapStyleOptions(customStyle)
|
|
330
|
+
mapView.customMapStyleEnabled = true
|
|
331
|
+
return
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// 如果没有提供任何样式,禁用自定义样式并清除缓存
|
|
336
|
+
cachedCustomStyleOptions = nil
|
|
337
|
+
mapView.customMapStyleEnabled = false
|
|
338
|
+
}
|
|
268
339
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
import AMapLocationKit
|
|
3
|
+
import AMapFoundationKit
|
|
3
4
|
import CoreLocation
|
|
4
5
|
import ExpoModulesCore
|
|
5
6
|
|
|
@@ -12,117 +13,76 @@ import ExpoModulesCore
|
|
|
12
13
|
* - 方向传感器管理
|
|
13
14
|
* - 定位结果回调
|
|
14
15
|
*/
|
|
16
|
+
|
|
15
17
|
class LocationManager: NSObject, AMapLocationManagerDelegate {
|
|
16
|
-
|
|
18
|
+
|
|
19
|
+
// 高德定位对象
|
|
17
20
|
var locationManager: AMapLocationManager?
|
|
18
|
-
|
|
21
|
+
|
|
22
|
+
// 连续定位是否已开启
|
|
19
23
|
private var isLocationStarted = false
|
|
20
|
-
|
|
24
|
+
|
|
25
|
+
// 连续定位 event 回调(给 JS map listener 用)
|
|
21
26
|
var onLocationUpdate: (([String: Any]) -> Void)?
|
|
22
|
-
/// 方向更新回调
|
|
23
27
|
var onHeadingUpdate: (([String: Any]) -> Void)?
|
|
24
|
-
|
|
28
|
+
|
|
25
29
|
override init() {
|
|
26
30
|
super.init()
|
|
27
31
|
initLocationManager()
|
|
28
32
|
}
|
|
29
|
-
|
|
30
|
-
// MARK: -
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* 开始连续定位
|
|
34
|
-
*/
|
|
33
|
+
|
|
34
|
+
// MARK: - 连续定位控制
|
|
35
|
+
|
|
35
36
|
func start() {
|
|
36
37
|
locationManager?.startUpdatingLocation()
|
|
37
38
|
isLocationStarted = true
|
|
38
39
|
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* 停止定位
|
|
42
|
-
*/
|
|
40
|
+
|
|
43
41
|
func stop() {
|
|
44
42
|
locationManager?.stopUpdatingLocation()
|
|
45
43
|
isLocationStarted = false
|
|
46
44
|
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* 检查定位是否已启动
|
|
50
|
-
* @return 是否正在定位
|
|
51
|
-
*/
|
|
45
|
+
|
|
52
46
|
func isStarted() -> Bool {
|
|
53
47
|
return isLocationStarted
|
|
54
48
|
}
|
|
55
|
-
|
|
56
|
-
// MARK: -
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* 设置是否返回逆地理信息
|
|
60
|
-
* @param isReGeocode 是否返回逆地理信息
|
|
61
|
-
*/
|
|
49
|
+
|
|
50
|
+
// MARK: - 高德定位配置 API
|
|
51
|
+
|
|
62
52
|
func setLocatingWithReGeocode(_ isReGeocode: Bool) {
|
|
63
53
|
locationManager?.locatingWithReGeocode = isReGeocode
|
|
64
54
|
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* 设置定位距离过滤器(米)
|
|
68
|
-
* @param distance 最小距离变化才触发定位更新
|
|
69
|
-
*/
|
|
55
|
+
|
|
70
56
|
func setDistanceFilter(_ distance: Double) {
|
|
71
57
|
locationManager?.distanceFilter = distance
|
|
72
58
|
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* 设置定位超时时间(秒)
|
|
76
|
-
* @param timeout 超时时间
|
|
77
|
-
*/
|
|
59
|
+
|
|
78
60
|
func setLocationTimeout(_ timeout: Int) {
|
|
79
61
|
locationManager?.locationTimeout = timeout
|
|
80
62
|
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* 设置逆地理超时时间(秒)
|
|
84
|
-
* @param timeout 超时时间
|
|
85
|
-
*/
|
|
63
|
+
|
|
86
64
|
func setReGeocodeTimeout(_ timeout: Int) {
|
|
87
65
|
locationManager?.reGeocodeTimeout = timeout
|
|
88
66
|
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* 设置定位精度
|
|
92
|
-
* @param accuracy 精度级别
|
|
93
|
-
* - 0: 最适合导航
|
|
94
|
-
* - 1: 最佳精度
|
|
95
|
-
* - 2: 10米精度
|
|
96
|
-
* - 3: 100米精度
|
|
97
|
-
* - 4: 1公里精度
|
|
98
|
-
* - 5: 3公里精度
|
|
99
|
-
*/
|
|
67
|
+
|
|
100
68
|
func setDesiredAccuracy(_ accuracy: Int) {
|
|
101
|
-
let
|
|
69
|
+
let value: CLLocationAccuracy
|
|
102
70
|
switch accuracy {
|
|
103
|
-
case 0:
|
|
104
|
-
case 1:
|
|
105
|
-
case 2:
|
|
106
|
-
case 3:
|
|
107
|
-
case 4:
|
|
108
|
-
case 5:
|
|
109
|
-
default:
|
|
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
|
|
110
78
|
}
|
|
111
|
-
locationManager?.desiredAccuracy =
|
|
79
|
+
locationManager?.desiredAccuracy = value
|
|
112
80
|
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* 设置是否自动暂停定位更新
|
|
116
|
-
* @param pauses 是否自动暂停
|
|
117
|
-
*/
|
|
81
|
+
|
|
118
82
|
func setPausesLocationUpdatesAutomatically(_ pauses: Bool) {
|
|
119
83
|
locationManager?.pausesLocationUpdatesAutomatically = pauses
|
|
120
84
|
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* 设置是否允许后台定位
|
|
124
|
-
* @param allows 是否允许后台定位
|
|
125
|
-
*/
|
|
85
|
+
|
|
126
86
|
func setAllowsBackgroundLocationUpdates(_ allows: Bool) {
|
|
127
87
|
if allows {
|
|
128
88
|
let backgroundModes = Bundle.main.object(forInfoDictionaryKey: "UIBackgroundModes") as? [String]
|
|
@@ -133,14 +93,7 @@ class LocationManager: NSObject, AMapLocationManagerDelegate {
|
|
|
133
93
|
}
|
|
134
94
|
locationManager?.allowsBackgroundLocationUpdates = allows
|
|
135
95
|
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* 设置逆地理语言
|
|
139
|
-
* @param language 语言类型
|
|
140
|
-
* - 0: 默认
|
|
141
|
-
* - 1: 中文
|
|
142
|
-
* - 2: 英文
|
|
143
|
-
*/
|
|
96
|
+
|
|
144
97
|
func setGeoLanguage(_ language: Int) {
|
|
145
98
|
switch language {
|
|
146
99
|
case 0: locationManager?.reGeocodeLanguage = .default
|
|
@@ -149,71 +102,41 @@ class LocationManager: NSObject, AMapLocationManagerDelegate {
|
|
|
149
102
|
default: break
|
|
150
103
|
}
|
|
151
104
|
}
|
|
152
|
-
|
|
153
|
-
// MARK: -
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* 开始更新设备方向
|
|
157
|
-
*/
|
|
105
|
+
|
|
106
|
+
// MARK: - 方向
|
|
107
|
+
|
|
158
108
|
func startUpdatingHeading() {
|
|
159
109
|
locationManager?.startUpdatingHeading()
|
|
160
110
|
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* 停止更新设备方向
|
|
164
|
-
*/
|
|
111
|
+
|
|
165
112
|
func stopUpdatingHeading() {
|
|
166
113
|
locationManager?.stopUpdatingHeading()
|
|
167
114
|
}
|
|
168
|
-
|
|
169
|
-
// MARK: -
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* 销毁定位管理器
|
|
173
|
-
*/
|
|
174
|
-
func destroy() {
|
|
175
|
-
locationManager?.stopUpdatingLocation()
|
|
176
|
-
locationManager?.stopUpdatingHeading()
|
|
177
|
-
locationManager?.delegate = nil
|
|
178
|
-
locationManager = nil
|
|
179
|
-
onLocationUpdate = nil
|
|
180
|
-
onHeadingUpdate = nil
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* 初始化定位管理器
|
|
185
|
-
*/
|
|
115
|
+
|
|
116
|
+
// MARK: - 初始化
|
|
117
|
+
|
|
186
118
|
private func initLocationManager() {
|
|
187
119
|
locationManager = AMapLocationManager()
|
|
188
120
|
locationManager?.delegate = self
|
|
189
|
-
|
|
121
|
+
|
|
122
|
+
// 默认配置
|
|
190
123
|
locationManager?.desiredAccuracy = kCLLocationAccuracyHundredMeters
|
|
191
124
|
locationManager?.distanceFilter = 10
|
|
192
|
-
|
|
193
|
-
locationManager?.
|
|
194
|
-
locationManager?.reGeocodeTimeout = 5 // 5秒超时
|
|
125
|
+
locationManager?.locationTimeout = 10
|
|
126
|
+
locationManager?.reGeocodeTimeout = 5
|
|
195
127
|
locationManager?.locatingWithReGeocode = true
|
|
196
|
-
|
|
197
|
-
// iOS 9 之前:防止后台被系统挂起(默认关闭,用户可通过 setPausesLocationUpdatesAutomatically 配置)
|
|
198
128
|
locationManager?.pausesLocationUpdatesAutomatically = false
|
|
199
129
|
}
|
|
200
|
-
|
|
201
|
-
// MARK: -
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
// 🔑 坐标验证:防止无效坐标
|
|
211
|
-
guard location.coordinate.latitude >= -90 && location.coordinate.latitude <= 90,
|
|
212
|
-
location.coordinate.longitude >= -180 && location.coordinate.longitude <= 180 else {
|
|
213
|
-
return
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
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] = [
|
|
217
140
|
"latitude": location.coordinate.latitude,
|
|
218
141
|
"longitude": location.coordinate.longitude,
|
|
219
142
|
"accuracy": location.horizontalAccuracy,
|
|
@@ -222,28 +145,23 @@ class LocationManager: NSObject, AMapLocationManagerDelegate {
|
|
|
222
145
|
"speed": location.speed,
|
|
223
146
|
"timestamp": location.timestamp.timeIntervalSince1970 * 1000
|
|
224
147
|
]
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
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
|
|
237
159
|
}
|
|
238
|
-
|
|
239
|
-
|
|
160
|
+
|
|
161
|
+
// 触发连续定位回调
|
|
162
|
+
onLocationUpdate?(data)
|
|
240
163
|
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* 方向更新回调
|
|
244
|
-
* @param manager 定位管理器
|
|
245
|
-
* @param heading 方向信息
|
|
246
|
-
*/
|
|
164
|
+
|
|
247
165
|
func amapLocationManager(_ manager: AMapLocationManager!, didUpdate heading: CLHeading!) {
|
|
248
166
|
let headingData: [String: Any] = [
|
|
249
167
|
"heading": heading.trueHeading,
|
|
@@ -252,22 +170,53 @@ class LocationManager: NSObject, AMapLocationManagerDelegate {
|
|
|
252
170
|
]
|
|
253
171
|
onHeadingUpdate?(headingData)
|
|
254
172
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
* @param manager 定位管理器
|
|
259
|
-
* @param locationManager 系统定位管理器
|
|
260
|
-
*/
|
|
261
|
-
func amapLocationManager(_ manager: AMapLocationManager!, doRequireLocationAuth locationManager: CLLocationManager!) {
|
|
262
|
-
locationManager.requestAlwaysAuthorization()
|
|
173
|
+
|
|
174
|
+
func amapLocationManager(_ manager: AMapLocationManager!, didFailWithError error: Error!) {
|
|
175
|
+
// 定位失败 - 静默处理(连续定位会自动重试)
|
|
263
176
|
}
|
|
264
|
-
|
|
177
|
+
|
|
178
|
+
// MARK: - 工具方法
|
|
179
|
+
|
|
265
180
|
/**
|
|
266
|
-
*
|
|
267
|
-
* @param
|
|
268
|
-
* @param
|
|
181
|
+
* 坐标转换
|
|
182
|
+
* @param coordinate 原始坐标
|
|
183
|
+
* @param type 坐标类型 (0: GPS/Google, 1: MapBar, 2: Baidu, 3: MapABC/SoSo)
|
|
184
|
+
* @param promise Promise
|
|
269
185
|
*/
|
|
270
|
-
func
|
|
271
|
-
|
|
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
|
|
272
221
|
}
|
|
273
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
|
|
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:
|
|
23
|
+
var fillColor: String?
|
|
22
24
|
/// 边框颜色
|
|
23
|
-
var strokeColor:
|
|
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
|
|
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
|
-
|
|
100
|
-
longitude >= -180 && longitude <= 180 else {
|
|
101
|
-
return
|
|
99
|
+
if let old = circle {
|
|
100
|
+
mapView.remove(old)
|
|
102
101
|
}
|
|
103
102
|
|
|
104
|
-
|
|
105
|
-
|
|
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:
|
|
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:
|
|
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
|
|
3
|
+
public class CircleViewModule: Module {
|
|
4
4
|
public func definition() -> ModuleDefinition {
|
|
5
|
-
Name("
|
|
5
|
+
Name("CircleView")
|
|
6
6
|
|
|
7
|
-
View(
|
|
7
|
+
View(CircleView.self) {
|
|
8
8
|
Events("onCirclePress")
|
|
9
9
|
|
|
10
|
-
Prop("center") { (view:
|
|
10
|
+
Prop("center") { (view: CircleView, center: [String: Double]?) in
|
|
11
11
|
view.setCenter(center)
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
Prop("radius") { (view:
|
|
14
|
+
Prop("radius") { (view: CircleView, radius: Double) in
|
|
15
15
|
view.setRadius(radius)
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
Prop("fillColor") { (view:
|
|
18
|
+
Prop("fillColor") { (view: CircleView, color: String?) in
|
|
19
19
|
view.setFillColor(color)
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
Prop("strokeColor") { (view:
|
|
22
|
+
Prop("strokeColor") { (view: CircleView, color: String?) in
|
|
23
23
|
view.setStrokeColor(color)
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
Prop("strokeWidth") { (view:
|
|
26
|
+
Prop("strokeWidth") { (view: CircleView, width: Double) in
|
|
27
27
|
view.setStrokeWidth(Float(width))
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
Prop("zIndex") { (view:
|
|
30
|
+
Prop("zIndex") { (view: CircleView, zIndex: Double) in
|
|
31
31
|
view.setZIndex(zIndex)
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
OnViewDidUpdateProps { (view:
|
|
34
|
+
OnViewDidUpdateProps { (view: CircleView) in
|
|
35
35
|
// 属性更新完成后,如果还没连接地图,尝试连接
|
|
36
36
|
if !view.isMapConnected() {
|
|
37
|
-
// 查找父视图
|
|
37
|
+
// 查找父视图 ExpoGaodeMapView
|
|
38
38
|
var parent = view.superview
|
|
39
39
|
while parent != nil {
|
|
40
|
-
if let mapView = parent as?
|
|
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
|
+
}
|