expo-gaode-map 1.1.8 → 2.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/README.en.md +32 -46
  2. package/README.md +50 -70
  3. package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapView.kt +37 -268
  4. package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapViewModule.kt +1 -49
  5. package/android/src/main/java/expo/modules/gaodemap/managers/CameraManager.kt +30 -7
  6. package/android/src/main/java/expo/modules/gaodemap/managers/UIManager.kt +1 -0
  7. package/android/src/main/java/expo/modules/gaodemap/modules/LocationManager.kt +10 -1
  8. package/android/src/main/java/expo/modules/gaodemap/overlays/CircleView.kt +38 -14
  9. package/android/src/main/java/expo/modules/gaodemap/overlays/CircleViewModule.kt +3 -3
  10. package/android/src/main/java/expo/modules/gaodemap/overlays/ClusterView.kt +8 -1
  11. package/android/src/main/java/expo/modules/gaodemap/overlays/HeatMapView.kt +4 -1
  12. package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerView.kt +322 -93
  13. package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerViewModule.kt +11 -3
  14. package/android/src/main/java/expo/modules/gaodemap/overlays/MultiPointView.kt +4 -1
  15. package/android/src/main/java/expo/modules/gaodemap/overlays/PolygonView.kt +25 -11
  16. package/android/src/main/java/expo/modules/gaodemap/overlays/PolygonViewModule.kt +3 -3
  17. package/android/src/main/java/expo/modules/gaodemap/overlays/PolylineView.kt +20 -10
  18. package/android/src/main/java/expo/modules/gaodemap/overlays/PolylineViewModule.kt +6 -2
  19. package/build/ExpoGaodeMap.types.d.ts +27 -6
  20. package/build/ExpoGaodeMap.types.d.ts.map +1 -1
  21. package/build/ExpoGaodeMap.types.js +3 -0
  22. package/build/ExpoGaodeMap.types.js.map +1 -1
  23. package/build/ExpoGaodeMapModule.d.ts +157 -10
  24. package/build/ExpoGaodeMapModule.d.ts.map +1 -1
  25. package/build/ExpoGaodeMapModule.js +4 -0
  26. package/build/ExpoGaodeMapModule.js.map +1 -1
  27. package/build/ExpoGaodeMapView.d.ts +1 -17
  28. package/build/ExpoGaodeMapView.d.ts.map +1 -1
  29. package/build/ExpoGaodeMapView.js +4 -221
  30. package/build/ExpoGaodeMapView.js.map +1 -1
  31. package/build/components/overlays/Circle.d.ts +11 -1
  32. package/build/components/overlays/Circle.d.ts.map +1 -1
  33. package/build/components/overlays/Circle.js +12 -58
  34. package/build/components/overlays/Circle.js.map +1 -1
  35. package/build/components/overlays/Cluster.d.ts.map +1 -1
  36. package/build/components/overlays/Cluster.js.map +1 -1
  37. package/build/components/overlays/Marker.d.ts +13 -1
  38. package/build/components/overlays/Marker.d.ts.map +1 -1
  39. package/build/components/overlays/Marker.js +51 -115
  40. package/build/components/overlays/Marker.js.map +1 -1
  41. package/build/components/overlays/Polygon.d.ts +7 -15
  42. package/build/components/overlays/Polygon.d.ts.map +1 -1
  43. package/build/components/overlays/Polygon.js +10 -80
  44. package/build/components/overlays/Polygon.js.map +1 -1
  45. package/build/components/overlays/Polyline.d.ts +7 -14
  46. package/build/components/overlays/Polyline.d.ts.map +1 -1
  47. package/build/components/overlays/Polyline.js +9 -66
  48. package/build/components/overlays/Polyline.js.map +1 -1
  49. package/build/index.d.ts +1 -4
  50. package/build/index.d.ts.map +1 -1
  51. package/build/index.js +2 -10
  52. package/build/index.js.map +1 -1
  53. package/build/types/map-view.types.d.ts +0 -90
  54. package/build/types/map-view.types.d.ts.map +1 -1
  55. package/build/types/map-view.types.js.map +1 -1
  56. package/build/types/overlays.types.d.ts +9 -9
  57. package/build/types/overlays.types.d.ts.map +1 -1
  58. package/build/types/overlays.types.js.map +1 -1
  59. package/docs/API.en.md +1 -21
  60. package/docs/API.md +84 -56
  61. package/docs/EXAMPLES.en.md +0 -48
  62. package/docs/EXAMPLES.md +49 -102
  63. package/docs/INITIALIZATION.md +59 -71
  64. package/docs/MIGRATION.md +423 -0
  65. package/ios/ExpoGaodeMapView.swift +317 -258
  66. package/ios/ExpoGaodeMapViewModule.swift +3 -50
  67. package/ios/managers/CameraManager.swift +23 -2
  68. package/ios/managers/UIManager.swift +10 -5
  69. package/ios/modules/LocationManager.swift +10 -0
  70. package/ios/overlays/CircleView.swift +98 -19
  71. package/ios/overlays/CircleViewModule.swift +21 -0
  72. package/ios/overlays/ClusterView.swift +33 -4
  73. package/ios/overlays/HeatMapView.swift +16 -4
  74. package/ios/overlays/MarkerView.swift +235 -146
  75. package/ios/overlays/MarkerViewModule.swift +7 -3
  76. package/ios/overlays/MultiPointView.swift +30 -1
  77. package/ios/overlays/PolygonView.swift +63 -12
  78. package/ios/overlays/PolygonViewModule.swift +17 -0
  79. package/ios/overlays/PolylineView.swift +95 -25
  80. package/ios/overlays/PolylineViewModule.swift +17 -8
  81. package/ios/utils/PermissionManager.swift +9 -14
  82. package/package.json +4 -3
  83. package/src/ExpoGaodeMap.types.ts +28 -3
  84. package/src/ExpoGaodeMapModule.ts +201 -12
  85. package/src/ExpoGaodeMapView.tsx +9 -234
  86. package/src/components/overlays/Circle.tsx +14 -70
  87. package/src/components/overlays/Cluster.tsx +0 -1
  88. package/src/components/overlays/Marker.tsx +63 -138
  89. package/src/components/overlays/Polygon.tsx +12 -92
  90. package/src/components/overlays/Polyline.tsx +11 -77
  91. package/src/index.ts +4 -29
  92. package/src/types/map-view.types.ts +1 -85
  93. package/src/types/overlays.types.ts +9 -9
  94. package/android/src/main/java/expo/modules/gaodemap/managers/OverlayManager.kt +0 -574
  95. package/build/modules/AMapLocation.d.ts +0 -78
  96. package/build/modules/AMapLocation.d.ts.map +0 -1
  97. package/build/modules/AMapLocation.js +0 -132
  98. package/build/modules/AMapLocation.js.map +0 -1
  99. package/build/modules/AMapPermissions.d.ts +0 -29
  100. package/build/modules/AMapPermissions.d.ts.map +0 -1
  101. package/build/modules/AMapPermissions.js +0 -23
  102. package/build/modules/AMapPermissions.js.map +0 -1
  103. package/build/modules/AMapSDK.d.ts +0 -22
  104. package/build/modules/AMapSDK.d.ts.map +0 -1
  105. package/build/modules/AMapSDK.js +0 -25
  106. package/build/modules/AMapSDK.js.map +0 -1
  107. package/build/modules/AMapView.d.ts +0 -44
  108. package/build/modules/AMapView.d.ts.map +0 -1
  109. package/build/modules/AMapView.js +0 -65
  110. package/build/modules/AMapView.js.map +0 -1
  111. package/ios/managers/OverlayManager.swift +0 -522
  112. package/src/modules/AMapLocation.ts +0 -165
  113. package/src/modules/AMapPermissions.ts +0 -41
  114. package/src/modules/AMapSDK.ts +0 -31
  115. package/src/modules/AMapView.ts +0 -72
