expo-gaode-map-navigation 2.0.12-next.0 → 2.0.13

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 (238) hide show
  1. package/README.md +296 -7
  2. package/android/build.gradle +12 -4
  3. package/android/src/main/AndroidManifest.xml +10 -1
  4. package/android/src/main/cpp/cluster_jni.cpp +56 -0
  5. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapModule.kt +49 -8
  6. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapOfflineModule.kt +83 -15
  7. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapView.kt +13 -3
  8. package/android/src/main/java/expo/modules/gaodemap/map/managers/UIManager.kt +36 -39
  9. package/android/src/main/java/expo/modules/gaodemap/map/modules/SDKInitializer.kt +23 -17
  10. package/android/src/main/java/expo/modules/gaodemap/map/overlays/ClusterView.kt +5 -2
  11. package/android/src/main/java/expo/modules/gaodemap/map/overlays/HeatMapView.kt +122 -10
  12. package/android/src/main/java/expo/modules/gaodemap/map/overlays/HeatMapViewModule.kt +2 -2
  13. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MarkerView.kt +37 -25
  14. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MarkerViewModule.kt +6 -6
  15. package/android/src/main/java/expo/modules/gaodemap/map/search/ExpoGaodeMapSearchModule.kt +751 -0
  16. package/android/src/main/java/expo/modules/gaodemap/map/utils/GeometryUtils.kt +103 -0
  17. package/android/src/main/java/expo/modules/gaodemap/navigation/ExpoGaodeMapNaviView.kt +1408 -394
  18. package/android/src/main/java/expo/modules/gaodemap/navigation/ExpoGaodeMapNaviViewModule.kt +121 -1
  19. package/android/src/main/java/expo/modules/gaodemap/navigation/ExpoGaodeMapNavigationModule.kt +14 -28
  20. package/android/src/main/java/expo/modules/gaodemap/navigation/listeners/IndependentRouteListener.kt +28 -3
  21. package/android/src/main/java/expo/modules/gaodemap/navigation/listeners/RouteCalculateListener.kt +2 -2
  22. package/android/src/main/java/expo/modules/gaodemap/navigation/managers/IndependentRouteManager.kt +114 -15
  23. package/android/src/main/java/expo/modules/gaodemap/navigation/routes/drive/DriveTruckRouteCalculator.kt +24 -35
  24. package/android/src/main/java/expo/modules/gaodemap/navigation/services/IndependentRouteService.kt +50 -36
  25. package/android/src/main/java/expo/modules/gaodemap/navigation/services/NavigationForegroundService.kt +661 -0
  26. package/android/src/main/java/expo/modules/gaodemap/navigation/utils/Converters.kt +21 -12
  27. package/android/src/main/res/drawable/ic_nav_notification_small.xml +10 -0
  28. package/android/src/main/res/drawable/landback_0.png +0 -0
  29. package/android/src/main/res/drawable/landback_1.png +0 -0
  30. package/android/src/main/res/drawable/landback_2.png +0 -0
  31. package/android/src/main/res/drawable/landback_3.png +0 -0
  32. package/android/src/main/res/drawable/landback_4.png +0 -0
  33. package/android/src/main/res/drawable/landback_5.png +0 -0
  34. package/android/src/main/res/drawable/landback_6.png +0 -0
  35. package/android/src/main/res/drawable/landback_7.png +0 -0
  36. package/android/src/main/res/drawable/landback_8.png +0 -0
  37. package/android/src/main/res/drawable/landback_9.png +0 -0
  38. package/android/src/main/res/drawable/landback_a.png +0 -0
  39. package/android/src/main/res/drawable/landback_b.png +0 -0
  40. package/android/src/main/res/drawable/landback_c.png +0 -0
  41. package/android/src/main/res/drawable/landback_d.png +0 -0
  42. package/android/src/main/res/drawable/landback_e.png +0 -0
  43. package/android/src/main/res/drawable/landback_f.png +0 -0
  44. package/android/src/main/res/drawable/landback_g.png +0 -0
  45. package/android/src/main/res/drawable/landback_h.png +0 -0
  46. package/android/src/main/res/drawable/landback_i.png +0 -0
  47. package/android/src/main/res/drawable/landback_j.png +0 -0
  48. package/android/src/main/res/drawable/landback_k.png +0 -0
  49. package/android/src/main/res/drawable/landback_l.png +0 -0
  50. package/android/src/main/res/drawable/landfront_0.png +0 -0
  51. package/android/src/main/res/drawable/landfront_00.png +0 -0
  52. package/android/src/main/res/drawable/landfront_1.png +0 -0
  53. package/android/src/main/res/drawable/landfront_11.png +0 -0
  54. package/android/src/main/res/drawable/landfront_20.png +0 -0
  55. package/android/src/main/res/drawable/landfront_21.png +0 -0
  56. package/android/src/main/res/drawable/landfront_22.png +0 -0
  57. package/android/src/main/res/drawable/landfront_3.png +0 -0
  58. package/android/src/main/res/drawable/landfront_33.png +0 -0
  59. package/android/src/main/res/drawable/landfront_40.png +0 -0
  60. package/android/src/main/res/drawable/landfront_43.png +0 -0
  61. package/android/src/main/res/drawable/landfront_44.png +0 -0
  62. package/android/src/main/res/drawable/landfront_5.png +0 -0
  63. package/android/src/main/res/drawable/landfront_55.png +0 -0
  64. package/android/src/main/res/drawable/landfront_61.png +0 -0
  65. package/android/src/main/res/drawable/landfront_63.png +0 -0
  66. package/android/src/main/res/drawable/landfront_66.png +0 -0
  67. package/android/src/main/res/drawable/landfront_70.png +0 -0
  68. package/android/src/main/res/drawable/landfront_71.png +0 -0
  69. package/android/src/main/res/drawable/landfront_73.png +0 -0
  70. package/android/src/main/res/drawable/landfront_77.png +0 -0
  71. package/android/src/main/res/drawable/landfront_8.png +0 -0
  72. package/android/src/main/res/drawable/landfront_88.png +0 -0
  73. package/android/src/main/res/drawable/landfront_90.png +0 -0
  74. package/android/src/main/res/drawable/landfront_95.png +0 -0
  75. package/android/src/main/res/drawable/landfront_99.png +0 -0
  76. package/android/src/main/res/drawable/landfront_a0.png +0 -0
  77. package/android/src/main/res/drawable/landfront_a8.png +0 -0
  78. package/android/src/main/res/drawable/landfront_aa.png +0 -0
  79. package/android/src/main/res/drawable/landfront_b1.png +0 -0
  80. package/android/src/main/res/drawable/landfront_b5.png +0 -0
  81. package/android/src/main/res/drawable/landfront_bb.png +0 -0
  82. package/android/src/main/res/drawable/landfront_c3.png +0 -0
  83. package/android/src/main/res/drawable/landfront_c8.png +0 -0
  84. package/android/src/main/res/drawable/landfront_cc.png +0 -0
  85. package/android/src/main/res/drawable/landfront_d.png +0 -0
  86. package/android/src/main/res/drawable/landfront_dd.png +0 -0
  87. package/android/src/main/res/drawable/landfront_e1.png +0 -0
  88. package/android/src/main/res/drawable/landfront_e5.png +0 -0
  89. package/android/src/main/res/drawable/landfront_ee.png +0 -0
  90. package/android/src/main/res/drawable/landfront_f0.png +0 -0
  91. package/android/src/main/res/drawable/landfront_f1.png +0 -0
  92. package/android/src/main/res/drawable/landfront_f5.png +0 -0
  93. package/android/src/main/res/drawable/landfront_ff.png +0 -0
  94. package/android/src/main/res/drawable/landfront_g3.png +0 -0
  95. package/android/src/main/res/drawable/landfront_g5.png +0 -0
  96. package/android/src/main/res/drawable/landfront_gg.png +0 -0
  97. package/android/src/main/res/drawable/landfront_h1.png +0 -0
  98. package/android/src/main/res/drawable/landfront_h3.png +0 -0
  99. package/android/src/main/res/drawable/landfront_h5.png +0 -0
  100. package/android/src/main/res/drawable/landfront_hh.png +0 -0
  101. package/android/src/main/res/drawable/landfront_i0.png +0 -0
  102. package/android/src/main/res/drawable/landfront_i3.png +0 -0
  103. package/android/src/main/res/drawable/landfront_i5.png +0 -0
  104. package/android/src/main/res/drawable/landfront_ii.png +0 -0
  105. package/android/src/main/res/drawable/landfront_j1.png +0 -0
  106. package/android/src/main/res/drawable/landfront_j8.png +0 -0
  107. package/android/src/main/res/drawable/landfront_jj.png +0 -0
  108. package/android/src/main/res/drawable/landfront_kk.png +0 -0
  109. package/android/src/main/res/drawable/landfront_ll.png +0 -0
  110. package/android/src/main/res/drawable/nav_notification_brand_icon.xml +16 -0
  111. package/android/src/main/res/drawable/navi_arrow_leftline.png +0 -0
  112. package/android/src/main/res/drawable/navi_lane_shape_bg_center.xml +5 -0
  113. package/android/src/main/res/drawable/navi_lane_shape_bg_left.xml +8 -0
  114. package/android/src/main/res/drawable/navi_lane_shape_bg_over.xml +6 -0
  115. package/android/src/main/res/drawable/navi_lane_shape_bg_right.xml +8 -0
  116. package/android/src/main/res/drawable-nodpi/nav_tracker_car.png +0 -0
  117. package/build/ExpoGaodeMapNaviView.d.ts +16 -0
  118. package/build/ExpoGaodeMapNaviView.d.ts.map +1 -1
  119. package/build/ExpoGaodeMapNaviView.js +74 -1
  120. package/build/ExpoGaodeMapNaviView.js.map +1 -1
  121. package/build/index.d.ts +56 -8
  122. package/build/index.d.ts.map +1 -1
  123. package/build/index.js +452 -10
  124. package/build/index.js.map +1 -1
  125. package/build/map/ExpoGaodeMapModule.d.ts +15 -13
  126. package/build/map/ExpoGaodeMapModule.d.ts.map +1 -1
  127. package/build/map/ExpoGaodeMapModule.js +31 -39
  128. package/build/map/ExpoGaodeMapModule.js.map +1 -1
  129. package/build/map/ExpoGaodeMapOfflineModule.d.ts +5 -0
  130. package/build/map/ExpoGaodeMapOfflineModule.d.ts.map +1 -1
  131. package/build/map/ExpoGaodeMapOfflineModule.js.map +1 -1
  132. package/build/map/ExpoGaodeMapView.d.ts +3 -4
  133. package/build/map/ExpoGaodeMapView.d.ts.map +1 -1
  134. package/build/map/ExpoGaodeMapView.js +28 -25
  135. package/build/map/ExpoGaodeMapView.js.map +1 -1
  136. package/build/map/components/overlays/Circle.d.ts.map +1 -1
  137. package/build/map/components/overlays/Circle.js +1 -30
  138. package/build/map/components/overlays/Circle.js.map +1 -1
  139. package/build/map/components/overlays/Cluster.d.ts.map +1 -1
  140. package/build/map/components/overlays/Cluster.js +1 -42
  141. package/build/map/components/overlays/Cluster.js.map +1 -1
  142. package/build/map/components/overlays/HeatMap.d.ts.map +1 -1
  143. package/build/map/components/overlays/HeatMap.js +21 -21
  144. package/build/map/components/overlays/HeatMap.js.map +1 -1
  145. package/build/map/components/overlays/Marker.d.ts.map +1 -1
  146. package/build/map/components/overlays/Marker.js +76 -80
  147. package/build/map/components/overlays/Marker.js.map +1 -1
  148. package/build/map/components/overlays/Polygon.d.ts.map +1 -1
  149. package/build/map/components/overlays/Polygon.js +1 -25
  150. package/build/map/components/overlays/Polygon.js.map +1 -1
  151. package/build/map/components/overlays/Polyline.d.ts.map +1 -1
  152. package/build/map/components/overlays/Polyline.js +1 -31
  153. package/build/map/components/overlays/Polyline.js.map +1 -1
  154. package/build/map/index.d.ts +9 -2
  155. package/build/map/index.d.ts.map +1 -1
  156. package/build/map/index.js +9 -2
  157. package/build/map/index.js.map +1 -1
  158. package/build/map/search/ExpoGaodeMapSearch.types.d.ts +340 -0
  159. package/build/map/search/ExpoGaodeMapSearch.types.d.ts.map +1 -0
  160. package/build/map/search/ExpoGaodeMapSearch.types.js +19 -0
  161. package/build/map/search/ExpoGaodeMapSearch.types.js.map +1 -0
  162. package/build/map/search/ExpoGaodeMapSearchModule.d.ts +74 -0
  163. package/build/map/search/ExpoGaodeMapSearchModule.d.ts.map +1 -0
  164. package/build/map/search/ExpoGaodeMapSearchModule.js +47 -0
  165. package/build/map/search/ExpoGaodeMapSearchModule.js.map +1 -0
  166. package/build/map/search/index.d.ts +156 -0
  167. package/build/map/search/index.d.ts.map +1 -0
  168. package/build/map/search/index.js +171 -0
  169. package/build/map/search/index.js.map +1 -0
  170. package/build/map/types/index.d.ts +2 -2
  171. package/build/map/types/index.d.ts.map +1 -1
  172. package/build/map/types/index.js.map +1 -1
  173. package/build/map/types/map-view.types.d.ts +4 -2
  174. package/build/map/types/map-view.types.d.ts.map +1 -1
  175. package/build/map/types/map-view.types.js.map +1 -1
  176. package/build/map/types/native-module.types.d.ts +11 -12
  177. package/build/map/types/native-module.types.d.ts.map +1 -1
  178. package/build/map/types/native-module.types.js.map +1 -1
  179. package/build/map/types/overlays.types.d.ts +9 -14
  180. package/build/map/types/overlays.types.d.ts.map +1 -1
  181. package/build/map/types/overlays.types.js.map +1 -1
  182. package/build/map/types/route-playback.types.d.ts +16 -0
  183. package/build/map/types/route-playback.types.d.ts.map +1 -1
  184. package/build/map/types/route-playback.types.js.map +1 -1
  185. package/build/map/utils/ErrorHandler.js +11 -11
  186. package/build/map/utils/ErrorHandler.js.map +1 -1
  187. package/build/map/utils/OfflineMapManager.d.ts +4 -0
  188. package/build/map/utils/OfflineMapManager.d.ts.map +1 -1
  189. package/build/map/utils/OfflineMapManager.js +6 -0
  190. package/build/map/utils/OfflineMapManager.js.map +1 -1
  191. package/build/types/coordinates.types.d.ts +3 -0
  192. package/build/types/coordinates.types.d.ts.map +1 -1
  193. package/build/types/coordinates.types.js.map +1 -1
  194. package/build/types/independent.types.d.ts +111 -12
  195. package/build/types/independent.types.d.ts.map +1 -1
  196. package/build/types/independent.types.js.map +1 -1
  197. package/build/types/native-module.types.d.ts +1 -1
  198. package/build/types/native-module.types.js.map +1 -1
  199. package/build/types/naviview.types.d.ts +304 -14
  200. package/build/types/naviview.types.d.ts.map +1 -1
  201. package/build/types/naviview.types.js.map +1 -1
  202. package/build/types/route.types.d.ts +12 -2
  203. package/build/types/route.types.d.ts.map +1 -1
  204. package/build/types/route.types.js.map +1 -1
  205. package/expo-module.config.json +4 -2
  206. package/ios/ExpoGaodeMapNaviView.swift +2331 -201
  207. package/ios/ExpoGaodeMapNaviViewModule.swift +109 -1
  208. package/ios/ExpoGaodeMapNavigation.podspec +2 -1
  209. package/ios/ExpoGaodeMapNavigationModule.swift +7 -5
  210. package/ios/managers/IndependentRouteManager.swift +90 -26
  211. package/ios/map/ExpoGaodeMapModule.swift +72 -21
  212. package/ios/map/ExpoGaodeMapOfflineModule.swift +61 -0
  213. package/ios/map/ExpoGaodeMapSearchModule.swift +773 -0
  214. package/ios/map/ExpoGaodeMapView.swift +23 -5
  215. package/ios/map/GaodeMapPrivacyManager.swift +26 -18
  216. package/ios/map/cpp/GeometryEngine.cpp +112 -0
  217. package/ios/map/cpp/GeometryEngine.hpp +21 -0
  218. package/ios/map/modules/LocationManager.swift +37 -5
  219. package/ios/map/overlays/MarkerView.swift +11 -11
  220. package/ios/map/overlays/MarkerViewModule.swift +4 -4
  221. package/ios/map/overlays/PolylineView.swift +6 -12
  222. package/ios/map/utils/ClusterNative.h +8 -0
  223. package/ios/map/utils/ClusterNative.mm +27 -0
  224. package/ios/map/utils/PermissionManager.swift +115 -6
  225. package/ios/routes/drive/DriveTruckRouteCalculator.swift +165 -77
  226. package/ios/routes/walkride/WalkRideRouteCalculator.swift +127 -1
  227. package/ios/services/IndependentRouteService.swift +198 -39
  228. package/ios/services/NavigationLiveActivityAttributes.swift +48 -0
  229. package/ios/services/NavigationLiveActivityManager.swift +359 -0
  230. package/package.json +22 -7
  231. package/plugin/build/withGaodeMap.d.ts +8 -0
  232. package/plugin/build/withGaodeMap.js +60 -4
  233. package/scripts/check-expo-modules.js +68 -0
  234. package/shared/cpp/GeometryEngine.cpp +112 -0
  235. package/shared/cpp/GeometryEngine.hpp +21 -0
  236. package/widget-template/README.md +46 -0
  237. package/widget-template/ios/NavigationLiveActivityWidget.swift +367 -0
  238. package/android/src/main/java/expo/modules/gaodemap/navigation/managers/RouteCalculator.kt +0 -173
