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.
- package/README.en.md +32 -46
- package/README.md +50 -70
- package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapView.kt +37 -268
- package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapViewModule.kt +1 -49
- package/android/src/main/java/expo/modules/gaodemap/managers/CameraManager.kt +30 -7
- package/android/src/main/java/expo/modules/gaodemap/managers/UIManager.kt +1 -0
- package/android/src/main/java/expo/modules/gaodemap/modules/LocationManager.kt +10 -1
- package/android/src/main/java/expo/modules/gaodemap/overlays/CircleView.kt +38 -14
- package/android/src/main/java/expo/modules/gaodemap/overlays/CircleViewModule.kt +3 -3
- package/android/src/main/java/expo/modules/gaodemap/overlays/ClusterView.kt +8 -1
- package/android/src/main/java/expo/modules/gaodemap/overlays/HeatMapView.kt +4 -1
- package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerView.kt +322 -93
- package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerViewModule.kt +11 -3
- package/android/src/main/java/expo/modules/gaodemap/overlays/MultiPointView.kt +4 -1
- package/android/src/main/java/expo/modules/gaodemap/overlays/PolygonView.kt +25 -11
- package/android/src/main/java/expo/modules/gaodemap/overlays/PolygonViewModule.kt +3 -3
- package/android/src/main/java/expo/modules/gaodemap/overlays/PolylineView.kt +20 -10
- package/android/src/main/java/expo/modules/gaodemap/overlays/PolylineViewModule.kt +6 -2
- package/build/ExpoGaodeMap.types.d.ts +27 -6
- package/build/ExpoGaodeMap.types.d.ts.map +1 -1
- package/build/ExpoGaodeMap.types.js +3 -0
- package/build/ExpoGaodeMap.types.js.map +1 -1
- package/build/ExpoGaodeMapModule.d.ts +157 -10
- package/build/ExpoGaodeMapModule.d.ts.map +1 -1
- package/build/ExpoGaodeMapModule.js +4 -0
- package/build/ExpoGaodeMapModule.js.map +1 -1
- package/build/ExpoGaodeMapView.d.ts +1 -17
- package/build/ExpoGaodeMapView.d.ts.map +1 -1
- package/build/ExpoGaodeMapView.js +4 -221
- package/build/ExpoGaodeMapView.js.map +1 -1
- package/build/components/overlays/Circle.d.ts +11 -1
- package/build/components/overlays/Circle.d.ts.map +1 -1
- package/build/components/overlays/Circle.js +12 -58
- package/build/components/overlays/Circle.js.map +1 -1
- package/build/components/overlays/Cluster.d.ts.map +1 -1
- package/build/components/overlays/Cluster.js.map +1 -1
- package/build/components/overlays/Marker.d.ts +13 -1
- package/build/components/overlays/Marker.d.ts.map +1 -1
- package/build/components/overlays/Marker.js +51 -115
- package/build/components/overlays/Marker.js.map +1 -1
- package/build/components/overlays/Polygon.d.ts +7 -15
- package/build/components/overlays/Polygon.d.ts.map +1 -1
- package/build/components/overlays/Polygon.js +10 -80
- package/build/components/overlays/Polygon.js.map +1 -1
- package/build/components/overlays/Polyline.d.ts +7 -14
- package/build/components/overlays/Polyline.d.ts.map +1 -1
- package/build/components/overlays/Polyline.js +9 -66
- package/build/components/overlays/Polyline.js.map +1 -1
- package/build/index.d.ts +1 -4
- package/build/index.d.ts.map +1 -1
- package/build/index.js +2 -10
- package/build/index.js.map +1 -1
- package/build/types/map-view.types.d.ts +0 -90
- package/build/types/map-view.types.d.ts.map +1 -1
- package/build/types/map-view.types.js.map +1 -1
- package/build/types/overlays.types.d.ts +9 -9
- package/build/types/overlays.types.d.ts.map +1 -1
- package/build/types/overlays.types.js.map +1 -1
- package/docs/API.en.md +1 -21
- package/docs/API.md +84 -56
- package/docs/EXAMPLES.en.md +0 -48
- package/docs/EXAMPLES.md +49 -102
- package/docs/INITIALIZATION.md +59 -71
- package/docs/MIGRATION.md +423 -0
- package/ios/ExpoGaodeMapView.swift +317 -258
- package/ios/ExpoGaodeMapViewModule.swift +3 -50
- package/ios/managers/CameraManager.swift +23 -2
- package/ios/managers/UIManager.swift +10 -5
- package/ios/modules/LocationManager.swift +10 -0
- package/ios/overlays/CircleView.swift +98 -19
- package/ios/overlays/CircleViewModule.swift +21 -0
- package/ios/overlays/ClusterView.swift +33 -4
- package/ios/overlays/HeatMapView.swift +16 -4
- package/ios/overlays/MarkerView.swift +235 -146
- package/ios/overlays/MarkerViewModule.swift +7 -3
- package/ios/overlays/MultiPointView.swift +30 -1
- package/ios/overlays/PolygonView.swift +63 -12
- package/ios/overlays/PolygonViewModule.swift +17 -0
- package/ios/overlays/PolylineView.swift +95 -25
- package/ios/overlays/PolylineViewModule.swift +17 -8
- package/ios/utils/PermissionManager.swift +9 -14
- package/package.json +4 -3
- package/src/ExpoGaodeMap.types.ts +28 -3
- package/src/ExpoGaodeMapModule.ts +201 -12
- package/src/ExpoGaodeMapView.tsx +9 -234
- package/src/components/overlays/Circle.tsx +14 -70
- package/src/components/overlays/Cluster.tsx +0 -1
- package/src/components/overlays/Marker.tsx +63 -138
- package/src/components/overlays/Polygon.tsx +12 -92
- package/src/components/overlays/Polyline.tsx +11 -77
- package/src/index.ts +4 -29
- package/src/types/map-view.types.ts +1 -85
- package/src/types/overlays.types.ts +9 -9
- package/android/src/main/java/expo/modules/gaodemap/managers/OverlayManager.kt +0 -574
- package/build/modules/AMapLocation.d.ts +0 -78
- package/build/modules/AMapLocation.d.ts.map +0 -1
- package/build/modules/AMapLocation.js +0 -132
- package/build/modules/AMapLocation.js.map +0 -1
- package/build/modules/AMapPermissions.d.ts +0 -29
- package/build/modules/AMapPermissions.d.ts.map +0 -1
- package/build/modules/AMapPermissions.js +0 -23
- package/build/modules/AMapPermissions.js.map +0 -1
- package/build/modules/AMapSDK.d.ts +0 -22
- package/build/modules/AMapSDK.d.ts.map +0 -1
- package/build/modules/AMapSDK.js +0 -25
- package/build/modules/AMapSDK.js.map +0 -1
- package/build/modules/AMapView.d.ts +0 -44
- package/build/modules/AMapView.d.ts.map +0 -1
- package/build/modules/AMapView.js +0 -65
- package/build/modules/AMapView.js.map +0 -1
- package/ios/managers/OverlayManager.swift +0 -522
- package/src/modules/AMapLocation.ts +0 -165
- package/src/modules/AMapPermissions.ts +0 -41
- package/src/modules/AMapSDK.ts +0 -31
- package/src/modules/AMapView.ts +0 -72
|
@@ -10,7 +10,7 @@ import MAMapKit
|
|
|
10
10
|
* - 响应属性变化并更新渲染
|
|
11
11
|
*/
|
|
12
12
|
class PolygonView: ExpoView {
|
|
13
|
-
let
|
|
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"],
|
|
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
|
-
|
|
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
|
|
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"],
|
|
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
|
-
|
|
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
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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": "
|
|
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
|
-
"
|
|
17
|
-
"
|
|
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:
|
|
56
|
+
onLocationUpdate: (location: Coordinates | ReGeocode) => void;
|
|
49
57
|
|
|
50
58
|
/**
|
|
51
|
-
*
|
|
59
|
+
* 方向更新事件(iOS)
|
|
60
|
+
* 当设备方向发生变化时触发
|
|
61
|
+
* @param heading 方向信息
|
|
52
62
|
*/
|
|
53
|
-
|
|
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
|
/**
|