@@ -10,7 +10,7 @@ import MAMapKit
10
10
  * - 响应属性变化并更新渲染
11
11
  */
12
12
  class PolygonView: ExpoView {
13
- let onPress = EventDispatcher()
13
+ let onPolygonPress = EventDispatcher()
14
14
 
15
15
  /// 多边形点数组
16
16
  var points: [[String: Double]] = []
@@ -21,15 +21,41 @@ class PolygonView: ExpoView {
21
21
  /// 边框宽度
22
22
  var strokeWidth: Float = 0
23
23
 
24
- /// 地图视图弱引用
24
+ /// 地图视图引用
25
25
  private var mapView: MAMapView?
26
26
  /// 多边形覆盖物对象
27
27
  var polygon: MAPolygon?
28
28
  /// 多边形渲染器
29
29
  private var renderer: MAPolygonRenderer?
30
+ /// 上次设置的地图引用(防止重复调用)
31
+ private weak var lastSetMapView: MAMapView?
30
32
 
31
33
  required init(appContext: AppContext? = nil) {
32
34
  super.init(appContext: appContext)
35
+
36
+ // 🔑 关键修复:PolygonView 不应该拦截触摸事件
37
+ self.isUserInteractionEnabled = false
38
+ }
39
+
40
+ /**
41
+ * 重写 hitTest,让触摸事件完全穿透此视图
42
+ */
43
+ override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
44
+ return nil
45
+ }
46
+
47
+ /**
48
+ * 重写 point(inside:with:),确保此视图不响应任何触摸
49
+ */
50
+ override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
51
+ return false
52
+ }
53
+
54
+ /**
55
+ * 检查地图是否已连接
56
+ */
57
+ func isMapConnected() -> Bool {
58
+ return mapView != nil
33
59
  }