@@ -6,6 +6,7 @@
6
6
  //
7
7
 
8
8
  import ExpoModulesCore
9
+ import UIKit
9
10
 
10
11
  public class ExpoGaodeMapNaviViewModule: Module {
11
12
  public func definition() -> ModuleDefinition {
@@ -27,7 +28,10 @@ public class ExpoGaodeMapNaviViewModule: Module {
27
28
  "onWayPointArrived",
28
29
  "onGpsStatusChanged",
29
30
  "onNavigationInfoUpdate",
30
- "onGpsSignalWeak"
31
+ "onGpsSignalWeak",
32
+ "onNavigationVisualStateUpdate",
33
+ "onLaneInfoUpdate",
34
+ "onTrafficStatusesUpdate"
31
35
  )
32
36
 
33
37
  // 属性定义
@@ -42,6 +46,44 @@ public class ExpoGaodeMapNaviViewModule: Module {
42
46
  Prop("showCamera") { (view: ExpoGaodeMapNaviView, value: Bool) in
43
47
  view.showCamera = value
44
48
  }
49
+
50
+ Prop("carImage") { (view: ExpoGaodeMapNaviView, value: String?) in
51
+ view.carImageSource = value
52
+ }
53
+
54
+ Prop("carImageSize") { (view: ExpoGaodeMapNaviView, value: [String: Double]?) in
55
+ let width = CGFloat(value?["width"] ?? 0)
56
+ let height = CGFloat(value?["height"] ?? 0)
57
+ if width > 0, height > 0 {
58
+ view.carImageSize = CGSize(width: width, height: height)
59
+ } else {
60
+ view.carImageSize = nil
61
+ }
62
+ }
63
+
64
+ Prop("carCompassImage") { (view: ExpoGaodeMapNaviView, value: String?) in
65
+ view.carCompassImageSource = value
66
+ }
67
+
68
+ Prop("startPointImage") { (view: ExpoGaodeMapNaviView, value: String?) in
69
+ view.startPointImageSource = value
70
+ }
71
+
72
+ Prop("wayPointImage") { (view: ExpoGaodeMapNaviView, value: String?) in
73
+ view.wayPointImageSource = value
74
+ }
75
+
76
+ Prop("customWaypointMarkers") { (view: ExpoGaodeMapNaviView, value: [[String: Any]]?) in
77
+ view.customWaypointMarkerPayloads = value
78
+ }
79
+
80
+ Prop("endPointImage") { (view: ExpoGaodeMapNaviView, value: String?) in
81
+ view.endPointImageSource = value
82
+ }
83
+
84
+ Prop("cameraImage") { (view: ExpoGaodeMapNaviView, value: String?) in
85
+ view.cameraImageSource = value
86
+ }
45
87
 
46
88
  Prop("autoLockCar") { (view: ExpoGaodeMapNaviView, value: Bool) in
47
89
  view.autoLockCar = value
@@ -83,6 +125,18 @@ public class ExpoGaodeMapNaviViewModule: Module {
83
125
  Prop("showTrafficBar") { (view: ExpoGaodeMapNaviView, value: Bool) in
84
126
  view.showTrafficBar = value
85
127
  }
128
+
129
+ Prop("trafficBarFrame") { (view: ExpoGaodeMapNaviView, value: [String: Double]?) in
130
+ let x = CGFloat(value?["x"] ?? 0)
131
+ let y = CGFloat(value?["y"] ?? 0)
132
+ let width = CGFloat(value?["width"] ?? 0)
133
+ let height = CGFloat(value?["height"] ?? 0)
134
+ view.trafficBarFrame = CGRect(x: x, y: y, width: width, height: height)
135
+ }
136
+
137
+ Prop("trafficBarColors") { (view: ExpoGaodeMapNaviView, value: [String: Any]?) in
138
+ view.trafficBarColors = value
139
+ }
86
140
 
87
141
  Prop("showBrowseRouteButton") { (view: ExpoGaodeMapNaviView, value: Bool) in
88
142
  view.showBrowseRouteButton = value
@@ -95,6 +149,14 @@ public class ExpoGaodeMapNaviViewModule: Module {
95
149
  Prop("showTrafficButton") { (view: ExpoGaodeMapNaviView, value: Bool) in
96
150
  view.showTrafficButton = value
97
151
  }
152
+
153
+ Prop("showBackupRoute") { (view: ExpoGaodeMapNaviView, value: Bool) in
154
+ view.showBackupRoute = value
155
+ }
156
+
157
+ Prop("showEagleMap") { (view: ExpoGaodeMapNaviView, value: Bool) in
158
+ view.showEagleMap = value
159
+ }
98
160
 
99
161
  Prop("showUIElements") { (view: ExpoGaodeMapNaviView, value: Bool) in
100
162
  view.applyShowUIElements(value)
@@ -111,6 +173,34 @@ public class ExpoGaodeMapNaviViewModule: Module {
111
173
  Prop("showTrafficLights") { (view: ExpoGaodeMapNaviView, value: Bool) in
112
174
  view.showTrafficLights = value
113
175
  }
176
+
177
+ Prop("showCompassEnabled") { (view: ExpoGaodeMapNaviView, value: Bool) in
178
+ view.showCompassEnabled = value
179
+ }
180
+
181
+ Prop("showDriveCongestion") { (view: ExpoGaodeMapNaviView, value: Bool) in
182
+ view.showDriveCongestion = value
183
+ }
184
+
185
+ Prop("showTrafficLightView") { (view: ExpoGaodeMapNaviView, value: Bool) in
186
+ view.showTrafficLightView = value
187
+ }
188
+
189
+ Prop("hideNativeTopInfoLayout") { (view: ExpoGaodeMapNaviView, value: Bool) in
190
+ view.hideNativeTopInfoLayout = value
191
+ }
192
+
193
+ Prop("hideNativeLaneInfoLayout") { (view: ExpoGaodeMapNaviView, value: Bool) in
194
+ view.hideNativeLaneInfoLayout = value
195
+ }
196
+
197
+ // Android-only prop, keep a no-op mapping on iOS for cross-platform prop compatibility.
198
+ Prop("androidBackgroundNavigationNotificationEnabled") { (_: ExpoGaodeMapNaviView, _: Bool) in
199
+ }
200
+
201
+ Prop("iosLiveActivityEnabled") { (view: ExpoGaodeMapNaviView, value: Bool) in
202
+ view.iosLiveActivityEnabled = value
203
+ }
114
204
 
115
205
  Prop("mapViewModeType") { (view: ExpoGaodeMapNaviView, value: Int) in
116
206
  view.mapViewModeType = value
@@ -119,11 +209,29 @@ public class ExpoGaodeMapNaviViewModule: Module {
119
209
  Prop("lineWidth") { (view: ExpoGaodeMapNaviView, value: Double) in
120
210
  view.lineWidth = CGFloat(value)
121
211
  }
212
+
213
+ Prop("driveViewEdgePadding") { (view: ExpoGaodeMapNaviView, value: [String: Double]?) in
214
+ let top = CGFloat(value?["top"] ?? 0)
215
+ let left = CGFloat(value?["left"] ?? 0)
216
+ let bottom = CGFloat(value?["bottom"] ?? 0)
217
+ let right = CGFloat(value?["right"] ?? 0)
218
+ view.driveViewEdgePadding = UIEdgeInsets(top: top, left: left, bottom: bottom, right: right)
219
+ }
220
+
221
+ Prop("screenAnchor") { (view: ExpoGaodeMapNaviView, value: [String: Double]?) in
222
+ let x = CGFloat(value?["x"] ?? 0)
223
+ let y = CGFloat(value?["y"] ?? 0)
224
+ view.screenAnchor = CGPoint(x: x, y: y)
225
+ }
122
226
 
123
227
  // 方法定义
124
228
  AsyncFunction("startNavigation") { (view: ExpoGaodeMapNaviView, startLat: Double, startLng: Double, endLat: Double, endLng: Double, promise: Promise) in
125
229
  view.startNavigation(startLat: startLat, startLng: startLng, endLat: endLat, endLng: endLng, promise: promise)
126
230
  }
231
+
232
+ AsyncFunction("startNavigationWithIndependentPath") { (view: ExpoGaodeMapNaviView, token: Int, routeId: Int?, routeIndex: Int?, naviType: Int?, promise: Promise) in
233
+ view.startNavigationWithIndependentPath(token: token, routeId: routeId, routeIndex: routeIndex, naviType: naviType, promise: promise)
234
+ }
127
235
 
128
236
  AsyncFunction("stopNavigation") { (view: ExpoGaodeMapNaviView, promise: Promise) in
129
237
  view.stopNavigation(promise: promise)
@@ -24,9 +24,10 @@ Pod::Spec.new do |s|
24
24
  s.static_framework = true
25
25
 
26
26
  s.dependency 'ExpoModulesCore'
27
- s.dependency 'AMapNavi'
27
+ s.dependency 'AMapNavi','= 11.1.200'
28
28
  s.dependency 'AMapFoundation'
29
29
  s.dependency 'AMapLocation'
30
+ s.dependency 'AMapSearch'
30
31
 
31
32
  s.library = 'c++'
32
33
 
@@ -21,7 +21,7 @@ public class ExpoGaodeMapNavigationModule: Module {
21
21
  private var walkRideCalculator: WalkRideRouteCalculator?
22
22
 
23
23
  // 独立路径规划管理
24
- private let independentRouteManager = IndependentRouteManager()
24
+ private let independentRouteManager = IndependentRouteManager.shared
25
25
  private var independentRouteService: IndependentRouteService?
26
26
 
27
27
  // 官方导航组件(iOS)
@@ -309,8 +309,11 @@ public class ExpoGaodeMapNavigationModule: Module {
309
309
  AsyncFunction("calculateMotorcycleRoute") { (options: [String: Any], promise: Promise) in
310
310
  do {
311
311
  try self.ensureInitialized()
312
- // 摩托车复用驾车算路
313
- self.ensureDriveTruck().calculateDriveRoute(options: options, promise: promise)
312
+ var motorcycleOptions = options
313
+ if motorcycleOptions["carType"] == nil && motorcycleOptions["type"] == nil {
314
+ motorcycleOptions["carType"] = 11
315
+ }
316
+ self.ensureDriveTruck().calculateDriveRoute(options: motorcycleOptions, promise: promise)
314
317
  } catch {
315
318
  self.rejectInitializationError(promise, error: error)
316
319
  }
@@ -321,8 +324,7 @@ public class ExpoGaodeMapNavigationModule: Module {
321
324
  AsyncFunction("calculateEBikeRoute") { (options: [String: Any], promise: Promise) in
322
325
  do {
323
326
  try self.ensureInitialized()
324
- // 电动车复用骑行算路
325
- self.ensureWalkRide().calculateRideRoute(options: options, promise: promise)
327
+ self.ensureWalkRide().calculateResolvedEleBikeRoute(options: options, promise: promise)
326
328
  } catch {
327
329
  self.rejectInitializationError(promise, error: error)
328
330
  }
@@ -10,8 +10,15 @@ import Foundation
10
10
  import AMapNaviKit
11
11
 
12
12
  class IndependentRouteManager {
13
+ static let shared = IndependentRouteManager()
14
+
15
+ private struct Entry {
16
+ let scene: String
17
+ let routeGroup: AMapNaviRouteGroup?
18
+ let routeIds: [Int]
19
+ }
13
20
 
14
- private var routeGroups: [Int: AMapNaviRouteGroup] = [:]
21
+ private var routeGroups: [Int: Entry] = [:]
15
22
  private var nextToken: Int = 1
16
23
  private let lock = NSLock()
17
24
 
@@ -25,10 +32,18 @@ class IndependentRouteManager {
25
32
  }
26
33
 
27
34
  /// 存储路线组(使用指定 token)
28
- func storeRouteGroup(token: Int, routeGroup: AMapNaviRouteGroup) {
35
+ func storeRouteGroup(token: Int, scene: String = "drive", routeGroup: AMapNaviRouteGroup) {
36
+ lock.lock()
37
+ defer { lock.unlock() }
38
+ let routeIds = routeGroup.naviRouteIDs?.map { $0.intValue } ?? []
39
+ routeGroups[token] = Entry(scene: scene, routeGroup: routeGroup, routeIds: routeIds)
40
+ }
41
+
42
+ /// 存储非驾车场景的独立路径元信息
43
+ func storeSceneRoutes(token: Int, scene: String, routeIds: [Int]) {
29
44
  lock.lock()
30
45
  defer { lock.unlock() }
31
- routeGroups[token] = routeGroup
46
+ routeGroups[token] = Entry(scene: scene, routeGroup: nil, routeIds: routeIds)
32
47
  }
33
48
 
34
49
  /// 存储路线组(自动生成 token)
@@ -37,7 +52,8 @@ class IndependentRouteManager {
37
52
  defer { lock.unlock() }
38
53
  let token = nextToken
39
54
  nextToken += 1
40
- routeGroups[token] = routeGroup
55
+ let routeIds = routeGroup.naviRouteIDs?.map { $0.intValue } ?? []
56
+ routeGroups[token] = Entry(scene: "drive", routeGroup: routeGroup, routeIds: routeIds)
41
57
  return token
42
58
  }
43
59
 
@@ -45,7 +61,14 @@ class IndependentRouteManager {
45
61
  func get(_ token: Int) -> AMapNaviRouteGroup? {
46
62
  lock.lock()
47
63
  defer { lock.unlock() }
48
- return routeGroups[token]
64
+ return routeGroups[token]?.routeGroup
65
+ }
66
+
67
+ /// 获取路线场景
68
+ func scene(for token: Int) -> String? {
69
+ lock.lock()
70
+ defer { lock.unlock() }
71
+ return routeGroups[token]?.scene
49
72
  }
50
73
 
51
74
  /// 行前选路 - 选择指定路线
@@ -54,32 +77,45 @@ class IndependentRouteManager {
54
77
  lock.lock()
55
78
  defer { lock.unlock() }
56
79
 
57
- guard let routeGroup = routeGroups[token] else { return false }
58
-
59
- // 优先使用 routeId
60
- if let routeId = routeId {
61
- routeGroup.selectNaviRoute(withRouteID: routeId)
62
- return true
80
+ guard let entry = routeGroups[token] else { return false }
81
+
82
+ let resolvedRouteId: Int? = {
83
+ if let routeId {
84
+ return routeId
85
+ }
86
+ if let routeIndex, routeIndex >= 0, routeIndex < entry.routeIds.count {
87
+ return entry.routeIds[routeIndex]
88
+ }
89
+ return nil
90
+ }()
91
+
92
+ guard let resolvedRouteId else {
93
+ return false
63
94
  }
64
-
65
- // 使用 routeIndex
66
- if let routeIndex = routeIndex, let routeIDs = routeGroup.naviRouteIDs, routeIndex < routeIDs.count {
67
- let routeId = routeIDs[routeIndex].intValue
68
- routeGroup.selectNaviRoute(withRouteID: routeId)
95
+
96
+ if let routeGroup = entry.routeGroup {
97
+ routeGroup.selectNaviRoute(withRouteID: resolvedRouteId)
69
98
  return true
70
99
  }
71
-
72
- return false
100
+
101
+ switch entry.scene {
102
+ case "walk":
103
+ return AMapNaviWalkManager.sharedInstance().selectNaviRoute(withRouteID: resolvedRouteId)
104
+ case "ride":
105
+ return AMapNaviRideManager.sharedInstance().selectNaviRoute(withRouteID: resolvedRouteId)
106
+ default:
107
+ return false
108
+ }
73
109
  }
74
110
 
75
111
  /// 启动导航
76
112
  /// 官方方法:startGPSNavi: / startEmulatorNavi:
77
113
  func start(token: Int, naviType: Int, routeId: Int?, routeIndex: Int?) -> Bool {
78
114
  lock.lock()
79
- let routeGroup = routeGroups[token]
115
+ let entry = routeGroups[token]
80
116
  lock.unlock()
81
117
 
82
- guard let routeGroup = routeGroup else { return false }
118
+ guard let entry = entry else { return false }
83
119
 
84
120
  // 先选择路线
85
121
  if routeId != nil || routeIndex != nil {
@@ -88,13 +124,41 @@ class IndependentRouteManager {
88
124
 
89
125
  // 启动导航
90
126
  // naviType: 0 = GPS导航, 1 = 模拟导航
91
- if naviType == 1 {
92
- AMapNaviDriveManager.sharedInstance().startEmulatorNavi(routeGroup)
93
- } else {
94
- AMapNaviDriveManager.sharedInstance().startGPSNavi(routeGroup)
127
+ switch entry.scene {
128
+ case "walk":
129
+ if let routeGroup = entry.routeGroup {
130
+ if naviType == 1 {
131
+ return AMapNaviWalkManager.sharedInstance().startEmulatorNavi(routeGroup)
132
+ } else {
133
+ return AMapNaviWalkManager.sharedInstance().startGPSNavi(routeGroup)
134
+ }
135
+ }
136
+ if naviType == 1 {
137
+ return AMapNaviWalkManager.sharedInstance().startEmulatorNavi()
138
+ } else {
139
+ return AMapNaviWalkManager.sharedInstance().startGPSNavi()
140
+ }
141
+ case "ride":
142
+ if let routeGroup = entry.routeGroup {
143
+ if naviType == 1 {
144
+ return AMapNaviRideManager.sharedInstance().startEmulatorNavi(routeGroup)
145
+ } else {
146
+ return AMapNaviRideManager.sharedInstance().startGPSNavi(routeGroup)
147
+ }
148
+ }
149
+ if naviType == 1 {
150
+ return AMapNaviRideManager.sharedInstance().startEmulatorNavi()
151
+ } else {
152
+ return AMapNaviRideManager.sharedInstance().startGPSNavi()
153
+ }
154
+ default:
155
+ guard let routeGroup = entry.routeGroup else { return false }
156
+ if naviType == 1 {
157
+ return AMapNaviDriveManager.sharedInstance().startEmulatorNavi(routeGroup)
158
+ } else {
159
+ return AMapNaviDriveManager.sharedInstance().startGPSNavi(routeGroup)
160
+ }
95
161
  }
96
-
97
- return true
98
162
  }
99
163
 
100
164
  /// 清除指定路线组
@@ -48,12 +48,19 @@ public class ExpoGaodeMapModule: Module {
48
48
  _ = self.trySetupApiKeyFromPlist()
49
49
  }
50
50
 
51
- Function("setPrivacyShow") { (hasShow: Bool, hasContainsPrivacy: Bool) in
52
- GaodeMapPrivacyManager.setPrivacyShow(hasShow, hasContainsPrivacy: hasContainsPrivacy)
53
- }
51
+ Function("setPrivacyConfig") { (config: [String: Any]) in
52
+ let hasShow = config["hasShow"] as? Bool ?? false
53
+ let hasContainsPrivacy = config["hasContainsPrivacy"] as? Bool ?? hasShow
54
+ let hasAgree = config["hasAgree"] as? Bool ?? false
55
+ let privacyVersion = config["privacyVersion"] as? String
54
56
 
55
- Function("setPrivacyAgree") { (hasAgree: Bool) in
56
- GaodeMapPrivacyManager.setPrivacyAgree(hasAgree)
57
+ GaodeMapPrivacyManager.setPrivacyConfig(
58
+ hasShow: hasShow,
59
+ hasContainsPrivacy: hasContainsPrivacy,
60
+ hasAgree: hasAgree,
61
+ privacyVersion: privacyVersion,
62
+ updatesPrivacyVersion: config.keys.contains("privacyVersion")
63
+ )
57
64
  }
58
65
 
59
66
  Function("setPrivacyVersion") { (version: String) in
@@ -76,7 +83,7 @@ public class ExpoGaodeMapModule: Module {
76
83
  */
77
84
  Function("initSDK") { (config: [String: String]) in
78
85
  guard GaodeMapPrivacyManager.isReady else {
79
- throw Exception(name: "PRIVACY_NOT_AGREED", description: "隐私协议未完成确认,请先调用 setPrivacyShow/setPrivacyAgree")
86
+ throw Exception(name: "PRIVACY_NOT_AGREED", description: "隐私协议未完成确认,请先调用 setPrivacyConfig")
80
87
  }
81
88
  GaodeMapPrivacyManager.applyPrivacyState()
82
89
 
@@ -179,7 +186,7 @@ public class ExpoGaodeMapModule: Module {
179
186
 
180
187
  if status == .authorizedAlways || status == .authorizedWhenInUse {
181
188
  let manager = self.getLocationManager()
182
- manager.locationManager?.requestLocation(withReGeocode: manager.locationManager?.locatingWithReGeocode ?? true, completionBlock: { location, regeocode, error in
189
+ manager.requestSingleLocation { location, regeocode, error in
183
190
  if let error = error {
184
191
  promise.reject("LOCATION_ERROR", error.localizedDescription)
185
192
  return
@@ -213,7 +220,7 @@ public class ExpoGaodeMapModule: Module {
213
220
  }
214
221
 
215
222
  promise.resolve(locationData)
216
- })
223
+ }
217
224
  } else {
218
225
  promise.reject("LOCATION_ERROR", "location unauthorized")
219
226
  }
@@ -272,6 +279,31 @@ public class ExpoGaodeMapModule: Module {
272
279
  }
273
280
  return ClusterNative.calculateDistance(lat1: coord1.latitude, lon1: coord1.longitude, lat2: coord2.latitude, lon2: coord2.longitude)
274
281
  }
282
+
283
+ /**
284
+ * 根据多个坐标点计算可同时可见的推荐缩放级别
285
+ */
286
+ Function("calculateFitZoom") {
287
+ (points: [Any]?, viewportWidthPx: Double?, viewportHeightPx: Double?, paddingPx: Double?, minZoom: Int?, maxZoom: Int?) -> Double in
288
+ let coords = LatLngParser.parseLatLngList(points)
289
+ let safeMinZoom = minZoom ?? 3
290
+ let safeMaxZoom = maxZoom ?? 20
291
+ if coords.isEmpty {
292
+ return Double(safeMinZoom)
293
+ }
294
+
295
+ let lats = coords.map { NSNumber(value: $0.latitude) }
296
+ let lons = coords.map { NSNumber(value: $0.longitude) }
297
+ return ClusterNative.calculateFitZoom(
298
+ latitudes: lats,
299
+ longitudes: lons,
300
+ viewportWidthPx: viewportWidthPx ?? 390.0,
301
+ viewportHeightPx: viewportHeightPx ?? 844.0,
302
+ paddingPx: paddingPx ?? 48.0,
303
+ minZoom: Int32(safeMinZoom),
304
+ maxZoom: Int32(safeMaxZoom)
305
+ )
306
+ }
275
307
 
276
308
  /**
277
309
  * 计算多边形面积
@@ -703,8 +735,13 @@ public class ExpoGaodeMapModule: Module {
703
735
  if self.permissionManager == nil {
704
736
  self.permissionManager = PermissionManager()
705
737
  }
706
-
707
- self.permissionManager?.requestPermission { granted, status in
738
+
739
+ guard let permissionManager = self.permissionManager else {
740
+ promise.reject("PERMISSION_MANAGER_INIT_FAILED", "权限管理器初始化失败")
741
+ return
742
+ }
743
+
744
+ permissionManager.requestPermission { _, _ in
708
745
  // 无论结果如何,都延迟后再次检查最终状态
709
746
  DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
710
747
  let finalStatus = self.currentAuthorizationStatus()
@@ -731,17 +768,31 @@ public class ExpoGaodeMapModule: Module {
731
768
  promise.reject("FOREGROUND_PERMISSION_REQUIRED", "必须先授予前台位置权限才能请求后台位置权限")
732
769
  return
733
770
  }
734
-
735
- // iOS 上后台权限通过 Info.plist 配置 + 系统设置
736
- // 这里返回当前状态
737
- let hasBackground = status == .authorizedAlways
738
-
739
- promise.resolve([
740
- "granted": hasBackground,
741
- "backgroundLocation": hasBackground,
742
- "status": self.getAuthorizationStatusString(status),
743
- "message": hasBackground ? "已授予后台权限" : "需要在系统设置中手动授予'始终'权限"
744
- ])
771
+
772
+ if self.permissionManager == nil {
773
+ self.permissionManager = PermissionManager()
774
+ }
775
+
776
+ guard let permissionManager = self.permissionManager else {
777
+ promise.reject("PERMISSION_MANAGER_INIT_FAILED", "权限管理器初始化失败")
778
+ return
779
+ }
780
+
781
+ permissionManager.requestAlwaysPermission { _, _ in
782
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
783
+ let finalStatus = self.currentAuthorizationStatus()
784
+ let hasBackground = finalStatus == .authorizedAlways
785
+
786
+ promise.resolve([
787
+ "granted": hasBackground,
788
+ "backgroundLocation": hasBackground,
789
+ "status": self.getAuthorizationStatusString(finalStatus),
790
+ "message": hasBackground
791
+ ? "已授予后台权限"
792
+ : "后台权限未授予,请在系统设置中将定位权限改为“始终允许”"
793
+ ])
794
+ }
795
+ }
745
796
  }
746
797
 
747
798
 
@@ -2,6 +2,8 @@ import ExpoModulesCore
2
2
  import AMapFoundationKit
3
3
  import AMapNaviKit
4
4
  import Foundation
5
+ import AMapNaviKit
6
+ import UIKit
5
7
 
6
8
  /**
7
9
  * 高德地图离线地图模块 (iOS)
@@ -66,6 +68,12 @@ public class ExpoGaodeMapOfflineModule: Module {
66
68
  self.downloadingCities.removeAll()
67
69
  self.pausedCities.removeAll()
68
70
  }
71
+
72
+ AsyncFunction("openOfflineMapUI") { (promise: Promise) in
73
+ DispatchQueue.main.async {
74
+ self.openOfflineMapUI(promise: promise)
75
+ }
76
+ }
69
77
 
70
78
  // ==================== 1. 地图列表管理 ====================
71
79
 
@@ -383,6 +391,59 @@ public class ExpoGaodeMapOfflineModule: Module {
383
391
 
384
392
  return offlineMapManager
385
393
  }
394
+
395
+ private func openOfflineMapUI(promise: Promise) {
396
+ guard getOfflineMapManager() != nil else {
397
+ promise.reject("ERR_SETUP", "Setup failed")
398
+ return
399
+ }
400
+
401
+ guard let detailViewController = MAOfflineMapViewController.sharedInstance() else {
402
+ promise.reject("ERR_OFFLINE_MAP_UI", "Offline map UI is unavailable")
403
+ return
404
+ }
405
+
406
+ guard let presenter = currentPresenterViewController() else {
407
+ promise.reject("ERR_NO_VIEW_CONTROLLER", "No active view controller")
408
+ return
409
+ }
410
+
411
+ if let navigationController = presenter as? UINavigationController {
412
+ navigationController.pushViewController(detailViewController, animated: true)
413
+ } else if let navigationController = presenter.navigationController {
414
+ navigationController.pushViewController(detailViewController, animated: true)
415
+ } else {
416
+ let navigationController = UINavigationController(rootViewController: detailViewController)
417
+ presenter.present(navigationController, animated: true)
418
+ }
419
+ promise.resolve(nil)
420
+ }
421
+
422
+ private func currentPresenterViewController() -> UIViewController? {
423
+ guard let scene = UIApplication.shared.connectedScenes
424
+ .compactMap({ $0 as? UIWindowScene })
425
+ .first(where: { $0.activationState == .foregroundActive }) else {
426
+ return topViewController(from: UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.rootViewController)
427
+ }
428
+
429
+ let root = scene.windows.first(where: { $0.isKeyWindow })?.rootViewController
430
+ ?? scene.windows.first?.rootViewController
431
+ return topViewController(from: root)
432
+ }
433
+
434
+ private func topViewController(from root: UIViewController?) -> UIViewController? {
435
+ guard let root else { return nil }
436
+ if let presented = root.presentedViewController {
437
+ return topViewController(from: presented)
438
+ }
439
+ if let navigationController = root as? UINavigationController {
440
+ return topViewController(from: navigationController.visibleViewController)
441
+ }
442
+ if let tabBarController = root as? UITabBarController {
443
+ return topViewController(from: tabBarController.selectedViewController)
444
+ }
445
+ return root
446
+ }
386
447
 
387
448
  private func ensureSetup(completion: @escaping (Bool) -> Void) {
388
449
  guard let manager = getOfflineMapManager() else {