expo-gaode-map-navigation 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.
Files changed (146) hide show
  1. package/README.md +213 -73
  2. package/android/build.gradle +10 -0
  3. package/android/src/main/cpp/CMakeLists.txt +24 -0
  4. package/android/src/main/cpp/cluster_jni.cpp +848 -0
  5. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapModule.kt +616 -92
  6. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapOfflineModule.kt +493 -0
  7. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapView.kt +230 -14
  8. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapViewModule.kt +37 -27
  9. package/android/src/main/java/expo/modules/gaodemap/map/MapPreloadManager.kt +494 -0
  10. package/android/src/main/java/expo/modules/gaodemap/map/companion/BitmapDescriptorCache.kt +30 -0
  11. package/android/src/main/java/expo/modules/gaodemap/map/companion/IconBitmapCache.kt +37 -0
  12. package/android/src/main/java/expo/modules/gaodemap/map/managers/UIManager.kt +76 -0
  13. package/android/src/main/java/expo/modules/gaodemap/map/modules/LocationManager.kt +15 -3
  14. package/android/src/main/java/expo/modules/gaodemap/map/modules/SDKInitializer.kt +4 -59
  15. package/android/src/main/java/expo/modules/gaodemap/map/overlays/CircleView.kt +9 -12
  16. package/android/src/main/java/expo/modules/gaodemap/map/overlays/CircleViewModule.kt +5 -6
  17. package/android/src/main/java/expo/modules/gaodemap/map/overlays/ClusterView.kt +539 -66
  18. package/android/src/main/java/expo/modules/gaodemap/map/overlays/ClusterViewModule.kt +17 -1
  19. package/android/src/main/java/expo/modules/gaodemap/map/overlays/HeatMapView.kt +165 -33
  20. package/android/src/main/java/expo/modules/gaodemap/map/overlays/HeatMapViewModule.kt +15 -3
  21. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MarkerView.kt +1249 -672
  22. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MarkerViewModule.kt +40 -17
  23. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MultiPointView.kt +177 -22
  24. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MultiPointViewModule.kt +11 -3
  25. package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolygonView.kt +57 -14
  26. package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolygonViewModule.kt +9 -5
  27. package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolylineView.kt +90 -63
  28. package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolylineViewModule.kt +7 -3
  29. package/android/src/main/java/expo/modules/gaodemap/map/services/LocationForegroundService.kt +3 -2
  30. package/android/src/main/java/expo/modules/gaodemap/map/utils/BitmapDescriptorCache.kt +20 -0
  31. package/android/src/main/java/expo/modules/gaodemap/map/utils/ClusterNative.kt +13 -0
  32. package/android/src/main/java/expo/modules/gaodemap/map/utils/ColorParser.kt +20 -0
  33. package/android/src/main/java/expo/modules/gaodemap/map/utils/GeometryUtils.kt +515 -0
  34. package/android/src/main/java/expo/modules/gaodemap/map/utils/LatLngParser.kt +91 -0
  35. package/android/src/main/java/expo/modules/gaodemap/map/utils/PermissionHelper.kt +248 -0
  36. package/build/ExpoGaodeMapNaviView.d.ts +7 -7
  37. package/build/ExpoGaodeMapNaviView.js +10 -11
  38. package/build/ExpoGaodeMapNavigationModule.d.ts +2 -1
  39. package/build/index.d.ts +35 -33
  40. package/build/index.js +70 -106
  41. package/build/map/ExpoGaodeMapModule.d.ts +2 -201
  42. package/build/map/ExpoGaodeMapModule.js +586 -18
  43. package/build/map/ExpoGaodeMapOfflineModule.d.ts +139 -0
  44. package/build/map/ExpoGaodeMapOfflineModule.js +8 -0
  45. package/build/map/ExpoGaodeMapView.js +66 -58
  46. package/build/map/components/FoldableMapView.d.ts +38 -0
  47. package/build/map/components/FoldableMapView.js +209 -0
  48. package/build/map/components/MapContext.d.ts +12 -0
  49. package/build/map/components/MapContext.js +54 -0
  50. package/build/map/components/MapUI.d.ts +18 -0
  51. package/build/map/components/MapUI.js +29 -0
  52. package/build/map/components/overlays/Circle.js +34 -3
  53. package/build/map/components/overlays/Cluster.d.ts +3 -1
  54. package/build/map/components/overlays/Cluster.js +31 -2
  55. package/build/map/components/overlays/HeatMap.d.ts +3 -1
  56. package/build/map/components/overlays/HeatMap.js +33 -3
  57. package/build/map/components/overlays/Marker.d.ts +1 -1
  58. package/build/map/components/overlays/Marker.js +37 -32
  59. package/build/map/components/overlays/MultiPoint.js +1 -1
  60. package/build/map/components/overlays/Polygon.js +30 -3
  61. package/build/map/components/overlays/Polyline.js +36 -3
  62. package/build/map/index.d.ts +25 -5
  63. package/build/map/index.js +59 -18
  64. package/build/map/types/common.types.d.ts +40 -0
  65. package/build/map/types/common.types.js +0 -4
  66. package/build/map/types/index.d.ts +3 -2
  67. package/build/map/types/map-view.types.d.ts +108 -3
  68. package/build/map/types/native-module.types.d.ts +363 -0
  69. package/build/map/types/native-module.types.js +5 -0
  70. package/build/map/types/offline.types.d.ts +132 -0
  71. package/build/map/types/offline.types.js +5 -0
  72. package/build/map/types/overlays.types.d.ts +137 -24
  73. package/build/map/utils/ErrorHandler.d.ts +110 -0
  74. package/build/map/utils/ErrorHandler.js +421 -0
  75. package/build/map/utils/GeoUtils.d.ts +20 -0
  76. package/build/map/utils/GeoUtils.js +76 -0
  77. package/build/map/utils/OfflineMapManager.d.ts +148 -0
  78. package/build/map/utils/OfflineMapManager.js +217 -0
  79. package/build/map/utils/PermissionUtils.d.ts +91 -0
  80. package/build/map/utils/PermissionUtils.js +255 -0
  81. package/build/map/utils/PlatformDetector.d.ts +102 -0
  82. package/build/map/utils/PlatformDetector.js +186 -0
  83. package/build/types/index.d.ts +1 -0
  84. package/build/types/index.js +1 -0
  85. package/build/types/native-module.types.d.ts +69 -0
  86. package/build/types/native-module.types.js +2 -0
  87. package/build/types/naviview.types.d.ts +1 -1
  88. package/expo-module.config.json +12 -10
  89. package/ios/ExpoGaodeMapNavigation.podspec +9 -0
  90. package/ios/map/ExpoGaodeMapModule.swift +485 -75
  91. package/ios/map/ExpoGaodeMapOfflineModule.swift +479 -0
  92. package/ios/map/ExpoGaodeMapView.swift +611 -62
  93. package/ios/map/ExpoGaodeMapViewModule.swift +48 -26
  94. package/ios/map/MapPreloadManager.swift +348 -0
  95. package/ios/map/cpp/ClusterEngine.cpp +110 -0
  96. package/ios/map/cpp/ClusterEngine.hpp +20 -0
  97. package/ios/map/cpp/ColorParser.cpp +135 -0
  98. package/ios/map/cpp/ColorParser.hpp +14 -0
  99. package/ios/map/cpp/GeometryEngine.cpp +574 -0
  100. package/ios/map/cpp/GeometryEngine.hpp +159 -0
  101. package/ios/map/cpp/QuadTree.cpp +92 -0
  102. package/ios/map/cpp/QuadTree.hpp +42 -0
  103. package/ios/map/cpp/README.md +55 -0
  104. package/ios/map/managers/UIManager.swift +72 -1
  105. package/ios/map/modules/LocationManager.swift +123 -166
  106. package/ios/map/overlays/CircleView.swift +16 -32
  107. package/ios/map/overlays/CircleViewModule.swift +12 -12
  108. package/ios/map/overlays/ClusterAnnotation.swift +32 -0
  109. package/ios/map/overlays/ClusterView.swift +331 -45
  110. package/ios/map/overlays/ClusterViewModule.swift +20 -6
  111. package/ios/map/overlays/HeatMapView.swift +135 -32
  112. package/ios/map/overlays/HeatMapViewModule.swift +20 -8
  113. package/ios/map/overlays/MarkerView.swift +613 -130
  114. package/ios/map/overlays/MarkerViewModule.swift +38 -18
  115. package/ios/map/overlays/MultiPointView.swift +168 -10
  116. package/ios/map/overlays/MultiPointViewModule.swift +27 -5
  117. package/ios/map/overlays/PolygonView.swift +62 -23
  118. package/ios/map/overlays/PolygonViewModule.swift +18 -12
  119. package/ios/map/overlays/PolylineView.swift +21 -13
  120. package/ios/map/overlays/PolylineViewModule.swift +18 -12
  121. package/ios/map/utils/ClusterNative.h +96 -0
  122. package/ios/map/utils/ClusterNative.mm +377 -0
  123. package/ios/map/utils/ColorParser.swift +12 -1
  124. package/ios/map/utils/CppBridging.mm +13 -0
  125. package/ios/map/utils/GeometryUtils.swift +34 -0
  126. package/ios/map/utils/LatLngParser.swift +87 -0
  127. package/ios/map/utils/PermissionManager.swift +135 -6
  128. package/package.json +3 -2
  129. package/shared/cpp/ClusterEngine.cpp +110 -0
  130. package/shared/cpp/ClusterEngine.hpp +20 -0
  131. package/shared/cpp/ColorParser.cpp +135 -0
  132. package/shared/cpp/ColorParser.hpp +14 -0
  133. package/shared/cpp/GeometryEngine.cpp +574 -0
  134. package/shared/cpp/GeometryEngine.hpp +159 -0
  135. package/shared/cpp/QuadTree.cpp +92 -0
  136. package/shared/cpp/QuadTree.hpp +42 -0
  137. package/shared/cpp/README.md +55 -0
  138. package/shared/cpp/tests/benchmark_js.js +41 -0
  139. package/shared/cpp/tests/run.sh +17 -0
  140. package/shared/cpp/tests/test_main.cpp +276 -0
  141. package/build/map/ExpoGaodeMap.types.d.ts +0 -41
  142. package/build/map/ExpoGaodeMap.types.js +0 -24
  143. package/build/map/utils/EventManager.d.ts +0 -10
  144. package/build/map/utils/EventManager.js +0 -26
  145. package/build/map/utils/ModuleLoader.d.ts +0 -73
  146. package/build/map/utils/ModuleLoader.js +0 -112