34
60
 
35
61
  /**
@@ -37,7 +63,11 @@ class PolygonView: ExpoView {
37
63
  * @param map 地图视图
38
64
  */
39
65
  func setMap(_ map: MAMapView) {
66
+ let isNewMap = self.mapView == nil
40
67
  self.mapView = map
68
+
69
+ // 无论是否是新地图,都调用 updatePolygon
70
+ // 这确保了即使在 setMap 之前设置了 props,覆盖物也能被正确创建
41
71
  updatePolygon()
42
72
  }
43
73
 
@@ -48,11 +78,19 @@ class PolygonView: ExpoView {
48
78
  guard let mapView = mapView else { return }
49
79
  if let old = polygon { mapView.remove(old) }
50
80
 
81
+ // 🔑 坐标验证和过滤
51
82
  var coords = points.compactMap { point -> CLLocationCoordinate2D? in
52
- guard let lat = point["latitude"], let lng = point["longitude"] else { return nil }
83
+ guard let lat = point["latitude"],
84
+ let lng = point["longitude"],
85
+ lat >= -90 && lat <= 90,
86
+ lng >= -180 && lng <= 180 else {
87
+ return nil
88
+ }
53
89
  return CLLocationCoordinate2D(latitude: lat, longitude: lng)
54
90
  }
55
- guard !coords.isEmpty else { return }
91
+
92
+ // 🔑 至少需要3个点才能绘制多边形
93
+ guard coords.count >= 3 else { return }
56
94
 
57
95
  polygon = MAPolygon(coordinates: &coords, count: UInt(coords.count))
58
96
  mapView.add(polygon!)
@@ -72,10 +110,6 @@ class PolygonView: ExpoView {
72
110
  renderer?.fillColor = parsedFillColor ?? UIColor.clear
73
111
  renderer?.strokeColor = parsedStrokeColor ?? UIColor.clear
74
112
  renderer?.lineWidth = CGFloat(strokeWidth)
75
- print("🔶 PolygonView.getRenderer: 创建新 renderer")
76
- print("🔶 PolygonView.getRenderer: fillColor=\(String(describing: parsedFillColor)), strokeColor=\(String(describing: parsedStrokeColor)), lineWidth=\(strokeWidth)")
77
- } else {
78
- print("🔶 PolygonView.getRenderer: 使用缓存的 renderer")
79
113
  }
80
114
  return renderer!
81
115
  }
