expo-gaode-map-navigation 2.0.14 → 2.0.15
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/.project
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<projectDescription>
|
|
3
|
+
<name>expo-gaode-map-navigation</name>
|
|
4
|
+
<comment>Project example-navigation-android-expo-gaode-map-navigation created by Buildship.</comment>
|
|
5
|
+
<projects>
|
|
6
|
+
</projects>
|
|
7
|
+
<buildSpec>
|
|
8
|
+
<buildCommand>
|
|
9
|
+
<name>org.eclipse.jdt.core.javabuilder</name>
|
|
10
|
+
<arguments>
|
|
11
|
+
</arguments>
|
|
12
|
+
</buildCommand>
|
|
13
|
+
<buildCommand>
|
|
14
|
+
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
|
15
|
+
<arguments>
|
|
16
|
+
</arguments>
|
|
17
|
+
</buildCommand>
|
|
18
|
+
</buildSpec>
|
|
19
|
+
<natures>
|
|
20
|
+
<nature>org.eclipse.jdt.core.javanature</nature>
|
|
21
|
+
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
|
22
|
+
</natures>
|
|
23
|
+
<filteredResources>
|
|
24
|
+
<filter>
|
|
25
|
+
<id>1778483172220</id>
|
|
26
|
+
<name></name>
|
|
27
|
+
<type>30</type>
|
|
28
|
+
<matcher>
|
|
29
|
+
<id>org.eclipse.core.resources.regexFilterMatcher</id>
|
|
30
|
+
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
|
|
31
|
+
</matcher>
|
|
32
|
+
</filter>
|
|
33
|
+
</filteredResources>
|
|
34
|
+
</projectDescription>
|
|
@@ -27,6 +27,8 @@ class ExpoGaodeMapModule : Module() {
|
|
|
27
27
|
/** 定位管理器实例 */
|
|
28
28
|
private var locationManager: LocationManager? = null
|
|
29
29
|
|
|
30
|
+
private fun jsValue(value: Any?): Any? = value
|
|
31
|
+
|
|
30
32
|
override fun definition() = ModuleDefinition {
|
|
31
33
|
Name("ExpoGaodeMap")
|
|
32
34
|
|
|
@@ -93,7 +95,7 @@ class ExpoGaodeMapModule : Module() {
|
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
Function("getPrivacyStatus") {
|
|
96
|
-
SDKInitializer.getPrivacyStatus()
|
|
98
|
+
jsValue(SDKInitializer.getPrivacyStatus())
|
|
97
99
|
}
|
|
98
100
|
|
|
99
101
|
/**
|
|
@@ -109,14 +111,14 @@ class ExpoGaodeMapModule : Module() {
|
|
|
109
111
|
* @return SDK 版本号
|
|
110
112
|
*/
|
|
111
113
|
Function("getVersion") {
|
|
112
|
-
SDKInitializer.getVersion()
|
|
114
|
+
jsValue(SDKInitializer.getVersion())
|
|
113
115
|
}
|
|
114
116
|
|
|
115
117
|
/**
|
|
116
118
|
* 检查原生 SDK 是否已配置 API Key
|
|
117
119
|
*/
|
|
118
120
|
Function("isNativeSDKConfigured") {
|
|
119
|
-
try {
|
|
121
|
+
jsValue(try {
|
|
120
122
|
val context = appContext.reactContext!!
|
|
121
123
|
val apiKey = context.packageManager
|
|
122
124
|
.getApplicationInfo(context.packageName, android.content.pm.PackageManager.GET_META_DATA)
|
|
@@ -124,7 +126,7 @@ class ExpoGaodeMapModule : Module() {
|
|
|
124
126
|
!apiKey.isNullOrEmpty()
|
|
125
127
|
} catch (_: Exception) {
|
|
126
128
|
false
|
|
127
|
-
}
|
|
129
|
+
})
|
|
128
130
|
}
|
|
129
131
|
|
|
130
132
|
|
|
@@ -187,11 +189,11 @@ class ExpoGaodeMapModule : Module() {
|
|
|
187
189
|
Function("distanceBetweenCoordinates") { p1: Map<String, Any>?, p2: Map<String, Any>? ->
|
|
188
190
|
val coord1 = LatLngParser.parseLatLng(p1)
|
|
189
191
|
val coord2 = LatLngParser.parseLatLng(p2)
|
|
190
|
-
if (coord1 != null && coord2 != null) {
|
|
192
|
+
jsValue(if (coord1 != null && coord2 != null) {
|
|
191
193
|
GeometryUtils.calculateDistance(coord1, coord2)
|
|
192
194
|
} else {
|
|
193
195
|
0.0
|
|
194
|
-
}
|
|
196
|
+
})
|
|
195
197
|
}
|
|
196
198
|
|
|
197
199
|
/**
|
|
@@ -213,16 +215,16 @@ class ExpoGaodeMapModule : Module() {
|
|
|
213
215
|
val normalized = LatLngParser.parseLatLngList(points)
|
|
214
216
|
val safeMinZoom = minZoom ?: 3
|
|
215
217
|
val safeMaxZoom = maxZoom ?: 20
|
|
216
|
-
if (normalized.isEmpty()) return@Function safeMinZoom.toDouble()
|
|
218
|
+
if (normalized.isEmpty()) return@Function jsValue(safeMinZoom.toDouble())
|
|
217
219
|
|
|
218
|
-
GeometryUtils.calculateFitZoom(
|
|
220
|
+
jsValue(GeometryUtils.calculateFitZoom(
|
|
219
221
|
normalized,
|
|
220
222
|
viewportWidthPx ?: 390.0,
|
|
221
223
|
viewportHeightPx ?: 844.0,
|
|
222
224
|
paddingPx ?: 48.0,
|
|
223
225
|
safeMinZoom,
|
|
224
226
|
safeMaxZoom
|
|
225
|
-
)
|
|
227
|
+
))
|
|
226
228
|
}
|
|
227
229
|
|
|
228
230
|
/**
|
|
@@ -232,7 +234,7 @@ class ExpoGaodeMapModule : Module() {
|
|
|
232
234
|
*/
|
|
233
235
|
Function("calculatePolygonArea") { points: List<Any>? ->
|
|
234
236
|
val rings = LatLngParser.parseLatLngListList(points)
|
|
235
|
-
if (rings.isEmpty()) return@Function 0.0
|
|
237
|
+
if (rings.isEmpty()) return@Function jsValue(0.0)
|
|
236
238
|
|
|
237
239
|
// 第一项是外轮廓
|
|
238
240
|
var totalArea = GeometryUtils.calculatePolygonArea(rings[0])
|
|
@@ -245,7 +247,7 @@ class ExpoGaodeMapModule : Module() {
|
|
|
245
247
|
}
|
|
246
248
|
|
|
247
249
|
// 确保面积不为负数
|
|
248
|
-
max(0.0, totalArea)
|
|
250
|
+
jsValue(max(0.0, totalArea))
|
|
249
251
|
}
|
|
250
252
|
|
|
251
253
|
/**
|
|
@@ -255,24 +257,24 @@ class ExpoGaodeMapModule : Module() {
|
|
|
255
257
|
* @return 是否在多边形内
|
|
256
258
|
*/
|
|
257
259
|
Function("isPointInPolygon") { point: Map<String, Any>?, polygon: List<Any>? ->
|
|
258
|
-
val pt = LatLngParser.parseLatLng(point) ?: return@Function false
|
|
260
|
+
val pt = LatLngParser.parseLatLng(point) ?: return@Function jsValue(false)
|
|
259
261
|
val rings = LatLngParser.parseLatLngListList(polygon)
|
|
260
|
-
if (rings.isEmpty()) return@Function false
|
|
262
|
+
if (rings.isEmpty()) return@Function jsValue(false)
|
|
261
263
|
|
|
262
264
|
// 点必须在外轮廓内
|
|
263
265
|
val inOuter = GeometryUtils.isPointInPolygon(pt, rings[0])
|
|
264
|
-
if (!inOuter) return@Function false
|
|
266
|
+
if (!inOuter) return@Function jsValue(false)
|
|
265
267
|
|
|
266
268
|
// 点不能在任何内孔内
|
|
267
269
|
if (rings.size > 1) {
|
|
268
270
|
for (i in 1 until rings.size) {
|
|
269
271
|
if (GeometryUtils.isPointInPolygon(pt, rings[i])) {
|
|
270
|
-
return@Function false
|
|
272
|
+
return@Function jsValue(false)
|
|
271
273
|
}
|
|
272
274
|
}
|
|
273
275
|
}
|
|
274
276
|
|
|
275
|
-
true
|
|
277
|
+
jsValue(true)
|
|
276
278
|
}
|
|
277
279
|
|
|
278
280
|
/**
|
|
@@ -285,11 +287,11 @@ class ExpoGaodeMapModule : Module() {
|
|
|
285
287
|
Function("isPointInCircle") { point: Map<String, Any>?, center: Map<String, Any>?, radius: Double ->
|
|
286
288
|
val pt = LatLngParser.parseLatLng(point)
|
|
287
289
|
val cn = LatLngParser.parseLatLng(center)
|
|
288
|
-
if (pt != null && cn != null) {
|
|
290
|
+
jsValue(if (pt != null && cn != null) {
|
|
289
291
|
GeometryUtils.isPointInCircle(pt, cn, radius)
|
|
290
292
|
} else {
|
|
291
293
|
false
|
|
292
|
-
}
|
|
294
|
+
})
|
|
293
295
|
}
|
|
294
296
|
|
|
295
297
|
/**
|
|
@@ -301,11 +303,11 @@ class ExpoGaodeMapModule : Module() {
|
|
|
301
303
|
Function("calculateRectangleArea") { southWest: Map<String, Any>?, northEast: Map<String, Any>? ->
|
|
302
304
|
val sw = LatLngParser.parseLatLng(southWest)
|
|
303
305
|
val ne = LatLngParser.parseLatLng(northEast)
|
|
304
|
-
if (sw != null && ne != null) {
|
|
306
|
+
jsValue(if (sw != null && ne != null) {
|
|
305
307
|
GeometryUtils.calculateRectangleArea(sw, ne)
|
|
306
308
|
} else {
|
|
307
309
|
0.0
|
|
308
|
-
}
|
|
310
|
+
})
|
|
309
311
|
}
|
|
310
312
|
|
|
311
313
|
/**
|
|
@@ -318,7 +320,7 @@ class ExpoGaodeMapModule : Module() {
|
|
|
318
320
|
val pathPoints = LatLngParser.parseLatLngList(path)
|
|
319
321
|
val targetPoint = LatLngParser.parseLatLng(target)
|
|
320
322
|
|
|
321
|
-
if (targetPoint != null && pathPoints.isNotEmpty()) {
|
|
323
|
+
jsValue(if (targetPoint != null && pathPoints.isNotEmpty()) {
|
|
322
324
|
val result = GeometryUtils.getNearestPointOnPath(pathPoints, targetPoint)
|
|
323
325
|
if (result != null) {
|
|
324
326
|
mapOf(
|
|
@@ -332,7 +334,7 @@ class ExpoGaodeMapModule : Module() {
|
|
|
332
334
|
}
|
|
333
335
|
} else {
|
|
334
336
|
null
|
|
335
|
-
}
|
|
337
|
+
})
|
|
336
338
|
}
|
|
337
339
|
|
|
338
340
|
/**
|
|
@@ -342,16 +344,16 @@ class ExpoGaodeMapModule : Module() {
|
|
|
342
344
|
*/
|
|
343
345
|
Function("calculateCentroid") { polygon: List<Any>? ->
|
|
344
346
|
val rings = LatLngParser.parseLatLngListList(polygon)
|
|
345
|
-
if (rings.isEmpty()) return@Function null
|
|
347
|
+
if (rings.isEmpty()) return@Function jsValue(null)
|
|
346
348
|
|
|
347
349
|
if (rings.size == 1) {
|
|
348
350
|
val result = GeometryUtils.calculateCentroid(rings[0])
|
|
349
|
-
return@Function result?.let {
|
|
351
|
+
return@Function jsValue(result?.let {
|
|
350
352
|
mapOf(
|
|
351
353
|
"latitude" to it.latitude,
|
|
352
354
|
"longitude" to it.longitude
|
|
353
355
|
)
|
|
354
|
-
}
|
|
356
|
+
})
|
|
355
357
|
}
|
|
356
358
|
|
|
357
359
|
// 带孔多边形的质心计算: Σ(Area_i * Centroid_i) / Σ(Area_i)
|
|
@@ -376,14 +378,14 @@ class ExpoGaodeMapModule : Module() {
|
|
|
376
378
|
}
|
|
377
379
|
}
|
|
378
380
|
|
|
379
|
-
if (abs(totalArea) > 1e-9) {
|
|
381
|
+
jsValue(if (abs(totalArea) > 1e-9) {
|
|
380
382
|
mapOf(
|
|
381
383
|
"latitude" to sumLat / totalArea,
|
|
382
384
|
"longitude" to sumLon / totalArea
|
|
383
385
|
)
|
|
384
386
|
} else {
|
|
385
387
|
null
|
|
386
|
-
}
|
|
388
|
+
})
|
|
387
389
|
}
|
|
388
390
|
|
|
389
391
|
/**
|
|
@@ -393,10 +395,10 @@ class ExpoGaodeMapModule : Module() {
|
|
|
393
395
|
*/
|
|
394
396
|
Function("calculatePathBounds") { pointsList: List<Any>? ->
|
|
395
397
|
val points = LatLngParser.parseLatLngList(pointsList)
|
|
396
|
-
if (points.isEmpty()) return@Function null
|
|
398
|
+
if (points.isEmpty()) return@Function jsValue(null)
|
|
397
399
|
|
|
398
400
|
val result = GeometryUtils.calculatePathBounds(points)
|
|
399
|
-
result?.let {
|
|
401
|
+
jsValue(result?.let {
|
|
400
402
|
mapOf(
|
|
401
403
|
"north" to it.north,
|
|
402
404
|
"south" to it.south,
|
|
@@ -407,7 +409,7 @@ class ExpoGaodeMapModule : Module() {
|
|
|
407
409
|
"longitude" to it.centerLon
|
|
408
410
|
)
|
|
409
411
|
)
|
|
410
|
-
}
|
|
412
|
+
})
|
|
411
413
|
}
|
|
412
414
|
|
|
413
415
|
/**
|
|
@@ -418,11 +420,11 @@ class ExpoGaodeMapModule : Module() {
|
|
|
418
420
|
*/
|
|
419
421
|
Function("encodeGeoHash") { coordinate: Map<String, Any>?, precision: Int ->
|
|
420
422
|
val latLng = LatLngParser.parseLatLng(coordinate)
|
|
421
|
-
if (latLng != null) {
|
|
423
|
+
jsValue(if (latLng != null) {
|
|
422
424
|
GeometryUtils.encodeGeoHash(latLng, precision)
|
|
423
425
|
} else {
|
|
424
426
|
""
|
|
425
|
-
}
|
|
427
|
+
})
|
|
426
428
|
}
|
|
427
429
|
|
|
428
430
|
/**
|
|
@@ -434,12 +436,12 @@ class ExpoGaodeMapModule : Module() {
|
|
|
434
436
|
Function("simplifyPolyline") { points: List<Any>?, tolerance: Double ->
|
|
435
437
|
val poly = LatLngParser.parseLatLngList(points)
|
|
436
438
|
val simplified = GeometryUtils.simplifyPolyline(poly, tolerance)
|
|
437
|
-
simplified.map {
|
|
439
|
+
jsValue(simplified.map {
|
|
438
440
|
mapOf(
|
|
439
441
|
"latitude" to it.latitude,
|
|
440
442
|
"longitude" to it.longitude
|
|
441
443
|
)
|
|
442
|
-
}
|
|
444
|
+
})
|
|
443
445
|
}
|
|
444
446
|
|
|
445
447
|
/**
|
|
@@ -449,7 +451,7 @@ class ExpoGaodeMapModule : Module() {
|
|
|
449
451
|
*/
|
|
450
452
|
Function("calculatePathLength") { points: List<Any>? ->
|
|
451
453
|
val poly = LatLngParser.parseLatLngList(points)
|
|
452
|
-
GeometryUtils.calculatePathLength(poly)
|
|
454
|
+
jsValue(GeometryUtils.calculatePathLength(poly))
|
|
453
455
|
}
|
|
454
456
|
|
|
455
457
|
/**
|
|
@@ -459,12 +461,12 @@ class ExpoGaodeMapModule : Module() {
|
|
|
459
461
|
*/
|
|
460
462
|
Function("parsePolyline") { polylineStr: String? ->
|
|
461
463
|
val result = GeometryUtils.parsePolyline(polylineStr)
|
|
462
|
-
result.map {
|
|
464
|
+
jsValue(result.map {
|
|
463
465
|
mapOf(
|
|
464
466
|
"latitude" to it.latitude,
|
|
465
467
|
"longitude" to it.longitude
|
|
466
468
|
)
|
|
467
|
-
}
|
|
469
|
+
})
|
|
468
470
|
}
|
|
469
471
|
|
|
470
472
|
/**
|
|
@@ -476,7 +478,7 @@ class ExpoGaodeMapModule : Module() {
|
|
|
476
478
|
Function("getPointAtDistance") { points: List<Any>?, distance: Double ->
|
|
477
479
|
val poly = LatLngParser.parseLatLngList(points)
|
|
478
480
|
val result = GeometryUtils.getPointAtDistance(poly, distance)
|
|
479
|
-
if (result != null) {
|
|
481
|
+
jsValue(if (result != null) {
|
|
480
482
|
mapOf(
|
|
481
483
|
"latitude" to result.point.latitude,
|
|
482
484
|
"longitude" to result.point.longitude,
|
|
@@ -484,7 +486,7 @@ class ExpoGaodeMapModule : Module() {
|
|
|
484
486
|
)
|
|
485
487
|
} else {
|
|
486
488
|
null
|
|
487
|
-
}
|
|
489
|
+
})
|
|
488
490
|
}
|
|
489
491
|
|
|
490
492
|
/**
|
|
@@ -495,7 +497,7 @@ class ExpoGaodeMapModule : Module() {
|
|
|
495
497
|
*/
|
|
496
498
|
Function("latLngToTile") { coordinate: Map<String, Any>?, zoom: Int ->
|
|
497
499
|
val latLng = LatLngParser.parseLatLng(coordinate)
|
|
498
|
-
if (latLng != null) {
|
|
500
|
+
jsValue(if (latLng != null) {
|
|
499
501
|
val result = GeometryUtils.latLngToTile(latLng, zoom)
|
|
500
502
|
if (result != null && result.size >= 2) {
|
|
501
503
|
mapOf("x" to result[0], "y" to result[1])
|
|
@@ -504,7 +506,7 @@ class ExpoGaodeMapModule : Module() {
|
|
|
504
506
|
}
|
|
505
507
|
} else {
|
|
506
508
|
null
|
|
507
|
-
}
|
|
509
|
+
})
|
|
508
510
|
}
|
|
509
511
|
|
|
510
512
|
/**
|
|
@@ -517,9 +519,9 @@ class ExpoGaodeMapModule : Module() {
|
|
|
517
519
|
val y = (tile?.get("y") as? Number)?.toInt() ?: 0
|
|
518
520
|
val zoom = (tile?.get("z") as? Number)?.toInt() ?: (tile?.get("zoom") as? Number)?.toInt() ?: 0
|
|
519
521
|
val result = GeometryUtils.tileToLatLng(x, y, zoom)
|
|
520
|
-
result?.let {
|
|
522
|
+
jsValue(result?.let {
|
|
521
523
|
mapOf("latitude" to it.latitude, "longitude" to it.longitude)
|
|
522
|
-
}
|
|
524
|
+
})
|
|
523
525
|
}
|
|
524
526
|
|
|
525
527
|
/**
|
|
@@ -530,7 +532,7 @@ class ExpoGaodeMapModule : Module() {
|
|
|
530
532
|
*/
|
|
531
533
|
Function("latLngToPixel") { coordinate: Map<String, Any>?, zoom: Int ->
|
|
532
534
|
val latLng = LatLngParser.parseLatLng(coordinate)
|
|
533
|
-
if (latLng != null) {
|
|
535
|
+
jsValue(if (latLng != null) {
|
|
534
536
|
val result = GeometryUtils.latLngToPixel(latLng, zoom)
|
|
535
537
|
if (result != null && result.size >= 2) {
|
|
536
538
|
mapOf("x" to result[0], "y" to result[1])
|
|
@@ -539,7 +541,7 @@ class ExpoGaodeMapModule : Module() {
|
|
|
539
541
|
}
|
|
540
542
|
} else {
|
|
541
543
|
null
|
|
542
|
-
}
|
|
544
|
+
})
|
|
543
545
|
}
|
|
544
546
|
|
|
545
547
|
/**
|
|
@@ -552,9 +554,9 @@ class ExpoGaodeMapModule : Module() {
|
|
|
552
554
|
val x = (pixel?.get("x") as? Number)?.toDouble() ?: 0.0
|
|
553
555
|
val y = (pixel?.get("y") as? Number)?.toDouble() ?: 0.0
|
|
554
556
|
val result = GeometryUtils.pixelToLatLng(x, y, zoom)
|
|
555
|
-
result?.let {
|
|
557
|
+
jsValue(result?.let {
|
|
556
558
|
mapOf("latitude" to it.latitude, "longitude" to it.longitude)
|
|
557
|
-
}
|
|
559
|
+
})
|
|
558
560
|
}
|
|
559
561
|
|
|
560
562
|
/**
|
|
@@ -566,11 +568,11 @@ class ExpoGaodeMapModule : Module() {
|
|
|
566
568
|
Function("findPointInPolygons") { point: Map<String, Any>?, polygons: List<List<Any>>? ->
|
|
567
569
|
val pt = LatLngParser.parseLatLng(point)
|
|
568
570
|
val polys = polygons?.map { LatLngParser.parseLatLngList(it) }
|
|
569
|
-
if (pt != null && polys != null) {
|
|
571
|
+
jsValue(if (pt != null && polys != null) {
|
|
570
572
|
GeometryUtils.findPointInPolygons(pt, polys)
|
|
571
573
|
} else {
|
|
572
574
|
-1
|
|
573
|
-
}
|
|
575
|
+
})
|
|
574
576
|
}
|
|
575
577
|
|
|
576
578
|
/**
|
|
@@ -579,7 +581,7 @@ class ExpoGaodeMapModule : Module() {
|
|
|
579
581
|
* @param gridSizeMeters 网格大小(米)
|
|
580
582
|
*/
|
|
581
583
|
Function("generateHeatmapGrid") { points: List<Map<String, Any>>?, gridSizeMeters: Double ->
|
|
582
|
-
if (points == null || points.isEmpty()) return@Function emptyList<Map<String, Any>>()
|
|
584
|
+
if (points == null || points.isEmpty()) return@Function jsValue(emptyList<Map<String, Any>>())
|
|
583
585
|
|
|
584
586
|
val count = points.size
|
|
585
587
|
val latitudes = DoubleArray(count)
|
|
@@ -593,13 +595,13 @@ class ExpoGaodeMapModule : Module() {
|
|
|
593
595
|
}
|
|
594
596
|
|
|
595
597
|
val result = GeometryUtils.generateHeatmapGrid(latitudes, longitudes, weights, gridSizeMeters)
|
|
596
|
-
result.map {
|
|
598
|
+
jsValue(result.map {
|
|
597
599
|
mapOf(
|
|
598
600
|
"latitude" to it.latitude,
|
|
599
601
|
"longitude" to it.longitude,
|
|
600
602
|
"intensity" to it.intensity
|
|
601
603
|
)
|
|
602
|
-
}
|
|
604
|
+
})
|
|
603
605
|
}
|
|
604
606
|
|
|
605
607
|
// ==================== 定位配置 ====================
|
|
@@ -102,10 +102,8 @@ class LocationManager: NSObject, AMapLocationManagerDelegate {
|
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
private func setReGeocodeLanguage(_ rawValue:
|
|
106
|
-
|
|
107
|
-
ensureLocationManager()?.reGeocodeLanguage = language
|
|
108
|
-
}
|
|
105
|
+
private func setReGeocodeLanguage(_ rawValue: Int) {
|
|
106
|
+
ensureLocationManager()?.setValue(rawValue, forKey: "reGeocodeLanguage")
|
|
109
107
|
}
|
|
110
108
|
|
|
111
109
|
func setGeoLanguage(_ language: Int) {
|
|
@@ -243,6 +243,7 @@ class MarkerView: ExpoView {
|
|
|
243
243
|
// 异步渲染并设置
|
|
244
244
|
DispatchQueue.main.async { [weak self, weak annotationView] in
|
|
245
245
|
guard let self = self, let annotationView = annotationView else { return }
|
|
246
|
+
guard self.isAnnotationView(annotationView, boundTo: annotation) else { return }
|
|
246
247
|
if let generated = self.createImageFromSubviews() {
|
|
247
248
|
annotationView.image = generated
|
|
248
249
|
self.applyCenterOffset(to: annotationView, defaultOffset: .zero)
|
|
@@ -265,6 +266,7 @@ class MarkerView: ExpoView {
|
|
|
265
266
|
// 异步加载图标
|
|
266
267
|
loadIcon(iconUri: iconUri) { [weak self, weak annotationView] image in
|
|
267
268
|
guard let self = self, let image = image, let annotationView = annotationView else { return }
|
|
269
|
+
guard self.isAnnotationView(annotationView, boundTo: annotation) else { return }
|
|
268
270
|
let size = CGSize(width: self.iconWidth, height: self.iconHeight)
|
|
269
271
|
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
|
|
270
272
|
image.draw(in: CGRect(origin: .zero, size: size))
|
|
@@ -347,6 +349,7 @@ class MarkerView: ExpoView {
|
|
|
347
349
|
// 🔑 修复:延长延迟时间,给 React Native Image 更多加载时间
|
|
348
350
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self, weak annotationView] in
|
|
349
351
|
guard let self = self, let annotationView = annotationView else { return }
|
|
352
|
+
guard self.isAnnotationView(annotationView, boundTo: annotation) else { return }
|
|
350
353
|
// 再次检查缓存(避免重复渲染)
|
|
351
354
|
if let cached = IconBitmapCache.shared.image(forKey: key) {
|
|
352
355
|
annotationView.image = cached
|
|
@@ -410,12 +413,12 @@ class MarkerView: ExpoView {
|
|
|
410
413
|
UIGraphicsEndImageContext()
|
|
411
414
|
|
|
412
415
|
DispatchQueue.main.async {
|
|
416
|
+
guard let annotationView else { return }
|
|
417
|
+
guard self.isAnnotationView(annotationView, boundTo: annotation) else { return }
|
|
413
418
|
if let img = resizedImage {
|
|
414
419
|
IconBitmapCache.shared.setImage(img, forKey: key)
|
|
415
|
-
annotationView
|
|
416
|
-
|
|
417
|
-
self.applyCenterOffset(to: annotationView, defaultOffset: CGPoint(x: 0, y: -img.size.height / 2))
|
|
418
|
-
}
|
|
420
|
+
annotationView.image = img
|
|
421
|
+
self.applyCenterOffset(to: annotationView, defaultOffset: CGPoint(x: 0, y: -img.size.height / 2))
|
|
419
422
|
}
|
|
420
423
|
}
|
|
421
424
|
}
|
|
@@ -580,6 +583,13 @@ class MarkerView: ExpoView {
|
|
|
580
583
|
return .zero
|
|
581
584
|
}
|
|
582
585
|
|
|
586
|
+
private func isAnnotationView(_ annotationView: MAAnnotationView, boundTo annotation: MAAnnotation) -> Bool {
|
|
587
|
+
guard let current = annotationView.annotation else {
|
|
588
|
+
return false
|
|
589
|
+
}
|
|
590
|
+
return (current as AnyObject) === (annotation as AnyObject)
|
|
591
|
+
}
|
|
592
|
+
|
|
583
593
|
private func resolvedCustomSubviewSize(defaultSize: CGSize) -> CGSize {
|
|
584
594
|
guard let firstSubview = subviews.first else {
|
|
585
595
|
return defaultSize
|
|
@@ -725,36 +735,42 @@ class MarkerView: ExpoView {
|
|
|
725
735
|
pendingUpdateTask?.cancel(); pendingUpdateTask = nil
|
|
726
736
|
pendingSubviewRefreshTask?.cancel(); pendingSubviewRefreshTask = nil
|
|
727
737
|
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
// 确保在主线程执行移除操作
|
|
734
|
-
let cleanup = { [weak self, weak mapView] in
|
|
735
|
-
guard let self = self, let mapView = mapView else { return }
|
|
736
|
-
|
|
737
|
-
// 1. 停止任何正在进行的平滑移动
|
|
738
|
-
if self.animatedAnnotation != nil {
|
|
739
|
-
self.stopSmoothMove()
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
// 2. 移除普通标记点
|
|
743
|
-
if let annotation = self.annotation {
|
|
744
|
-
mapView.removeAnnotation(annotation)
|
|
745
|
-
self.annotation = nil
|
|
738
|
+
if Thread.isMainThread {
|
|
739
|
+
cleanupAnnotationFromMap()
|
|
740
|
+
} else {
|
|
741
|
+
DispatchQueue.main.sync {
|
|
742
|
+
cleanupAnnotationFromMap()
|
|
746
743
|
}
|
|
744
|
+
}
|
|
745
|
+
}
|
|
747
746
|
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
747
|
+
private func cleanupAnnotationFromMap() {
|
|
748
|
+
defer { isRemoving = false }
|
|
749
|
+
|
|
750
|
+
guard let mapView = mapView else { return }
|
|
751
|
+
|
|
752
|
+
if let animAnnotation = animatedAnnotation {
|
|
753
|
+
if let animations = animAnnotation.allMoveAnimations() {
|
|
754
|
+
for animation in animations {
|
|
755
|
+
animation.cancel()
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
mapView.removeAnnotation(animAnnotation)
|
|
759
|
+
animatedAnnotation = nil
|
|
751
760
|
}
|
|
752
761
|
|
|
753
|
-
if
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
DispatchQueue.main.async(execute: cleanup)
|
|
762
|
+
if let annotation = annotation {
|
|
763
|
+
mapView.removeAnnotation(annotation)
|
|
764
|
+
self.annotation = nil
|
|
757
765
|
}
|
|
766
|
+
|
|
767
|
+
annotationView?.annotation = nil
|
|
768
|
+
animatedAnnotationView?.annotation = nil
|
|
769
|
+
annotationView = nil
|
|
770
|
+
animatedAnnotationView = nil
|
|
771
|
+
isAnimating = false
|
|
772
|
+
lastSetMapView = nil
|
|
773
|
+
self.mapView = nil
|
|
758
774
|
}
|
|
759
775
|
|
|
760
776
|
override func willRemoveSubview(_ subview: UIView) {
|
|
@@ -780,10 +796,12 @@ class MarkerView: ExpoView {
|
|
|
780
796
|
}
|
|
781
797
|
|
|
782
798
|
private func scheduleSubviewRefresh(allowFallbackToDefault: Bool) {
|
|
799
|
+
guard superview != nil else { return }
|
|
800
|
+
|
|
783
801
|
pendingSubviewRefreshTask?.cancel()
|
|
784
802
|
|
|
785
803
|
let task = DispatchWorkItem { [weak self] in
|
|
786
|
-
guard let self = self, !self.isRemoving else { return }
|
|
804
|
+
guard let self = self, !self.isRemoving, self.superview != nil else { return }
|
|
787
805
|
self.refreshAnnotationForSubviewChanges(allowFallbackToDefault: allowFallbackToDefault)
|
|
788
806
|
}
|
|
789
807
|
|
|
@@ -1262,11 +1280,17 @@ class MarkerView: ExpoView {
|
|
|
1262
1280
|
pendingAddTask?.cancel()
|
|
1263
1281
|
pendingUpdateTask?.cancel()
|
|
1264
1282
|
pendingSubviewRefreshTask?.cancel()
|
|
1283
|
+
|
|
1284
|
+
if Thread.isMainThread {
|
|
1285
|
+
cleanupAnnotationFromMap()
|
|
1286
|
+
}
|
|
1265
1287
|
|
|
1266
1288
|
// 清理引用,防止内存泄漏
|
|
1267
1289
|
mapView = nil
|
|
1268
1290
|
annotation = nil
|
|
1269
1291
|
annotationView = nil
|
|
1292
|
+
animatedAnnotation = nil
|
|
1293
|
+
animatedAnnotationView = nil
|
|
1270
1294
|
lastSetMapView = nil
|
|
1271
1295
|
}
|
|
1272
1296
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-gaode-map-navigation",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.15",
|
|
4
4
|
"description": "React Native AMap (Gaode Map) navigation module for Expo: route planning and turn-by-turn navigation, includes full map features.",
|
|
5
5
|
"author": "TomWq <582752848@qq.com> (https://github.com/TomWq)",
|
|
6
6
|
"repository": {
|