@@ -8,7 +8,7 @@ import expo.modules.kotlin.modules.ModuleDefinition
8
8
  */
9
9
  class ClusterViewModule : Module() {
10
10
  override fun definition() = ModuleDefinition {
11
- Name("NaviClusterView")
11
+ Name("ClusterView")
12
12
 
13
13
  View(ClusterView::class) {
14
14
  Events("onPress", "onClusterPress")
@@ -24,6 +24,22 @@ class ClusterViewModule : Module() {
24
24
  Prop<Int>("minClusterSize") { view: ClusterView, size ->
25
25
  view.setMinClusterSize(size)
26
26
  }
27
+
28
+ Prop<Map<String, Any>>("clusterStyle") { view: ClusterView, style ->
29
+ view.setClusterStyle(style)
30
+ }
31
+
32
+ Prop<List<Map<String, Any>>>("clusterBuckets") { view: ClusterView, buckets ->
33
+ view.setClusterBuckets(buckets)
34
+ }
35
+
36
+ Prop<Map<String, Any>>("clusterTextStyle") { view: ClusterView, style ->
37
+ view.setClusterTextStyle(style)
38
+ }
39
+
40
+ Prop<String>("icon") { view: ClusterView, icon ->
41
+ view.setIcon(icon)
42
+ }
27
43
  }
28
44
  }
29
45
  }
@@ -1,16 +1,28 @@
1
1
  package expo.modules.gaodemap.map.overlays
2
2
 
3
3
  import android.content.Context
4
+ import android.os.Looper
5
+ import android.util.Log
4
6
  import com.amap.api.maps.AMap
5
7
  import com.amap.api.maps.model.LatLng
6
8
  import com.amap.api.maps.model.TileOverlay
7
9
  import com.amap.api.maps.model.TileOverlayOptions
8
10
  import com.amap.api.maps.model.HeatmapTileProvider
11
+ import com.amap.api.maps.CameraUpdateFactory
9
12
  import expo.modules.kotlin.AppContext
10
13
  import expo.modules.kotlin.views.ExpoView
14
+ import java.util.concurrent.ExecutorService
15
+ import java.util.concurrent.Executors
16
+ import expo.modules.gaodemap.map.utils.LatLngParser
11
17
 
12
18
  class HeatMapView(context: Context, appContext: AppContext) : ExpoView(context, appContext) {
13
19
 
20
+ private val executor: ExecutorService = Executors.newSingleThreadExecutor()
21
+ private val applyUpdateRunnable = Runnable { applyUpdateOnMain() }
22
+ @Volatile private var updateToken: Int = 0
23
+ @Volatile private var needsRebuild: Boolean = true
24
+ private var visible: Boolean = true
25
+
14
26
  private var heatmapOverlay: TileOverlay? = null
15
27
  private var aMap: AMap? = null
16
28
  private var dataList: MutableList<LatLng> = mutableListOf()
@@ -23,23 +35,20 @@ class HeatMapView(context: Context, appContext: AppContext) : ExpoView(context,
23
35
  @Suppress("unused")
24
36
  fun setMap(map: AMap) {
25
37
  aMap = map
26
- createOrUpdateHeatMap()
38
+ needsRebuild = true
39
+ scheduleUpdate()
27
40
  }
28
41
 
42
+
43
+
29
44
  /**
30
45
  * 设置热力图数据
31
46
  */
32
- fun setData(data: List<Map<String, Any>>) {
47
+ fun setData(data: List<Any>?) {
33
48
  dataList.clear()
34
- data.forEach { point ->
35
- val lat = (point["latitude"] as? Number)?.toDouble()
36
- val lng = (point["longitude"] as? Number)?.toDouble()
37
- // 坐标验证
38
- if (lat != null && lng != null && lat >= -90 && lat <= 90 && lng >= -180 && lng <= 180) {
39
- dataList.add(LatLng(lat, lng))
40
- }
41
- }
42
- createOrUpdateHeatMap()
49
+ dataList.addAll(LatLngParser.parseLatLngList(data))
50
+ needsRebuild = true
51
+ scheduleUpdate()
43
52
  }
44
53
 
45
54
  /**
@@ -47,7 +56,8 @@ class HeatMapView(context: Context, appContext: AppContext) : ExpoView(context,
47
56
  */
48
57
  fun setRadius(radiusValue: Int) {
49
58
  radius = radiusValue
50
- createOrUpdateHeatMap()
59
+ needsRebuild = true
60
+ scheduleUpdate()
51
61
  }
52
62
 
53
63
  /**
@@ -55,41 +65,162 @@ class HeatMapView(context: Context, appContext: AppContext) : ExpoView(context,
55
65
  */
56
66
  fun setOpacity(opacityValue: Double) {
57
67
  opacity = opacityValue
58
- createOrUpdateHeatMap()
68
+ applyOverlayOpacity()
59
69
  }
60
-
70
+
71
+ fun setVisible(visibleValue: Boolean) {
72
+ if (!visibleValue) {
73
+ visible = false
74
+ updateToken += 1
75
+ removeCallbacks(applyUpdateRunnable)
76
+ applyOverlayVisibility()
77
+ return
78
+ }
79
+
80
+ visible = true
81
+ applyOverlayVisibility()
82
+
83
+ if (dataList.isEmpty()) {
84
+ return
85
+ }
86
+
87
+ if (heatmapOverlay == null || needsRebuild) {
88
+ scheduleUpdate()
89
+ } else {
90
+ applyOverlayOpacity()
91
+ forceRefresh()
92
+ }
93
+ }
94
+
95
+ private fun scheduleUpdate() {
96
+ updateToken += 1
97
+ removeCallbacks(applyUpdateRunnable)
98
+ postDelayed(applyUpdateRunnable, 32)
99
+ }
100
+
101
+ private fun applyOverlayVisibility() {
102
+ if (Looper.myLooper() != Looper.getMainLooper()) {
103
+ post { applyOverlayVisibility() }
104
+ return
105
+ }
106
+ val overlay = heatmapOverlay ?: return
107
+ runCatching {
108
+ overlay.javaClass.getMethod("setVisible", Boolean::class.javaPrimitiveType)
109
+ .invoke(overlay, visible)
110
+ }.onFailure {
111
+ if (!visible) {
112
+ overlay.remove()
113
+ heatmapOverlay = null
114
+ needsRebuild = true
115
+ }
116
+ }
117
+ }
118
+
119
+ private fun applyOverlayOpacity() {
120
+ if (Looper.myLooper() != Looper.getMainLooper()) {
121
+ post { applyOverlayOpacity() }
122
+ return
123
+ }
124
+ val overlay = heatmapOverlay ?: return
125
+ val opacityValue = opacity.coerceIn(0.0, 1.0)
126
+ val transparency = (1.0 - opacityValue).toFloat()
127
+ runCatching {
128
+ overlay.javaClass.getMethod("setTransparency", Float::class.javaPrimitiveType)
129
+ .invoke(overlay, transparency)
130
+ }
131
+ }
132
+
61
133
  /**
62
- * 创建或更新热力图
134
+ * 在主线程应用更新(构建 TileProvider 在后台线程)
63
135
  */
64
- private fun createOrUpdateHeatMap() {
65
- aMap?.let { map ->
66
- if (dataList.isNotEmpty()) {
67
- // 移除旧的热力图
68
- heatmapOverlay?.remove()
69
-
70
- // 创建热力图提供者
71
- val builder = HeatmapTileProvider.Builder()
72
- builder.data(dataList)
73
- builder.radius(radius)
74
-
75
- // 创建热力图图层
76
- val heatmapTileProvider = builder.build()
77
- val tileOverlayOptions = TileOverlayOptions()
78
- .tileProvider(heatmapTileProvider)
79
-
80
- heatmapOverlay = map.addTileOverlay(tileOverlayOptions)
81
- // 注意:TileOverlay 不支持 transparency 属性,透明度通过 HeatmapTileProvider 控制
136
+ private fun applyUpdateOnMain() {
137
+ if (Looper.myLooper() != Looper.getMainLooper()) {
138
+ post { applyUpdateOnMain() }
139
+ return
140
+ }
141
+
142
+ val map = aMap ?: return
143
+ val token = updateToken
144
+ val pointsSnapshot = ArrayList(dataList)
145
+ val radiusValue = radius.coerceIn(10, 200)
146
+ val opacityValue = opacity.coerceIn(0.0, 1.0)
147
+
148
+ if (!visible) {
149
+ applyOverlayVisibility()
150
+ return
151
+ }
152
+
153
+ if (pointsSnapshot.isEmpty()) {
154
+ heatmapOverlay?.remove()
155
+ heatmapOverlay = null
156
+ return
157
+ }
158
+
159
+ if (heatmapOverlay != null && !needsRebuild) {
160
+ applyOverlayVisibility()
161
+ applyOverlayOpacity()
162
+ return
163
+ }
164
+
165
+ executor.execute {
166
+ try {
167
+ val provider = HeatmapTileProvider.Builder()
168
+ .data(pointsSnapshot)
169
+ .radius(radiusValue)
170
+ .build()
171
+
172
+ post {
173
+ if (token != updateToken) {
174
+ return@post
175
+ }
176
+ if (aMap !== map) {
177
+ return@post
178
+ }
179
+ if (!visible) {
180
+ return@post
181
+ }
182
+
183
+ heatmapOverlay?.remove()
184
+
185
+ val options = TileOverlayOptions().tileProvider(provider)
186
+
187
+ runCatching {
188
+ options.javaClass.getMethod("zIndex", Float::class.javaPrimitiveType)
189
+ .invoke(options, 1f)
190
+ }
191
+
192
+ runCatching {
193
+ options.javaClass.getMethod("transparency", Float::class.javaPrimitiveType)
194
+ .invoke(options, (1.0 - opacityValue).toFloat())
195
+ }
196
+
197
+ heatmapOverlay = map.addTileOverlay(options)
198
+ needsRebuild = false
199
+ runCatching { heatmapOverlay?.clearTileCache() }
200
+ applyOverlayVisibility()
201
+ applyOverlayOpacity()
202
+ forceRefresh()
203
+ }
204
+ } catch (t: Throwable) {
205
+ Log.e("HeatMapView", "Failed to build heatmap", t)
82
206
  }
83
207
  }
84
208
  }
85
209
 
210
+ private fun forceRefresh() {
211
+ runCatching { aMap?.moveCamera(CameraUpdateFactory.zoomBy(0f)) }
212
+ }
213
+
86
214
  /**
87
215
  * 移除热力图
88
216
  */
89
217
  fun removeHeatMap() {
218
+ updateToken += 1
219
+ removeCallbacks(applyUpdateRunnable)
90
220
  heatmapOverlay?.remove()
91
221
  heatmapOverlay = null
92
222
  dataList.clear()
223
+ needsRebuild = true
93
224
  }
94
225
 
95
226
  override fun onDetachedFromWindow() {
@@ -99,6 +230,7 @@ class HeatMapView(context: Context, appContext: AppContext) : ExpoView(context,
99
230
  if (parent == null) {
100
231
  removeHeatMap()
101
232
  aMap = null
233
+ runCatching { executor.shutdownNow() }
102
234
  }
103
235
  }
104
236
  }
@@ -8,12 +8,16 @@ import expo.modules.kotlin.modules.ModuleDefinition
8
8
  */
9
9
  class HeatMapViewModule : Module() {
10
10
  override fun definition() = ModuleDefinition {
11
- Name("NaviHeatMapView")
11
+ Name("HeatMapView")
12
12
 
13
13
  View(HeatMapView::class) {
14
- Prop<List<Map<String, Any>>>("data") { view: HeatMapView, data ->
14
+ Prop<List<Any>?>("data") { view: HeatMapView, data ->
15
15
  view.setData(data)
16
16
  }
17
+
18
+ Prop<Boolean>("visible") { view: HeatMapView, visible ->
19
+ view.setVisible(visible)
20
+ }
17
21
 
18
22
  Prop<Int>("radius") { view: HeatMapView, radius ->
19
23
  view.setRadius(radius)
@@ -22,6 +26,14 @@ class HeatMapViewModule : Module() {
22
26
  Prop<Double>("opacity") { view: HeatMapView, opacity ->
23
27
  view.setOpacity(opacity)
24
28
  }
29
+
30
+ Prop<Map<String, Any>?>("gradient") { _: HeatMapView, _ ->
31
+ // iOS only, ignore on Android
32
+ }
33
+
34
+ Prop<Boolean>("allowRetinaAdapting") { _: HeatMapView, _ ->
35
+ // iOS only, ignore on Android
36
+ }
25
37
  }
26
38
  }
27
- }
39
+ }