@@ -94,7 +128,6 @@ class PolygonView: ExpoView {
94
128
  * @param color 颜色值
95
129
  */
96
130
  func setFillColor(_ color: Any?) {
97
- print("🔶 PolygonView.setFillColor: \(String(describing: color))")
98
131
  fillColor = color
99
132
  renderer = nil
100
133
  updatePolygon()
@@ -105,7 +138,6 @@ class PolygonView: ExpoView {
105
138
  * @param color 颜色值
106
139
  */
107
140
  func setStrokeColor(_ color: Any?) {
108
- print("🔶 PolygonView.setStrokeColor: \(String(describing: color))")
109
141
  strokeColor = color
110
142
  renderer = nil
111
143
  updatePolygon()
@@ -116,18 +148,37 @@ class PolygonView: ExpoView {
116
148
  * @param width 宽度值
117
149
  */
118
150
  func setStrokeWidth(_ width: Float) {
119
- print("🔶 PolygonView.setStrokeWidth: \(width)")
120
151
  strokeWidth = width
121
152
  renderer = nil
122
153
  updatePolygon()
123
154
  }
124
155
 
125
156
  /**
126
- * 析构时移除多边形
157
+ * 视图即将从父视图移除时调用
158
+ * 🔑 关键修复:旧架构下,React Native 移除视图时不一定立即调用 deinit
159
+ * 需要在 willMove(toSuperview:) 中立即清理地图覆盖物
160
+ */
161
+ override func willMove(toSuperview newSuperview: UIView?) {
162
+ super.willMove(toSuperview: newSuperview)
163
+
164
+ // 当 newSuperview 为 nil 时,表示视图正在从父视图移除
165
+ if newSuperview == nil {
166
+ if let mapView = mapView, let polygon = polygon {
167
+ mapView.remove(polygon)
168
+ self.polygon = nil
169
+ }
170
+ }
171
+ }
172
+
173
+ /**
174
+ * 析构时移除多边形(双重保险)
127
175
  */
128
176
  deinit {
129
177
  if let mapView = mapView, let polygon = polygon {
130
178
  mapView.remove(polygon)
131
179
  }
180
+ mapView = nil
181
+ polygon = nil
182
+ renderer = nil
132
183
  }
133
184
  }
@@ -5,6 +5,8 @@ public class PolygonViewModule: Module {
5
5
  Name("PolygonView")
6
6
 
7
7
  View(PolygonView.self) {
8
+ Events("onPolygonPress")
9
+
8
10
  Prop("points") { (view: PolygonView, points: [[String: Double]]) in
9
11
  view.setPoints(points)
10
12
  }
@@ -20,6 +22,21 @@ public class PolygonViewModule: Module {
20
22
  Prop("strokeWidth") { (view: PolygonView, width: Double) in
21
23
  view.setStrokeWidth(Float(width))
22
24
  }
25
+
26
+ OnViewDidUpdateProps { (view: PolygonView) in
27
+ // 属性更新完成后,如果还没连接地图,尝试连接
28
+ if !view.isMapConnected() {
29
+ // 查找父视图 ExpoGaodeMapView
30
+ var parent = view.superview
31
+ while parent != nil {
32
+ if let mapView = parent as? ExpoGaodeMapView {
33
+ view.setMap(mapView.mapView)
34
+ return
35
+ }
36
+ parent = parent?.superview
37
+ }
38
+ }
39
+ }
23
40
  }
24
41
  }
25
42
  }
@@ -6,7 +6,7 @@ import MAMapKit
6
6
  *
7
7
  * 负责:
8
8
  * - 在地图上绘制折线
9
- * - 支持纹理贴图
9
+ * - 支持纹理贴图(仅 3D 地图支持)
10
10
  * - 管理折线样式(线宽、颜色)
11
11
  */
12
12
  class PolylineView: ExpoView {
@@ -22,17 +22,43 @@ class PolylineView: ExpoView {
22
22
  var textureUrl: String?
23
23
 
24
24
  /// 点击事件派发器
25
- let onPress = EventDispatcher()
25
+ let onPolylinePress = EventDispatcher()
26
26
 
27
- /// 地图视图弱引用
27
+ /// 地图视图引用
28
28
  private var mapView: MAMapView?
29
29
  /// 折线覆盖物对象
30
30
  var polyline: MAPolyline?
31
31
  /// 折线渲染器
32
32
  private var renderer: MAPolylineRenderer?
33
+ /// 上次设置的地图引用(防止重复调用)
34
+ private weak var lastSetMapView: MAMapView?
33
35
 
34
36
  required init(appContext: AppContext? = nil) {
35
37
  super.init(appContext: appContext)
38
+
39
+ // 🔑 关键修复:PolylineView 不应该拦截触摸事件
40
+ self.isUserInteractionEnabled = false
41
+ }
42
+
43
+ /**
44
+ * 重写 hitTest,让触摸事件完全穿透此视图
45
+ */
46
+ override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
47
+ return nil
48
+ }
49
+
50
+ /**
51
+ * 重写 point(inside:with:),确保此视图不响应任何触摸
52
+ */
53
+ override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
54
+ return false
55
+ }
56
+
57
+ /**
58
+ * 检查地图是否已连接
59
+ */
60
+ func isMapConnected() -> Bool {
61
+ return mapView != nil
36
62
  }
37
63
 
38
64
  /**
@@ -40,6 +66,12 @@ class PolylineView: ExpoView {
40
66
  * @param map 地图视图
41
67
  */
42
68
  func setMap(_ map: MAMapView) {
69
+ // 🔑 关键优化:如果是同一个地图引用,跳过重复设置
70
+ if lastSetMapView === map {
71
+ return
72
+ }
73
+
74
+ lastSetMapView = map
43
75
  self.mapView = map
44
76
  updatePolyline()
45
77
  }
@@ -51,11 +83,19 @@ class PolylineView: ExpoView {
51
83
  guard let mapView = mapView else { return }
52
84
  if let old = polyline { mapView.remove(old) }
53
85
 
86
+ // 🔑 坐标验证和过滤
54
87
  var coords = points.compactMap { point -> CLLocationCoordinate2D? in
55
- guard let lat = point["latitude"], let lng = point["longitude"] else { return nil }
88
+ guard let lat = point["latitude"],
89
+ let lng = point["longitude"],
90
+ lat >= -90 && lat <= 90,
91
+ lng >= -180 && lng <= 180 else {
92
+ return nil
93
+ }
56
94
  return CLLocationCoordinate2D(latitude: lat, longitude: lng)
57
95
  }
58
- guard !coords.isEmpty else { return }
96
+
97
+ // 🔑 至少需要2个点才能绘制折线
98
+ guard coords.count >= 2 else { return }
59
99
 
60
100
  polyline = MAPolyline(coordinates: &coords, count: UInt(coords.count))
61
101
  mapView.add(polyline!)
@@ -72,19 +112,12 @@ class PolylineView: ExpoView {
72
112
  renderer = MAPolylineRenderer(polyline: polyline)
73
113
  renderer?.lineWidth = CGFloat(strokeWidth)
74
114
 
75
- // 注意: iOS 高德地图 SDK 不支持简单的虚线设置
76
- // 需要使用 MAMultiPolyline 实现虚线,暂不支持
77
-
78
115
  if let url = textureUrl {
79
- print("🔷 PolylineView.getRenderer: 加载纹理 \(url)")
80
116
  loadTexture(url: url, renderer: renderer!)
81
117
  } else {
82
118
  let parsedColor = ColorParser.parseColor(strokeColor)
83
119
  renderer?.strokeColor = parsedColor ?? UIColor.clear
84
- print("🔷 PolylineView.getRenderer: 创建新 renderer, strokeColor=\(String(describing: parsedColor)), lineWidth=\(strokeWidth)")
85
120
  }
86
- } else {
87
- print("🔷 PolylineView.getRenderer: 使用缓存的 renderer")
88
121
  }
89
122
  return renderer!
90
123
  }
@@ -124,15 +157,19 @@ class PolylineView: ExpoView {
124
157
 
125
158
  /**
126
159
  * 应用纹理到折线渲染器
160
+ *
161
+ * 根据高德地图官方文档:
162
+ * - 仅 3D 地图支持纹理
163
+ * - 纹理须是正方形,宽高是2的整数幂(如64x64)
164
+ * - 若设置了纹理,线颜色、连接类型和端点类型将无效
165
+ *
127
166
  * @param image 纹理图片
128
167
  * @param renderer 折线渲染器
129
168
  */
130
169
  private func applyTexture(image: UIImage, to renderer: MAPolylineRenderer) {
131
- let selector = NSSelectorFromString("loadStrokeTextureImage:")
132
- if renderer.responds(to: selector) {
133
- renderer.perform(selector, with: image)
134
- mapView?.setNeedsDisplay()
135
- }
170
+ // 🔑 关键修复:使用 strokeImage 属性设置纹理(与命令式 API 一致)
171
+ renderer.strokeImage = image
172
+ mapView?.setNeedsDisplay()
136
173
  }
137
174
 
138
175
  /**
@@ -149,10 +186,9 @@ class PolylineView: ExpoView {
149
186
  * @param width 线宽值
150
187
  */
151
188
  func setStrokeWidth(_ width: Float) {
152
- print("🔷 PolylineView.setStrokeWidth: \(width)")
153
189
  strokeWidth = width
154
190
  renderer = nil
155
- updatePolyline()
191
+ forceRerender()
156
192
  }
157
193
 
158
194
  /**
@@ -160,10 +196,9 @@ class PolylineView: ExpoView {
160
196
  * @param color 颜色值
161
197
  */
162
198
  func setStrokeColor(_ color: Any?) {
163
- print("🔷 PolylineView.setStrokeColor: \(String(describing: color))")
164
199
  strokeColor = color
165
200
  renderer = nil
166
- updatePolyline()
201
+ forceRerender()
167
202
  }
168
203
 
169
204
  /**
@@ -171,24 +206,59 @@ class PolylineView: ExpoView {
171
206
  * @param url 图片 URL
172
207
  */
173
208
  func setTexture(_ url: String?) {
174
- print("🔷 PolylineView.setTexture: \(String(describing: url))")
175
209
  textureUrl = url
176
210
  renderer = nil
177
- updatePolyline()
211
+ forceRerender()
212
+ }
213
+
214
+ /**
215
+ * 强制重新渲染折线
216
+ * 通过移除并重新添加 overlay 来触发地图重新请求 renderer
217
+ */
218
+ private func forceRerender() {
219
+ guard let mapView = mapView, let polyline = polyline else {
220
+ return
221
+ }
222
+
223
+ // 移除旧的 overlay
224
+ mapView.remove(polyline)
225
+
226
+ // 重新添加(地图会调用 rendererFor overlay)
227
+ mapView.add(polyline)
178
228
  }
179
229
 
180
230
  func setDotted(_ dotted: Bool) {
181
231
  isDotted = dotted
182
232
  renderer = nil
183
- updatePolyline()
233
+ forceRerender()
184
234
  }
185
235
 
186
236
  /**
187
- * 析构时移除折线
237
+ * 视图即将从父视图移除时调用
238
+ * 🔑 关键修复:旧架构下,React Native 移除视图时不一定立即调用 deinit
239
+ * 需要在 willMove(toSuperview:) 中立即清理地图覆盖物
240
+ */
241
+ override func willMove(toSuperview newSuperview: UIView?) {
242
+ super.willMove(toSuperview: newSuperview)
243
+
244
+ // 当 newSuperview 为 nil 时,表示视图正在从父视图移除
245
+ if newSuperview == nil {
246
+ if let mapView = mapView, let polyline = polyline {
247
+ mapView.remove(polyline)
248
+ self.polyline = nil
249
+ }
250
+ }
251
+ }
252
+
253
+ /**
254
+ * 析构时移除折线(双重保险)
188
255
  */
189
256
  deinit {
190
257
  if let mapView = mapView, let polyline = polyline {
191
258
  mapView.remove(polyline)
192
259
  }
260
+ mapView = nil
261
+ polyline = nil
262
+ renderer = nil
193
263
  }
194
264
  }
@@ -5,22 +5,16 @@ public class PolylineViewModule: Module {
5
5
  Name("PolylineView")
6
6
 
7
7
  View(PolylineView.self) {
8
+ Events("onPolylinePress")
9
+
8
10
  Prop("points") { (view: PolylineView, points: [[String: Double]]) in
9
11
  view.setPoints(points)
10
12
  }
11
13
 
12
- Prop("width") { (view: PolylineView, width: Double) in
13
- view.setStrokeWidth(Float(width))
14
- }
15
-
16
14
  Prop("strokeWidth") { (view: PolylineView, width: Double) in
17
15
  view.setStrokeWidth(Float(width))
18
16
  }
19
17
 
20
- Prop("color") { (view: PolylineView, color: String) in
21
- view.setStrokeColor(color)
22
- }
23
-
24
18
  Prop("strokeColor") { (view: PolylineView, color: String) in
25
19
  view.setStrokeColor(color)
26
20
  }
@@ -32,6 +26,21 @@ public class PolylineViewModule: Module {
32
26
  Prop("dotted") { (view: PolylineView, dotted: Bool) in
33
27
  view.setDotted(dotted)
34
28
  }
29
+
30
+ OnViewDidUpdateProps { (view: PolylineView) in
31
+ // 属性更新完成后,如果还没连接地图,尝试连接
32
+ if !view.isMapConnected() {
33
+ // 查找父视图 ExpoGaodeMapView
34
+ var parent = view.superview
35
+ while parent != nil {
36
+ if let mapView = parent as? ExpoGaodeMapView {
37
+ view.setMap(mapView.mapView)
38
+ return
39
+ }
40
+ parent = parent?.superview
41
+ }
42
+ }
43
+ }
35
44
  }
36
45
  }
37
46
  }
@@ -27,18 +27,14 @@ class PermissionManager: NSObject, CLLocationManagerDelegate {
27
27
  guard let self = self else { return }
28
28
 
29
29
  if self.locationManager == nil {
30
- print("🔐 [PermissionManager] 创建 CLLocationManager")
31
30
  self.locationManager = CLLocationManager()
32
31
  self.locationManager?.delegate = self
33
- print("🔐 [PermissionManager] delegate 已设置: \(self.locationManager?.delegate != nil)")
34
32
  }
35
33
 
36
34
  let currentStatus = CLLocationManager.authorizationStatus()
37
- print("🔐 [PermissionManager] 当前权限状态: \(self.getAuthorizationStatusString(currentStatus))")
38
35
 
39
36
  // 如果已经有权限,直接返回
40
37
  if currentStatus == .authorizedAlways || currentStatus == .authorizedWhenInUse {
41
- print("🔐 [PermissionManager] 已有权限,直接返回")
42
38
  self.permissionCallback?(true, self.getAuthorizationStatusString(currentStatus))
43
39
  self.permissionCallback = nil
44
40
  return
@@ -46,15 +42,12 @@ class PermissionManager: NSObject, CLLocationManagerDelegate {
46
42
 
47
43
  // 如果已经被拒绝,直接返回
48
44
  if currentStatus == .denied || currentStatus == .restricted {
49
- print("🔐 [PermissionManager] 权限已被拒绝")
50
45
  self.permissionCallback?(false, self.getAuthorizationStatusString(currentStatus))
51
46
  self.permissionCallback = nil
52
47
  return
53
48
  }
54
49
 
55
- print("🔐 [PermissionManager] 调用 requestWhenInUseAuthorization()")
56
50
  self.locationManager?.requestWhenInUseAuthorization()
57
- print("🔐 [PermissionManager] requestWhenInUseAuthorization() 调用完成")
58
51
  }
59
52
  }
60
53
 
@@ -62,7 +55,6 @@ class PermissionManager: NSObject, CLLocationManagerDelegate {
62
55
  * 权限状态变化回调 (iOS 14+)
63
56
  */
64
57
  func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
65
- print("🔐 [PermissionManager] locationManagerDidChangeAuthorization 被调用")
66
58
  handleAuthorizationChange(manager.authorizationStatus)
67
59
  }
68
60
 
@@ -70,7 +62,6 @@ class PermissionManager: NSObject, CLLocationManagerDelegate {
70
62
  * 权限状态变化回调 (iOS 13 及以下,兼容旧版本)
71
63
  */
72
64
  func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
73
- print("🔐 [PermissionManager] didChangeAuthorization 被调用")
74
65
  handleAuthorizationChange(status)
75
66
  }
76
67
 
@@ -78,11 +69,8 @@ class PermissionManager: NSObject, CLLocationManagerDelegate {
78
69
  * 处理权限状态变化
79
70
  */
80
71
  private func handleAuthorizationChange(_ status: CLAuthorizationStatus) {
81
- print("🔐 [PermissionManager] 当前状态: \(getAuthorizationStatusString(status))")
82
-
83
72
  // 如果状态仍是 notDetermined,说明用户还没有做出选择,忽略这次回调
84
73
  if status == .notDetermined {
85
- print("🔐 [PermissionManager] 状态仍为 notDetermined,等待用户选择")
86
74
  return
87
75
  }
88
76
 
@@ -90,8 +78,6 @@ class PermissionManager: NSObject, CLLocationManagerDelegate {
90
78
  let granted = status == .authorizedAlways || status == .authorizedWhenInUse
91
79
  let statusString = getAuthorizationStatusString(status)
92
80
 
93
- print("🔐 [PermissionManager] 返回结果: granted=\(granted), status=\(statusString)")
94
-
95
81
  permissionCallback?(granted, statusString)
96
82
  permissionCallback = nil
97
83
  }
@@ -109,4 +95,13 @@ class PermissionManager: NSObject, CLLocationManagerDelegate {
109
95
  @unknown default: return "unknown"
110
96
  }
111
97
  }
98
+
99
+ /**
100
+ * 析构函数 - 清理资源
101
+ */
102
+ deinit {
103
+ locationManager?.delegate = nil
104
+ locationManager = nil
105
+ permissionCallback = nil
106
+ }
112
107
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-gaode-map",
3
- "version": "1.1.8",
3
+ "version": "2.0.0-alpha.1",
4
4
  "description": "一个功能完整的高德地图 React Native 组件库,基于 Expo Modules 开发,提供地图显示、定位、覆盖物等功能。",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -13,8 +13,9 @@
13
13
  "prepublishOnly": "expo-module prepublishOnly",
14
14
  "expo-module": "expo-module",
15
15
  "open:ios": "xed example/ios",
16
- "npm:publish": "npm publish",
17
- "open:android": "open -a \"Android Studio\" example/android"
16
+ "open:android": "open -a \"Android Studio\" example/android",
17
+ "publish:next": "npm publish --tag next",
18
+ "publish:latest": "npm publish --tag latest"
18
19
  },
19
20
  "keywords": [
20
21
  "react-native",
@@ -1,4 +1,8 @@
1
+ /**
2
+ * 高德地图 Expo 模块类型定义
3
+ */
1
4
 
5
+ import type { Coordinates, ReGeocode } from './types';
2
6
 
3
7
  // 导出所有类型定义
4
8
  export * from './types';
@@ -20,6 +24,7 @@ export type {
20
24
  Coordinates,
21
25
  ReGeocode,
22
26
  LocationOptions,
27
+ LocationListener,
23
28
 
24
29
  // 覆盖物
25
30
  MarkerProps,
@@ -40,17 +45,37 @@ export {
40
45
 
41
46
  /**
42
47
  * Expo 模块事件类型
48
+ * 定义了原生模块可以触发的事件
43
49
  */
44
50
  export type ExpoGaodeMapModuleEvents = {
45
51
  /**
46
52
  * 定位更新事件
53
+ * 当位置发生变化时触发
54
+ * @param location 位置信息,包含坐标和可选的逆地理编码信息
47
55
  */
48
- onLocationUpdate: (location: any) => void;
56
+ onLocationUpdate: (location: Coordinates | ReGeocode) => void;
49
57
 
50
58
  /**
51
- * 定位错误事件
59
+ * 方向更新事件(iOS)
60
+ * 当设备方向发生变化时触发
61
+ * @param heading 方向信息
52
62
  */
53
- onLocationError: (error: { code: number; message: string }) => void;
63
+ onHeadingUpdate: (heading: {
64
+ /** 磁北方向角度 (0-359.9) */
65
+ magneticHeading: number;
66
+ /** 真北方向角度 (0-359.9) */
67
+ trueHeading: number;
68
+ /** 方向精度 */
69
+ headingAccuracy: number;
70
+ /** X 轴原始数据 */
71
+ x: number;
72
+ /** Y 轴原始数据 */
73
+ y: number;
74
+ /** Z 轴原始数据 */
75
+ z: number;
76
+ /** 时间戳 */
77
+ timestamp: number;
78
+ }) => void;
54
79
  };
55
80
 
56
81
  /**