expo-gaode-map 1.1.5 → 1.1.7
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/src/main/java/expo/modules/gaodemap/ExpoGaodeMapView.kt +637 -627
- package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapViewModule.kt +0 -2
- package/android/src/main/java/expo/modules/gaodemap/managers/OverlayManager.kt +3 -15
- package/android/src/main/java/expo/modules/gaodemap/managers/UIManager.kt +5 -56
- package/android/src/main/java/expo/modules/gaodemap/modules/SDKInitializer.kt +0 -1
- package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerView.kt +139 -175
- package/ios/ExpoGaodeMapModule.swift +0 -4
- package/ios/ExpoGaodeMapView.swift +24 -63
- package/ios/managers/OverlayManager.swift +0 -6
- package/ios/overlays/CircleView.swift +0 -3
- package/ios/overlays/ClusterViewModule.swift +0 -2
- package/ios/overlays/MarkerView.swift +21 -4
- package/ios/overlays/MultiPointViewModule.swift +0 -2
- package/ios/overlays/PolygonView.swift +2 -12
- package/ios/overlays/PolylineView.swift +2 -12
- package/ios/utils/PermissionManager.swift +0 -1
- package/package.json +1 -1
- package/test/ClockMapView.tsx +37 -9
- package/test/useMap.ts +35 -23
|
@@ -82,41 +82,35 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
|
|
|
82
82
|
private var isMapLoaded = false
|
|
83
83
|
/// 是否正在处理 annotation 选择事件
|
|
84
84
|
private var isHandlingAnnotationSelect = false
|
|
85
|
+
/// MarkerView 的隐藏容器(用于渲染 children)
|
|
86
|
+
private var markerContainer: UIView!
|
|
85
87
|
|
|
86
88
|
// MARK: - 初始化
|
|
87
89
|
|
|
88
90
|
required init(appContext: AppContext? = nil) {
|
|
89
91
|
super.init(appContext: appContext)
|
|
90
92
|
|
|
91
|
-
print("🗺️ [MapView Init] 开始初始化地图视图")
|
|
92
|
-
print("🗺️ [MapView Init] bounds: \(bounds)")
|
|
93
|
-
|
|
94
93
|
// 确保隐私合规已设置
|
|
95
94
|
MAMapView.updatePrivacyAgree(.didAgree)
|
|
96
95
|
MAMapView.updatePrivacyShow(.didShow, privacyInfo: .didContain)
|
|
97
|
-
print("🗺️ [MapView Init] 隐私合规设置完成")
|
|
98
96
|
|
|
99
|
-
// 创建 MAMapView
|
|
97
|
+
// 创建 MAMapView
|
|
100
98
|
mapView = MAMapView(frame: bounds)
|
|
101
99
|
|
|
102
|
-
// 检查是否创建成功
|
|
103
|
-
if mapView == nil {
|
|
104
|
-
print("❌ [MapView Init] MAMapView 创建失败!请检查:")
|
|
105
|
-
print("❌ [MapView Init] 1. iOS API Key 是否已正确配置")
|
|
106
|
-
print("❌ [MapView Init] 2. 是否调用了 initSDK({ iosKey: 'your_key' })")
|
|
107
|
-
print("❌ [MapView Init] 3. API Key 是否有效")
|
|
108
|
-
} else {
|
|
109
|
-
print("🗺️ [MapView Init] ✅ MAMapView 创建成功, frame: \(mapView.frame)")
|
|
110
|
-
}
|
|
111
|
-
|
|
112
100
|
mapView.delegate = self
|
|
113
101
|
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
114
102
|
|
|
115
|
-
//
|
|
103
|
+
// 创建 MarkerView 隐藏容器
|
|
104
|
+
markerContainer = UIView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
105
|
+
markerContainer.isHidden = true
|
|
106
|
+
markerContainer.isUserInteractionEnabled = false
|
|
107
|
+
markerContainer.alpha = 0
|
|
108
|
+
|
|
109
|
+
// 先添加隐藏容器(在最底层)
|
|
110
|
+
addSubview(markerContainer)
|
|
111
|
+
|
|
112
|
+
// 再添加 mapView(在隐藏容器之上,确保地图可以接收触摸)
|
|
116
113
|
addSubview(mapView)
|
|
117
|
-
print("🗺️ [MapView Init] ✅ mapView 已添加到视图层级")
|
|
118
|
-
print("🗺️ [MapView Init] mapView.superview: \(mapView.superview != nil ? "存在" : "nil")")
|
|
119
|
-
print("🗺️ [MapView Init] subviews.count: \(subviews.count)")
|
|
120
114
|
|
|
121
115
|
cameraManager = CameraManager(mapView: mapView)
|
|
122
116
|
uiManager = UIManager(mapView: mapView)
|
|
@@ -145,17 +139,11 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
|
|
|
145
139
|
}
|
|
146
140
|
|
|
147
141
|
setupDefaultConfig()
|
|
148
|
-
print("🗺️ [MapView Init] 初始化完成")
|
|
149
142
|
}
|
|
150
143
|
|
|
151
144
|
override func layoutSubviews() {
|
|
152
145
|
super.layoutSubviews()
|
|
153
|
-
print("🗺️ [MapView Layout] layoutSubviews 被调用")
|
|
154
|
-
print("🗺️ [MapView Layout] 旧 frame: \(mapView.frame), 新 bounds: \(bounds)")
|
|
155
146
|
mapView.frame = bounds
|
|
156
|
-
print("🗺️ [MapView Layout] mapView frame 已更新: \(mapView.frame)")
|
|
157
|
-
print("🗺️ [MapView Layout] mapView.superview: \(mapView.superview != nil ? "存在" : "nil")")
|
|
158
|
-
print("🗺️ [MapView Layout] subviews.count: \(subviews.count)")
|
|
159
147
|
|
|
160
148
|
// 收集并设置 MarkerView
|
|
161
149
|
collectAndSetupMarkerViews()
|
|
@@ -165,7 +153,8 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
|
|
|
165
153
|
* 收集所有 MarkerView 子视图并设置地图
|
|
166
154
|
*/
|
|
167
155
|
private func collectAndSetupMarkerViews() {
|
|
168
|
-
|
|
156
|
+
// 从隐藏容器中收集 MarkerView
|
|
157
|
+
for subview in markerContainer.subviews {
|
|
169
158
|
if let markerView = subview as? MarkerView {
|
|
170
159
|
markerView.setMap(mapView)
|
|
171
160
|
}
|
|
@@ -177,16 +166,17 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
|
|
|
177
166
|
* 将地图实例传递给覆盖物子视图
|
|
178
167
|
*/
|
|
179
168
|
override func addSubview(_ view: UIView) {
|
|
180
|
-
super.addSubview(view)
|
|
181
|
-
|
|
182
169
|
if let markerView = view as? MarkerView {
|
|
183
|
-
//
|
|
184
|
-
//
|
|
185
|
-
|
|
170
|
+
// ✅ 关键修复:将 MarkerView 添加到隐藏容器中,而不是主视图
|
|
171
|
+
// 这样 MarkerView 完全不会影响地图的触摸事件
|
|
172
|
+
markerContainer.addSubview(markerView)
|
|
186
173
|
markerView.setMap(mapView)
|
|
187
174
|
return
|
|
188
175
|
}
|
|
189
176
|
|
|
177
|
+
// 其他视图正常添加
|
|
178
|
+
super.addSubview(view)
|
|
179
|
+
|
|
190
180
|
if let circleView = view as? CircleView {
|
|
191
181
|
circleView.setMap(mapView)
|
|
192
182
|
} else if let polylineView = view as? PolylineView {
|
|
@@ -221,16 +211,10 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
|
|
|
221
211
|
* 在 Props 更新时调用
|
|
222
212
|
*/
|
|
223
213
|
func applyProps() {
|
|
224
|
-
print("🗺️ [MapView Props] applyProps 被调用")
|
|
225
|
-
print("🗺️ [MapView Props] mapView.superview: \(mapView.superview != nil ? "存在" : "nil")")
|
|
226
|
-
print("🗺️ [MapView Props] mapView.frame: \(mapView.frame)")
|
|
227
|
-
print("🗺️ [MapView Props] initialCameraPosition: \(initialCameraPosition != nil ? "存在" : "nil")")
|
|
228
|
-
|
|
229
214
|
uiManager.setMapType(mapType)
|
|
230
215
|
|
|
231
216
|
// 如果有初始位置,设置相机位置
|
|
232
217
|
if let position = initialCameraPosition {
|
|
233
|
-
print("🗺️ [MapView Props] 设置初始相机位置: \(position)")
|
|
234
218
|
cameraManager.setInitialCameraPosition(position)
|
|
235
219
|
}
|
|
236
220
|
|
|
@@ -247,10 +231,6 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
|
|
|
247
231
|
|
|
248
232
|
// 收集并设置所有 MarkerView
|
|
249
233
|
collectAndSetupMarkerViews()
|
|
250
|
-
|
|
251
|
-
print("🗺️ [MapView Props] Props 应用完成")
|
|
252
|
-
print("🗺️ [MapView Props] 最终 mapView.superview: \(mapView.superview != nil ? "存在" : "nil")")
|
|
253
|
-
print("🗺️ [MapView Props] 最终 subviews.count: \(subviews.count)")
|
|
254
234
|
}
|
|
255
235
|
|
|
256
236
|
// MARK: - 缩放控制
|
|
@@ -384,16 +364,8 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
|
|
|
384
364
|
* 析构函数 - 清理资源
|
|
385
365
|
*/
|
|
386
366
|
deinit {
|
|
387
|
-
print("🗺️ [MapView] deinit 开始清理")
|
|
388
|
-
|
|
389
367
|
// 先设置 delegate 为 nil,停止接收回调
|
|
390
368
|
mapView?.delegate = nil
|
|
391
|
-
|
|
392
|
-
// 不调用 overlayManager.clear()
|
|
393
|
-
// 因为声明式的 Marker/Circle 等会在自己的 willMove(toSuperview:) 中清理
|
|
394
|
-
// 调用 clear() 可能导致重复移除和崩溃
|
|
395
|
-
|
|
396
|
-
print("🗺️ [MapView] deinit 完成")
|
|
397
369
|
}
|
|
398
370
|
}
|
|
399
371
|
|
|
@@ -406,9 +378,6 @@ extension ExpoGaodeMapView {
|
|
|
406
378
|
public func mapViewDidFinishLoadingMap(_ mapView: MAMapView) {
|
|
407
379
|
guard !isMapLoaded else { return }
|
|
408
380
|
isMapLoaded = true
|
|
409
|
-
print("🗺️ [MapView Delegate] ✅ 地图加载完成")
|
|
410
|
-
print("🗺️ [MapView Delegate] mapView.frame: \(mapView.frame)")
|
|
411
|
-
print("🗺️ [MapView Delegate] mapView.superview: \(mapView.superview != nil ? "存在" : "nil")")
|
|
412
381
|
onLoad(["loaded": true])
|
|
413
382
|
}
|
|
414
383
|
|
|
@@ -460,20 +429,14 @@ extension ExpoGaodeMapView {
|
|
|
460
429
|
*/
|
|
461
430
|
private func checkCirclePress(at coordinate: CLLocationCoordinate2D) -> Bool {
|
|
462
431
|
let circleViews = subviews.compactMap { $0 as? CircleView }
|
|
463
|
-
print("🔍 检查圆形点击 - 找到 \(circleViews.count) 个 CircleView")
|
|
464
432
|
|
|
465
433
|
for circleView in circleViews {
|
|
466
|
-
guard let circle = circleView.circle else {
|
|
467
|
-
print("⚠️ CircleView 没有 circle 对象")
|
|
468
|
-
continue
|
|
469
|
-
}
|
|
434
|
+
guard let circle = circleView.circle else { continue }
|
|
470
435
|
|
|
471
436
|
let circleCenter = circle.coordinate
|
|
472
437
|
let distance = calculateDistance(from: coordinate, to: circleCenter)
|
|
473
|
-
print("📍 圆心: (\(circleCenter.latitude), \(circleCenter.longitude)), 半径: \(circle.radius)m, 距离: \(distance)m")
|
|
474
438
|
|
|
475
439
|
if distance <= circle.radius {
|
|
476
|
-
print("✅ 点击在圆形内,触发 onPress")
|
|
477
440
|
circleView.onPress([
|
|
478
441
|
"latitude": coordinate.latitude,
|
|
479
442
|
"longitude": coordinate.longitude
|
|
@@ -481,7 +444,6 @@ extension ExpoGaodeMapView {
|
|
|
481
444
|
return true
|
|
482
445
|
}
|
|
483
446
|
}
|
|
484
|
-
print("❌ 点击不在任何圆形内")
|
|
485
447
|
return false
|
|
486
448
|
}
|
|
487
449
|
|
|
@@ -631,16 +593,15 @@ extension ExpoGaodeMapView {
|
|
|
631
593
|
|
|
632
594
|
if annotation.isKind(of: MAPointAnnotation.self) {
|
|
633
595
|
// 首先检查是否是声明式 MarkerView 的 annotation
|
|
634
|
-
|
|
596
|
+
// 从隐藏容器中查找 MarkerView
|
|
597
|
+
for subview in markerContainer.subviews {
|
|
635
598
|
if let markerView = subview as? MarkerView, markerView.annotation === annotation {
|
|
636
|
-
print("🎯 [MapView Delegate] 找到声明式 MarkerView,调用其 getAnnotationView")
|
|
637
599
|
return markerView.getAnnotationView(for: mapView, annotation: annotation)
|
|
638
600
|
}
|
|
639
601
|
}
|
|
640
602
|
|
|
641
603
|
// 如果不是声明式的,检查是否是命令式 API 的 Marker
|
|
642
604
|
guard let props = overlayManager.getMarkerProps(for: annotation) else {
|
|
643
|
-
print("⚠️ [MapView Delegate] 未找到对应的 Marker props")
|
|
644
605
|
return nil
|
|
645
606
|
}
|
|
646
607
|
|
|
@@ -320,20 +320,16 @@ class OverlayManager {
|
|
|
320
320
|
|
|
321
321
|
// 设置纹理或颜色
|
|
322
322
|
if let textureUrl = style?["texture"] as? String, !textureUrl.isEmpty {
|
|
323
|
-
print("🔷 OverlayManager: 加载纹理 \(textureUrl)")
|
|
324
323
|
loadPolylineTexture(url: textureUrl, renderer: renderer)
|
|
325
324
|
} else {
|
|
326
325
|
if let color = style?["color"] {
|
|
327
326
|
let parsedColor = ColorParser.parseColor(color)
|
|
328
327
|
renderer.strokeColor = parsedColor ?? .red
|
|
329
|
-
print("🔷 OverlayManager: color=\(color) -> \(String(describing: parsedColor))")
|
|
330
328
|
} else if let strokeColor = style?["strokeColor"] {
|
|
331
329
|
let parsedColor = ColorParser.parseColor(strokeColor)
|
|
332
330
|
renderer.strokeColor = parsedColor ?? .red
|
|
333
|
-
print("🔷 OverlayManager: strokeColor=\(strokeColor) -> \(String(describing: parsedColor))")
|
|
334
331
|
} else {
|
|
335
332
|
renderer.strokeColor = .red
|
|
336
|
-
print("🔷 OverlayManager: 使用默认红色")
|
|
337
333
|
}
|
|
338
334
|
}
|
|
339
335
|
|
|
@@ -343,8 +339,6 @@ class OverlayManager {
|
|
|
343
339
|
return nil
|
|
344
340
|
}
|
|
345
341
|
|
|
346
|
-
print("🔶 OverlayManager.getRenderer(Polygon): style=\(String(describing: style))")
|
|
347
|
-
|
|
348
342
|
// 设置填充颜色
|
|
349
343
|
if let fillColor = style?["fillColor"] {
|
|
350
344
|
let parsedColor = ColorParser.parseColor(fillColor)
|
|
@@ -119,7 +119,6 @@ class CircleView: ExpoView {
|
|
|
119
119
|
* @param color 颜色值
|
|
120
120
|
*/
|
|
121
121
|
func setFillColor(_ color: Any?) {
|
|
122
|
-
print("🔵 CircleView.setFillColor: \(String(describing: color))")
|
|
123
122
|
fillColor = color
|
|
124
123
|
renderer = nil
|
|
125
124
|
updateCircle()
|
|
@@ -130,7 +129,6 @@ class CircleView: ExpoView {
|
|
|
130
129
|
* @param color 颜色值
|
|
131
130
|
*/
|
|
132
131
|
func setStrokeColor(_ color: Any?) {
|
|
133
|
-
print("🔵 CircleView.setStrokeColor: \(String(describing: color))")
|
|
134
132
|
strokeColor = color
|
|
135
133
|
renderer = nil
|
|
136
134
|
updateCircle()
|
|
@@ -141,7 +139,6 @@ class CircleView: ExpoView {
|
|
|
141
139
|
* @param width 宽度值
|
|
142
140
|
*/
|
|
143
141
|
func setStrokeWidth(_ width: Float) {
|
|
144
|
-
print("🔵 CircleView.setStrokeWidth: \(width)")
|
|
145
142
|
strokeWidth = width
|
|
146
143
|
renderer = nil
|
|
147
144
|
updateCircle()
|
|
@@ -63,8 +63,28 @@ class MarkerView: ExpoView {
|
|
|
63
63
|
|
|
64
64
|
required init(appContext: AppContext? = nil) {
|
|
65
65
|
super.init(appContext: appContext)
|
|
66
|
-
//
|
|
66
|
+
// 完全禁用交互,让触摸事件穿透
|
|
67
67
|
isUserInteractionEnabled = false
|
|
68
|
+
// 关键:让所有子视图也不接收触摸事件
|
|
69
|
+
isMultipleTouchEnabled = false
|
|
70
|
+
isExclusiveTouch = false
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 重写 hitTest,让触摸事件完全穿透此视图
|
|
75
|
+
* 这是解决旧架构下 children 阻挡地图触摸的关键
|
|
76
|
+
*/
|
|
77
|
+
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
|
78
|
+
// 始终返回 nil,让触摸事件穿透到地图
|
|
79
|
+
return nil
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* 重写 point(inside:with:),确保此视图不响应任何触摸
|
|
84
|
+
*/
|
|
85
|
+
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
|
|
86
|
+
// 始终返回 false,表示点击不在此视图内
|
|
87
|
+
return false
|
|
68
88
|
}
|
|
69
89
|
|
|
70
90
|
/**
|
|
@@ -90,12 +110,9 @@ class MarkerView: ExpoView {
|
|
|
90
110
|
guard let mapView = mapView,
|
|
91
111
|
let latitude = position["latitude"],
|
|
92
112
|
let longitude = position["longitude"] else {
|
|
93
|
-
print("⚠️ [MarkerView] updateAnnotation: mapView 或坐标为 nil")
|
|
94
113
|
return
|
|
95
114
|
}
|
|
96
115
|
|
|
97
|
-
print("📍 [MarkerView] updateAnnotation: 位置 (\(latitude), \(longitude)), subviews: \(self.subviews.count)")
|
|
98
|
-
|
|
99
116
|
// 取消之前的延迟任务
|
|
100
117
|
pendingAddTask?.cancel()
|
|
101
118
|
|
|
@@ -45,29 +45,19 @@ class PolygonView: ExpoView {
|
|
|
45
45
|
* 更新多边形覆盖物
|
|
46
46
|
*/
|
|
47
47
|
private func updatePolygon() {
|
|
48
|
-
guard let mapView = mapView else {
|
|
49
|
-
print("❌ PolygonView.updatePolygon: mapView 为空")
|
|
50
|
-
return
|
|
51
|
-
}
|
|
48
|
+
guard let mapView = mapView else { return }
|
|
52
49
|
if let old = polygon { mapView.remove(old) }
|
|
53
50
|
|
|
54
51
|
var coords = points.compactMap { point -> CLLocationCoordinate2D? in
|
|
55
52
|
guard let lat = point["latitude"], let lng = point["longitude"] else { return nil }
|
|
56
53
|
return CLLocationCoordinate2D(latitude: lat, longitude: lng)
|
|
57
54
|
}
|
|
58
|
-
guard !coords.isEmpty else {
|
|
59
|
-
print("❌ PolygonView.updatePolygon: 点数组为空")
|
|
60
|
-
return
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
print("🔶 PolygonView.updatePolygon: points=\(coords.count)个点")
|
|
64
|
-
print("🔶 PolygonView.updatePolygon: fillColor=\(String(describing: fillColor)), strokeColor=\(String(describing: strokeColor)), strokeWidth=\(strokeWidth)")
|
|
55
|
+
guard !coords.isEmpty else { return }
|
|
65
56
|
|
|
66
57
|
polygon = MAPolygon(coordinates: &coords, count: UInt(coords.count))
|
|
67
58
|
mapView.add(polygon!)
|
|
68
59
|
|
|
69
60
|
renderer = nil
|
|
70
|
-
print("🔶 PolygonView.updatePolygon: renderer 已清空")
|
|
71
61
|
}
|
|
72
62
|
|
|
73
63
|
/**
|
|
@@ -48,29 +48,19 @@ class PolylineView: ExpoView {
|
|
|
48
48
|
* 更新折线覆盖物
|
|
49
49
|
*/
|
|
50
50
|
private func updatePolyline() {
|
|
51
|
-
guard let mapView = mapView else {
|
|
52
|
-
print("❌ PolylineView.updatePolyline: mapView 为空")
|
|
53
|
-
return
|
|
54
|
-
}
|
|
51
|
+
guard let mapView = mapView else { return }
|
|
55
52
|
if let old = polyline { mapView.remove(old) }
|
|
56
53
|
|
|
57
54
|
var coords = points.compactMap { point -> CLLocationCoordinate2D? in
|
|
58
55
|
guard let lat = point["latitude"], let lng = point["longitude"] else { return nil }
|
|
59
56
|
return CLLocationCoordinate2D(latitude: lat, longitude: lng)
|
|
60
57
|
}
|
|
61
|
-
guard !coords.isEmpty else {
|
|
62
|
-
print("❌ PolylineView.updatePolyline: 点数组为空")
|
|
63
|
-
return
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
print("🔷 PolylineView.updatePolyline: points=\(coords.count)个点")
|
|
67
|
-
print("🔷 PolylineView.updatePolyline: strokeColor=\(String(describing: strokeColor)), strokeWidth=\(strokeWidth), texture=\(String(describing: textureUrl))")
|
|
58
|
+
guard !coords.isEmpty else { return }
|
|
68
59
|
|
|
69
60
|
polyline = MAPolyline(coordinates: &coords, count: UInt(coords.count))
|
|
70
61
|
mapView.add(polyline!)
|
|
71
62
|
|
|
72
63
|
renderer = nil
|
|
73
|
-
print("🔷 PolylineView.updatePolyline: renderer 已清空")
|
|
74
64
|
}
|
|
75
65
|
|
|
76
66
|
/**
|
|
@@ -20,7 +20,6 @@ class PermissionManager: NSObject, CLLocationManagerDelegate {
|
|
|
20
20
|
* @param callback 权限结果回调 (granted, status)
|
|
21
21
|
*/
|
|
22
22
|
func requestPermission(callback: @escaping (Bool, String) -> Void) {
|
|
23
|
-
print("🔐 [PermissionManager] requestPermission 被调用")
|
|
24
23
|
self.permissionCallback = callback
|
|
25
24
|
|
|
26
25
|
// 确保在主线程操作
|
package/package.json
CHANGED
package/test/ClockMapView.tsx
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* @Author : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
3
3
|
* @Date : 2025-03-11 09:29:07
|
|
4
4
|
* @LastEditors : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
5
|
-
* @LastEditTime : 2025-11-
|
|
6
|
-
* @FilePath : /
|
|
5
|
+
* @LastEditTime : 2025-11-24 09:45:58
|
|
6
|
+
* @FilePath : /jintan-app/widget/ClockMapView.tsx
|
|
7
7
|
* @Description :
|
|
8
8
|
*
|
|
9
9
|
* Copyright (c) 2025 by 尚博信_王强, All Rights Reserved.
|
|
@@ -66,6 +66,28 @@ const ClockMapView = () => {
|
|
|
66
66
|
|
|
67
67
|
} = useMap();
|
|
68
68
|
|
|
69
|
+
// 同步计算文本尺寸的函数
|
|
70
|
+
const calculateTextSize = (text: string, fontSize = 12) => {
|
|
71
|
+
if (!text) return { width: 100, height: 40 };
|
|
72
|
+
|
|
73
|
+
// 计算中文字符和其他字符
|
|
74
|
+
const chineseChars = (text.match(/[\u4e00-\u9fa5]/g) || []).length;
|
|
75
|
+
const otherChars = text.length - chineseChars;
|
|
76
|
+
|
|
77
|
+
// 中文字符宽度约为 fontSize,英文约为 fontSize * 0.6
|
|
78
|
+
// 加上左右 padding (5 * 2) + 边框 (1 * 2) = 12
|
|
79
|
+
const estimatedWidth = Math.ceil(
|
|
80
|
+
chineseChars * fontSize + otherChars * fontSize * 0.6 + 22
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
// 高度 = 行高 + 上下 padding (5 * 2) + 边框 (1 * 2) = fontSize * 1.5 + 12
|
|
84
|
+
const estimatedHeight = Math.ceil(fontSize * 1.5 + 12);
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
width: Math.max(estimatedWidth, 60), // 最小宽度 60
|
|
88
|
+
height: Math.max(estimatedHeight, 30) // 最小高度 30
|
|
89
|
+
};
|
|
90
|
+
};
|
|
69
91
|
|
|
70
92
|
let timers = useRef<NodeJS.Timeout | number>(0);
|
|
71
93
|
|
|
@@ -82,12 +104,11 @@ const ClockMapView = () => {
|
|
|
82
104
|
style={{ flex: 1 }}
|
|
83
105
|
ref={mapViewRef}
|
|
84
106
|
onLoad={(nativeEvent) => {
|
|
85
|
-
console.log('onLoad', nativeEvent)
|
|
86
107
|
setMapState(false);
|
|
87
108
|
}}
|
|
88
109
|
indoorViewEnabled={true}
|
|
89
110
|
zoomGesturesEnabled={true}
|
|
90
|
-
buildingsEnabled={true}
|
|
111
|
+
// buildingsEnabled={true}
|
|
91
112
|
userLocationRepresentation={{
|
|
92
113
|
showsAccuracyRing: false,
|
|
93
114
|
image: iconUri,
|
|
@@ -99,7 +120,7 @@ const ClockMapView = () => {
|
|
|
99
120
|
scaleControlsEnabled={false}
|
|
100
121
|
tiltGesturesEnabled={false}
|
|
101
122
|
compassEnabled={false}
|
|
102
|
-
followUserLocation={false}
|
|
123
|
+
// followUserLocation={false}
|
|
103
124
|
// onCameraIdle={({ nativeEvent }) => {}}
|
|
104
125
|
onLocation={({ nativeEvent }) => {
|
|
105
126
|
const { latitude, longitude } = nativeEvent;
|
|
@@ -123,7 +144,7 @@ const ClockMapView = () => {
|
|
|
123
144
|
});
|
|
124
145
|
setIsWithinRange(index);
|
|
125
146
|
}}
|
|
126
|
-
distanceFilter={1}
|
|
147
|
+
// distanceFilter={1}
|
|
127
148
|
// myLocationIcon={true}
|
|
128
149
|
myLocationEnabled={true}
|
|
129
150
|
initialCameraPosition={initialPosition || {
|
|
@@ -138,6 +159,10 @@ const ClockMapView = () => {
|
|
|
138
159
|
|
|
139
160
|
// ✅ 使用基于坐标的稳定 key,而不是 index
|
|
140
161
|
const stableKey = `${item.lat.toFixed(6)}-${item.lon.toFixed(6)}`;
|
|
162
|
+
|
|
163
|
+
// ✅ 同步计算 Marker 尺寸(无延迟)
|
|
164
|
+
const positionName = clockRule[clockRuleIndex]?.positionName || '';
|
|
165
|
+
const markerSize = calculateTextSize(positionName, 12);
|
|
141
166
|
|
|
142
167
|
return (
|
|
143
168
|
<React.Fragment key={stableKey}>
|
|
@@ -157,12 +182,12 @@ const ClockMapView = () => {
|
|
|
157
182
|
latitude: item?.lat || 39.908692,
|
|
158
183
|
longitude: item?.lon || 116.397477,
|
|
159
184
|
}}
|
|
160
|
-
|
|
161
|
-
|
|
185
|
+
customViewWidth={markerSize.width}
|
|
186
|
+
customViewHeight={markerSize.height}
|
|
162
187
|
>
|
|
163
188
|
<View style={styles.markerContainer}>
|
|
164
189
|
<Text style={styles.markerText}>
|
|
165
|
-
{
|
|
190
|
+
{positionName}
|
|
166
191
|
</Text>
|
|
167
192
|
</View>
|
|
168
193
|
</Marker>
|
|
@@ -479,6 +504,7 @@ const styleSheet = createStyleSheet((theme, tr) => ({
|
|
|
479
504
|
fontSize: 12,
|
|
480
505
|
color: theme.colors.text,
|
|
481
506
|
fontWeight: "600",
|
|
507
|
+
|
|
482
508
|
},
|
|
483
509
|
markerContainer: {
|
|
484
510
|
backgroundColor: theme.colors.white,
|
|
@@ -487,6 +513,8 @@ const styleSheet = createStyleSheet((theme, tr) => ({
|
|
|
487
513
|
alignItems: "center",
|
|
488
514
|
borderWidth: 1,
|
|
489
515
|
borderColor: "#ddd",
|
|
516
|
+
paddingVertical:5,
|
|
517
|
+
|
|
490
518
|
},
|
|
491
519
|
loadingContainer: {
|
|
492
520
|
flex: 1,
|
package/test/useMap.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* @Author : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
3
3
|
* @Date : 2024-07-09 16:16:06
|
|
4
4
|
* @LastEditors : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
5
|
-
* @LastEditTime : 2025-11-
|
|
6
|
-
* @FilePath : /
|
|
5
|
+
* @LastEditTime : 2025-11-24 10:01:11
|
|
6
|
+
* @FilePath : /jintan-app/hook/useMap.ts
|
|
7
7
|
* @Description : 地图的hook
|
|
8
8
|
*
|
|
9
9
|
* Copyright (c) 2024 by 尚博信_王强, All Rights Reserved.
|
|
@@ -264,10 +264,10 @@ export default function useMap() {
|
|
|
264
264
|
const initialize = async () => {
|
|
265
265
|
try {
|
|
266
266
|
// 1. 初始化 SDK
|
|
267
|
-
initSDK({
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
})
|
|
267
|
+
// initSDK({
|
|
268
|
+
// androidKey:'dcee3ae4bd6a53b44fbd3d55b9996cbf',
|
|
269
|
+
// iosKey:'b09eaba1eeca575db7a89b9738cb0246'
|
|
270
|
+
// })
|
|
271
271
|
|
|
272
272
|
// 2. 检查并请求权限
|
|
273
273
|
const status = await checkLocationPermission();
|
|
@@ -286,7 +286,7 @@ export default function useMap() {
|
|
|
286
286
|
configure({
|
|
287
287
|
withReGeocode: true,
|
|
288
288
|
interval: 5000,
|
|
289
|
-
distanceFilter:
|
|
289
|
+
distanceFilter: 1,
|
|
290
290
|
accuracy: 3
|
|
291
291
|
});
|
|
292
292
|
|
|
@@ -339,7 +339,7 @@ export default function useMap() {
|
|
|
339
339
|
}
|
|
340
340
|
timer.current && clearTimeout(timer.current);
|
|
341
341
|
};
|
|
342
|
-
}, [
|
|
342
|
+
}, [appPositions]);
|
|
343
343
|
|
|
344
344
|
|
|
345
345
|
useEffect(() => {
|
|
@@ -589,27 +589,39 @@ export default function useMap() {
|
|
|
589
589
|
//移动到当前位置
|
|
590
590
|
const moveToCurrentLocation = async() => {
|
|
591
591
|
HapticsUtil.triggerHaptic();
|
|
592
|
-
|
|
593
|
-
// if (!mapViewNodeHandle) return;
|
|
594
|
-
// UIManager.dispatchViewManagerCommand(
|
|
595
|
-
// mapViewNodeHandle,
|
|
596
|
-
// UIManager.getViewManagerConfig("AMapView").Commands.moveToCurrentLocation,
|
|
597
|
-
// []
|
|
598
|
-
// );
|
|
592
|
+
|
|
599
593
|
try {
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
594
|
+
// ✅ 优先使用 data.location(实时更新的位置)
|
|
595
|
+
let location = data.location;
|
|
596
|
+
|
|
597
|
+
// 如果 data.location 不存在或无效,才重新获取
|
|
598
|
+
if (!location || !location.latitude || !location.longitude) {
|
|
599
|
+
location = await getCurrentLocation() ;
|
|
600
|
+
}
|
|
606
601
|
|
|
602
|
+
// 确保有有效的坐标
|
|
603
|
+
if (location && location.latitude && location.longitude) {
|
|
604
|
+
if (mapViewRef.current) {
|
|
605
|
+
await mapViewRef.current.moveCamera({
|
|
606
|
+
target: {
|
|
607
|
+
latitude: location.latitude,
|
|
608
|
+
longitude: location.longitude
|
|
609
|
+
},
|
|
610
|
+
zoom: 16,
|
|
611
|
+
}, 300);
|
|
612
|
+
}
|
|
613
|
+
} else {
|
|
614
|
+
toast.info("提示", {
|
|
615
|
+
description: "无法获取当前位置,请稍后再试"
|
|
616
|
+
});
|
|
607
617
|
}
|
|
608
618
|
|
|
609
619
|
} catch (error) {
|
|
610
|
-
console.log(error);
|
|
620
|
+
console.log("moveToCurrentLocation error:", error);
|
|
621
|
+
toast.info("提示", {
|
|
622
|
+
description: "定位失败,请检查定位权限"
|
|
623
|
+
});
|
|
611
624
|
}
|
|
612
|
-
|
|
613
625
|
};
|
|
614
626
|
|
|
615
627
|
//生成用于上传前面的url
|