expo-gaode-map 1.0.1 → 1.0.3

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 (106) hide show
  1. package/README.md +1 -0
  2. package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapModule.kt +17 -1
  3. package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapView.kt +52 -5
  4. package/android/src/main/java/expo/modules/gaodemap/managers/OverlayManager.kt +184 -6
  5. package/android/src/main/java/expo/modules/gaodemap/overlays/CircleView.kt +24 -51
  6. package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerView.kt +3 -0
  7. package/build/ExpoGaodeMap.types.d.ts.map +1 -1
  8. package/build/ExpoGaodeMap.types.js +0 -10
  9. package/build/ExpoGaodeMap.types.js.map +1 -1
  10. package/build/ExpoGaodeMapModule.d.ts.map +1 -1
  11. package/build/ExpoGaodeMapModule.js +0 -10
  12. package/build/ExpoGaodeMapModule.js.map +1 -1
  13. package/build/ExpoGaodeMapView.d.ts +39 -20
  14. package/build/ExpoGaodeMapView.d.ts.map +1 -1
  15. package/build/ExpoGaodeMapView.js +215 -31
  16. package/build/ExpoGaodeMapView.js.map +1 -1
  17. package/build/components/overlays/Circle.d.ts +0 -15
  18. package/build/components/overlays/Circle.d.ts.map +1 -1
  19. package/build/components/overlays/Circle.js +28 -46
  20. package/build/components/overlays/Circle.js.map +1 -1
  21. package/build/components/overlays/Cluster.d.ts +3 -15
  22. package/build/components/overlays/Cluster.d.ts.map +1 -1
  23. package/build/components/overlays/Cluster.js +3 -25
  24. package/build/components/overlays/Cluster.js.map +1 -1
  25. package/build/components/overlays/HeatMap.d.ts +3 -14
  26. package/build/components/overlays/HeatMap.d.ts.map +1 -1
  27. package/build/components/overlays/HeatMap.js +3 -24
  28. package/build/components/overlays/HeatMap.js.map +1 -1
  29. package/build/components/overlays/Marker.d.ts +2 -15
  30. package/build/components/overlays/Marker.d.ts.map +1 -1
  31. package/build/components/overlays/Marker.js +60 -46
  32. package/build/components/overlays/Marker.js.map +1 -1
  33. package/build/components/overlays/MultiPoint.d.ts +3 -14
  34. package/build/components/overlays/MultiPoint.d.ts.map +1 -1
  35. package/build/components/overlays/MultiPoint.js +3 -24
  36. package/build/components/overlays/MultiPoint.js.map +1 -1
  37. package/build/components/overlays/Polygon.d.ts +13 -16
  38. package/build/components/overlays/Polygon.d.ts.map +1 -1
  39. package/build/components/overlays/Polygon.js +41 -75
  40. package/build/components/overlays/Polygon.js.map +1 -1
  41. package/build/components/overlays/Polyline.d.ts +12 -14
  42. package/build/components/overlays/Polyline.d.ts.map +1 -1
  43. package/build/components/overlays/Polyline.js +34 -35
  44. package/build/components/overlays/Polyline.js.map +1 -1
  45. package/build/components/overlays/index.d.ts.map +1 -1
  46. package/build/components/overlays/index.js +0 -10
  47. package/build/components/overlays/index.js.map +1 -1
  48. package/build/index.d.ts.map +1 -1
  49. package/build/index.js +0 -10
  50. package/build/index.js.map +1 -1
  51. package/build/modules/AMapLocation.d.ts +47 -10
  52. package/build/modules/AMapLocation.d.ts.map +1 -1
  53. package/build/modules/AMapLocation.js +48 -20
  54. package/build/modules/AMapLocation.js.map +1 -1
  55. package/build/modules/AMapPermissions.d.ts +3 -1
  56. package/build/modules/AMapPermissions.d.ts.map +1 -1
  57. package/build/modules/AMapPermissions.js +3 -11
  58. package/build/modules/AMapPermissions.js.map +1 -1
  59. package/build/modules/AMapSDK.d.ts +5 -4
  60. package/build/modules/AMapSDK.d.ts.map +1 -1
  61. package/build/modules/AMapSDK.js +5 -14
  62. package/build/modules/AMapSDK.js.map +1 -1
  63. package/build/modules/AMapView.d.ts.map +1 -1
  64. package/build/modules/AMapView.js +0 -8
  65. package/build/modules/AMapView.js.map +1 -1
  66. package/build/types/index.d.ts.map +1 -1
  67. package/build/types/index.js +0 -10
  68. package/build/types/index.js.map +1 -1
  69. package/build/types/map-view.types.d.ts +30 -0
  70. package/build/types/map-view.types.d.ts.map +1 -1
  71. package/build/types/map-view.types.js.map +1 -1
  72. package/build/types/overlays.types.d.ts +25 -1
  73. package/build/types/overlays.types.d.ts.map +1 -1
  74. package/build/types/overlays.types.js.map +1 -1
  75. package/docs/API.md +40 -0
  76. package/docs/EXAMPLES.md +86 -2
  77. package/docs/RELEASE_GUIDE.md +178 -0
  78. package/expo-module.config.json +1 -1
  79. package/ios/ExpoGaodeMapModule.swift +42 -14
  80. package/ios/ExpoGaodeMapView.swift +210 -7
  81. package/ios/managers/OverlayManager.swift +78 -10
  82. package/ios/overlays/CircleView.swift +41 -12
  83. package/ios/overlays/MarkerView.swift +55 -3
  84. package/ios/overlays/PolygonView.swift +25 -5
  85. package/ios/overlays/PolylineView.swift +23 -4
  86. package/ios/utils/ColorParser.swift +0 -5
  87. package/package.json +1 -1
  88. package/src/ExpoGaodeMap.types.ts +1 -10
  89. package/src/ExpoGaodeMapModule.ts +1 -10
  90. package/src/ExpoGaodeMapView.tsx +257 -38
  91. package/src/components/overlays/Circle.tsx +32 -50
  92. package/src/components/overlays/Cluster.tsx +4 -26
  93. package/src/components/overlays/HeatMap.tsx +4 -25
  94. package/src/components/overlays/Marker.tsx +69 -52
  95. package/src/components/overlays/MultiPoint.tsx +4 -25
  96. package/src/components/overlays/Polygon.tsx +48 -78
  97. package/src/components/overlays/Polyline.tsx +41 -38
  98. package/src/components/overlays/index.ts +0 -11
  99. package/src/index.ts +0 -11
  100. package/src/modules/AMapLocation.ts +56 -20
  101. package/src/modules/AMapPermissions.ts +4 -11
  102. package/src/modules/AMapSDK.ts +7 -14
  103. package/src/modules/AMapView.ts +0 -8
  104. package/src/types/index.ts +1 -10
  105. package/src/types/map-view.types.ts +25 -0
  106. package/src/types/overlays.types.ts +30 -1
package/README.md CHANGED
@@ -580,3 +580,4 @@ MIT
580
580
  - 📝 提交 [GitHub Issue](https://github.com/TomWq/expo-gaode-map/issues)
581
581
  - 💬 参与 [Discussions](https://github.com/TomWq/expo-gaode-map/discussions)
582
582
  - ⭐ 给项目点个 Star 支持一下
583
+ - 💬 加入 QQ 群:952241387
@@ -271,7 +271,7 @@ class ExpoGaodeMapModule : Module() {
271
271
  View(ExpoGaodeMapView::class) {
272
272
 
273
273
  // 事件
274
- Events("onMapPress", "onMapLongPress", "onLoad")
274
+ Events("onMapPress", "onMapLongPress", "onLoad", "onMarkerPress", "onMarkerDragStart", "onMarkerDrag", "onMarkerDragEnd", "onCirclePress")
275
275
 
276
276
  // 地图类型
277
277
  Prop<Int>("mapType") { view, type ->
@@ -416,6 +416,22 @@ class ExpoGaodeMapModule : Module() {
416
416
  Prop<Boolean>("draggable") { view: MarkerView, draggable ->
417
417
  view.setDraggable(draggable)
418
418
  }
419
+
420
+ Prop<Float>("opacity") { view: MarkerView, opacity ->
421
+ view.setOpacity(opacity)
422
+ }
423
+
424
+ Prop<Boolean>("flat") { view: MarkerView, flat ->
425
+ view.setFlat(flat)
426
+ }
427
+
428
+ Prop<Float>("zIndex") { view: MarkerView, zIndex ->
429
+ view.setZIndex(zIndex)
430
+ }
431
+
432
+ Prop<Map<String, Float>>("anchor") { view: MarkerView, anchor ->
433
+ view.setAnchor(anchor)
434
+ }
419
435
  }
420
436
 
421
437
  // Circle - 圆形
@@ -45,6 +45,11 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
45
45
  private val onMapPress by EventDispatcher()
46
46
  private val onMapLongPress by EventDispatcher()
47
47
  private val onLoad by EventDispatcher()
48
+ private val onMarkerPress by EventDispatcher()
49
+ private val onMarkerDragStart by EventDispatcher()
50
+ private val onMarkerDrag by EventDispatcher()
51
+ private val onMarkerDragEnd by EventDispatcher()
52
+ private val onCirclePress by EventDispatcher()
48
53
 
49
54
  // 高德地图视图
50
55
  private lateinit var mapView: MapView
@@ -73,7 +78,43 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
73
78
  // 初始化管理器
74
79
  cameraManager = CameraManager(aMap)
75
80
  uiManager = UIManager(aMap, context)
76
- overlayManager = OverlayManager(aMap)
81
+ overlayManager = OverlayManager(aMap, context).apply {
82
+ onMarkerPress = { id, lat, lng ->
83
+ this@ExpoGaodeMapView.onMarkerPress(mapOf(
84
+ "markerId" to id,
85
+ "latitude" to lat,
86
+ "longitude" to lng
87
+ ))
88
+ }
89
+ onMarkerDragStart = { id, lat, lng ->
90
+ this@ExpoGaodeMapView.onMarkerDragStart(mapOf(
91
+ "markerId" to id,
92
+ "latitude" to lat,
93
+ "longitude" to lng
94
+ ))
95
+ }
96
+ onMarkerDrag = { id, lat, lng ->
97
+ this@ExpoGaodeMapView.onMarkerDrag(mapOf(
98
+ "markerId" to id,
99
+ "latitude" to lat,
100
+ "longitude" to lng
101
+ ))
102
+ }
103
+ onMarkerDragEnd = { id, lat, lng ->
104
+ this@ExpoGaodeMapView.onMarkerDragEnd(mapOf(
105
+ "markerId" to id,
106
+ "latitude" to lat,
107
+ "longitude" to lng
108
+ ))
109
+ }
110
+ onCirclePress = { id, lat, lng ->
111
+ this@ExpoGaodeMapView.onCirclePress(mapOf(
112
+ "circleId" to id,
113
+ "latitude" to lat,
114
+ "longitude" to lng
115
+ ))
116
+ }
117
+ }
77
118
 
78
119
  // 添加地图视图到布局
79
120
  addView(mapView, LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT))
@@ -108,10 +149,16 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
108
149
  */
109
150
  private fun setupMapListeners() {
110
151
  aMap.setOnMapClickListener { latLng ->
111
- onMapPress(mapOf(
112
- "latitude" to latLng.latitude,
113
- "longitude" to latLng.longitude
114
- ))
152
+ // 先检查是否点击了圆形
153
+ val circleId = overlayManager.checkCirclePress(latLng)
154
+ if (circleId != null) {
155
+ overlayManager.onCirclePress?.invoke(circleId, latLng.latitude, latLng.longitude)
156
+ } else {
157
+ onMapPress(mapOf(
158
+ "latitude" to latLng.latitude,
159
+ "longitude" to latLng.longitude
160
+ ))
161
+ }
115
162
  }
116
163
 
117
164
  aMap.setOnMapLongClickListener { latLng ->
@@ -1,6 +1,8 @@
1
1
  package expo.modules.gaodemap.managers
2
2
 
3
+ import android.content.Context
3
4
  import android.util.Log
5
+ import android.graphics.Bitmap
4
6
  import android.graphics.BitmapFactory
5
7
  import com.amap.api.maps.AMap
6
8
  import com.amap.api.maps.model.LatLng
@@ -12,7 +14,7 @@ import java.net.URL
12
14
  * 覆盖物管理器
13
15
  * 负责地图上所有覆盖物的添加、删除、更新
14
16
  */
15
- class OverlayManager(private val aMap: AMap) {
17
+ class OverlayManager(private val aMap: AMap, private val context: Context) {
16
18
 
17
19
  companion object {
18
20
  private const val TAG = "OverlayManager"
@@ -24,6 +26,21 @@ class OverlayManager(private val aMap: AMap) {
24
26
  private val polylines = mutableMapOf<String, com.amap.api.maps.model.Polyline>()
25
27
  private val polygons = mutableMapOf<String, com.amap.api.maps.model.Polygon>()
26
28
 
29
+ // Marker ID 映射
30
+ private val markerIdMap = mutableMapOf<com.amap.api.maps.model.Marker, String>()
31
+
32
+ // Circle ID 映射
33
+ private val circleIdMap = mutableMapOf<com.amap.api.maps.model.Circle, String>()
34
+
35
+ // 事件回调
36
+ var onMarkerPress: ((String, Double, Double) -> Unit)? = null
37
+ var onMarkerDragStart: ((String, Double, Double) -> Unit)? = null
38
+ var onMarkerDrag: ((String, Double, Double) -> Unit)? = null
39
+ var onMarkerDragEnd: ((String, Double, Double) -> Unit)? = null
40
+ var onCirclePress: ((String, Double, Double) -> Unit)? = null
41
+
42
+ private val mainHandler = android.os.Handler(android.os.Looper.getMainLooper())
43
+
27
44
  // ==================== 圆形覆盖物 ====================
28
45
 
29
46
  fun addCircle(id: String, props: Map<String, Any>) {
@@ -49,11 +66,13 @@ class OverlayManager(private val aMap: AMap) {
49
66
 
50
67
  val circle = aMap.addCircle(options)
51
68
  circles[id] = circle
69
+ circleIdMap[circle] = id
52
70
  }
53
71
  }
54
72
 
55
73
  fun removeCircle(id: String) {
56
74
  circles[id]?.let { circle ->
75
+ circleIdMap.remove(circle)
57
76
  circle.remove()
58
77
  circles.remove(id)
59
78
  }
@@ -84,11 +103,22 @@ class OverlayManager(private val aMap: AMap) {
84
103
  // ==================== 标记点 ====================
85
104
 
86
105
  fun addMarker(id: String, props: Map<String, Any>) {
106
+ Log.d(TAG, "addMarker 调用 - ID: $id")
107
+ Log.d(TAG, "addMarker props: $props")
87
108
 
88
109
  @Suppress("UNCHECKED_CAST")
89
110
  val position = props["position"] as? Map<String, Double>
90
111
  val title = props["title"] as? String
112
+ val snippet = props["snippet"] as? String
91
113
  val draggable = props["draggable"] as? Boolean ?: false
114
+ val icon = props["icon"]
115
+ // 将 RN 的点(points)转换为 Android 的 dp
116
+ val iconWidth = dpToPx((props["iconWidth"] as? Number)?.toFloat() ?: 40f)
117
+ val iconHeight = dpToPx((props["iconHeight"] as? Number)?.toFloat() ?: 40f)
118
+ val opacity = (props["opacity"] as? Number)?.toFloat() ?: 1.0f
119
+ val flat = props["flat"] as? Boolean ?: false
120
+ val zIndex = (props["zIndex"] as? Number)?.toFloat() ?: 0f
121
+ val anchor = props["anchor"] as? Map<String, Double>
92
122
 
93
123
  if (position != null) {
94
124
  val lat = position["latitude"] ?: 0.0
@@ -98,21 +128,115 @@ class OverlayManager(private val aMap: AMap) {
98
128
  val options = com.amap.api.maps.model.MarkerOptions()
99
129
  .position(latLng)
100
130
  .draggable(draggable)
131
+ .setFlat(flat)
132
+ .zIndex(zIndex)
101
133
 
102
134
  title?.let { options.title(it) }
135
+ snippet?.let { options.snippet(it) }
136
+
137
+ anchor?.let {
138
+ val x = (it["x"] as? Number)?.toFloat() ?: 0.5f
139
+ val y = (it["y"] as? Number)?.toFloat() ?: 1.0f
140
+ options.anchor(x, y)
141
+ }
103
142
 
104
143
  val marker = aMap.addMarker(options)
144
+ marker?.alpha = opacity
105
145
 
106
- if (!title.isNullOrEmpty()) {
107
- marker?.showInfoWindow()
146
+ markers[id] = marker
147
+ marker?.let { markerIdMap[it] = id }
148
+
149
+ // 加载自定义图标
150
+ icon?.let {
151
+ val uri = when (it) {
152
+ is String -> it
153
+ is Map<*, *> -> it["uri"] as? String
154
+ else -> null
155
+ }
156
+ uri?.let { iconUri ->
157
+ loadMarkerIcon(iconUri, iconWidth, iconHeight) { bitmap ->
158
+ mainHandler.post {
159
+ marker?.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap))
160
+ }
161
+ }
162
+ }
108
163
  }
109
164
 
110
- markers[id] = marker
165
+ // 设置事件监听器(只设置一次)
166
+ setupMarkerListeners()
111
167
  }
112
168
  }
113
169
 
170
+ private fun setupMarkerListeners() {
171
+ aMap.setOnMarkerClickListener { marker ->
172
+ markerIdMap[marker]?.let { id ->
173
+ onMarkerPress?.invoke(id, marker.position.latitude, marker.position.longitude)
174
+ }
175
+ false // 返回 false 允许显示 InfoWindow
176
+ }
177
+
178
+ aMap.setOnMarkerDragListener(object : AMap.OnMarkerDragListener {
179
+ override fun onMarkerDragStart(marker: com.amap.api.maps.model.Marker?) {
180
+ marker?.let { m ->
181
+ markerIdMap[m]?.let { id ->
182
+ onMarkerDragStart?.invoke(id, m.position.latitude, m.position.longitude)
183
+ }
184
+ }
185
+ }
186
+
187
+ override fun onMarkerDrag(marker: com.amap.api.maps.model.Marker?) {
188
+ marker?.let { m ->
189
+ markerIdMap[m]?.let { id ->
190
+ onMarkerDrag?.invoke(id, m.position.latitude, m.position.longitude)
191
+ }
192
+ }
193
+ }
194
+
195
+ override fun onMarkerDragEnd(marker: com.amap.api.maps.model.Marker?) {
196
+ marker?.let { m ->
197
+ markerIdMap[m]?.let { id ->
198
+ onMarkerDragEnd?.invoke(id, m.position.latitude, m.position.longitude)
199
+ }
200
+ }
201
+ }
202
+ })
203
+ }
204
+
205
+ private fun loadMarkerIcon(uri: String, width: Int, height: Int, callback: (Bitmap) -> Unit) {
206
+ Thread {
207
+ try {
208
+ Log.d(TAG, "开始加载图标: $uri")
209
+ val bitmap = when {
210
+ uri.startsWith("http://") || uri.startsWith("https://") -> {
211
+ Log.d(TAG, "加载网络图片")
212
+ BitmapFactory.decodeStream(URL(uri).openStream())
213
+ }
214
+ uri.startsWith("file://") -> {
215
+ Log.d(TAG, "加载本地文件")
216
+ BitmapFactory.decodeFile(uri.substring(7))
217
+ }
218
+ else -> {
219
+ Log.d(TAG, "未知 URI 格式")
220
+ null
221
+ }
222
+ }
223
+
224
+ if (bitmap == null) {
225
+ Log.e(TAG, "图标加载失败: bitmap 为 null")
226
+ } else {
227
+ Log.d(TAG, "图标加载成功: ${bitmap.width}x${bitmap.height}")
228
+ val resized = Bitmap.createScaledBitmap(bitmap, width, height, true)
229
+ callback(resized)
230
+ }
231
+ } catch (e: Exception) {
232
+ Log.e(TAG, "图标加载异常: ${e.message}", e)
233
+ }
234
+ }.start()
235
+ }
236
+
114
237
  fun removeMarker(id: String) {
115
238
  markers[id]?.let { marker ->
239
+ markerIdMap.remove(marker)
116
240
  marker.remove()
117
241
  markers.remove(id)
118
242
  }
@@ -123,7 +247,15 @@ class OverlayManager(private val aMap: AMap) {
123
247
  @Suppress("UNCHECKED_CAST")
124
248
  val position = props["position"] as? Map<String, Double>
125
249
  val title = props["title"] as? String
250
+ val snippet = props["snippet"] as? String
126
251
  val draggable = props["draggable"] as? Boolean
252
+ val icon = props["icon"]
253
+ val iconWidth = dpToPx((props["iconWidth"] as? Number)?.toFloat() ?: 40f)
254
+ val iconHeight = dpToPx((props["iconHeight"] as? Number)?.toFloat() ?: 40f)
255
+ val opacity = props["opacity"] as? Number
256
+ val flat = props["flat"] as? Boolean
257
+ val zIndex = props["zIndex"] as? Number
258
+ val anchor = props["anchor"] as? Map<String, Double>
127
259
 
128
260
  position?.let {
129
261
  val lat = it["latitude"] ?: 0.0
@@ -132,7 +264,32 @@ class OverlayManager(private val aMap: AMap) {
132
264
  }
133
265
 
134
266
  title?.let { marker.title = it }
267
+ snippet?.let { marker.snippet = it }
135
268
  draggable?.let { marker.isDraggable = it }
269
+ opacity?.let { marker.alpha = it.toFloat() }
270
+ flat?.let { marker.isFlat = it }
271
+ zIndex?.let { marker.zIndex = it.toFloat() }
272
+
273
+ anchor?.let {
274
+ val x = (it["x"] as? Number)?.toFloat() ?: 0.5f
275
+ val y = (it["y"] as? Number)?.toFloat() ?: 1.0f
276
+ marker.setAnchor(x, y)
277
+ }
278
+
279
+ icon?.let {
280
+ val uri = when (it) {
281
+ is String -> it
282
+ is Map<*, *> -> it["uri"] as? String
283
+ else -> null
284
+ }
285
+ uri?.let { iconUri ->
286
+ loadMarkerIcon(iconUri, iconWidth, iconHeight) { bitmap ->
287
+ mainHandler.post {
288
+ marker.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap))
289
+ }
290
+ }
291
+ }
292
+ }
136
293
  }
137
294
  }
138
295
 
@@ -142,12 +299,12 @@ class OverlayManager(private val aMap: AMap) {
142
299
 
143
300
  @Suppress("UNCHECKED_CAST")
144
301
  val points = props["points"] as? List<Map<String, Double>>
145
- val width = (props["strokeWidth"] as? Number)?.toFloat() ?: 10f
302
+ val width = (props["width"] as? Number)?.toFloat() ?: (props["strokeWidth"] as? Number)?.toFloat() ?: 10f
146
303
  val texture = props["texture"] as? String
147
304
  val color = if (!texture.isNullOrEmpty()) {
148
305
  android.graphics.Color.TRANSPARENT
149
306
  } else {
150
- ColorParser.parseColor(props["strokeColor"])
307
+ ColorParser.parseColor(props["color"] ?: props["strokeColor"])
151
308
  }
152
309
 
153
310
  if (points != null && points.size >= 2) {
@@ -287,9 +444,22 @@ class OverlayManager(private val aMap: AMap) {
287
444
  /**
288
445
  * 清理所有覆盖物
289
446
  */
447
+ /**
448
+ * 检查点击位置是否在某个圆形内
449
+ */
450
+ fun checkCirclePress(latLng: LatLng): String? {
451
+ for ((circle, id) in circleIdMap) {
452
+ if (circle.contains(latLng)) {
453
+ return id
454
+ }
455
+ }
456
+ return null
457
+ }
458
+
290
459
  fun clear() {
291
460
  circles.values.forEach { it.remove() }
292
461
  circles.clear()
462
+ circleIdMap.clear()
293
463
 
294
464
  markers.values.forEach { it.remove() }
295
465
  markers.clear()
@@ -300,4 +470,12 @@ class OverlayManager(private val aMap: AMap) {
300
470
  polygons.values.forEach { it.remove() }
301
471
  polygons.clear()
302
472
  }
473
+
474
+ /**
475
+ * 将 dp 转换为 px
476
+ */
477
+ private fun dpToPx(dp: Float): Int {
478
+ val density = context.resources.displayMetrics.density
479
+ return (dp * density + 0.5f).toInt()
480
+ }
303
481
  }
@@ -19,6 +19,9 @@ class CircleView(context: Context, appContext: AppContext) : ExpoView(context, a
19
19
  private var aMap: AMap? = null
20
20
  private var center: LatLng? = null
21
21
  private var radius: Double = 1000.0
22
+ private var fillColor: Int = Color.argb(50, 0, 0, 255)
23
+ private var strokeColor: Int = Color.BLUE
24
+ private var strokeWidth: Float = 10f
22
25
 
23
26
  /**
24
27
  * 设置地图实例
@@ -26,28 +29,19 @@ class CircleView(context: Context, appContext: AppContext) : ExpoView(context, a
26
29
  @Suppress("unused")
27
30
  fun setMap(map: AMap) {
28
31
  aMap = map
29
- // 不立即创建,等 props 设置完成后再创建
32
+ // 延迟创建圆形,确保所有 props 都已设置
33
+ post { createOrUpdateCircle() }
30
34
  }
31
35
 
32
36
  /**
33
37
  * 设置圆心
34
38
  */
35
39
  fun setCenter(centerMap: Map<String, Double>) {
36
- android.util.Log.d("CircleView", "setCenter 被调用: $centerMap")
37
40
  val lat = centerMap["latitude"]
38
41
  val lng = centerMap["longitude"]
39
42
  if (lat != null && lng != null) {
40
43
  center = LatLng(lat, lng)
41
- android.util.Log.d("CircleView", "圆心设置为: lat=$lat, lng=$lng")
42
-
43
- // 如果圆形已存在,更新它;否则创建新圆形
44
- circle?.let {
45
- android.util.Log.d("CircleView", "更新现有圆形的圆心")
46
- it.center = center
47
- } ?: run {
48
- android.util.Log.d("CircleView", "圆形不存在,尝试创建")
49
- createOrUpdateCircle()
50
- }
44
+ circle?.center = center
51
45
  }
52
46
  }
53
47
 
@@ -56,77 +50,56 @@ class CircleView(context: Context, appContext: AppContext) : ExpoView(context, a
56
50
  */
57
51
  fun setRadius(radiusValue: Double) {
58
52
  radius = radiusValue
59
- circle?.let {
60
- it.radius = radius
61
- }
62
- // 半径可以后续更新,不需要在这里创建圆形
53
+ circle?.radius = radius
63
54
  }
64
55
 
65
56
  /**
66
57
  * 设置填充颜色
67
58
  */
68
59
  fun setFillColor(color: Int) {
69
- circle?.let {
70
- it.fillColor = color
71
- }
60
+ fillColor = color
61
+ circle?.fillColor = color
72
62
  }
73
63
 
74
64
  /**
75
65
  * 设置边框颜色
76
66
  */
77
67
  fun setStrokeColor(color: Int) {
78
- circle?.let {
79
- it.strokeColor = color
80
- }
68
+ strokeColor = color
69
+ circle?.strokeColor = color
81
70
  }
82
71
 
83
72
  /**
84
73
  * 设置边框宽度
85
74
  */
86
75
  fun setStrokeWidth(width: Float) {
87
- circle?.let {
88
- it.strokeWidth = width
89
- }
76
+ strokeWidth = width
77
+ circle?.strokeWidth = width
90
78
  }
91
79
 
92
80
  /**
93
81
  * 设置 z-index
94
82
  */
95
83
  fun setZIndex(zIndex: Float) {
96
- circle?.let {
97
- it.zIndex = zIndex
98
- } ?: createOrUpdateCircle()
84
+ circle?.zIndex = zIndex
99
85
  }
100
86
 
101
87
  /**
102
88
  * 创建或更新圆形
103
89
  */
104
90
  private fun createOrUpdateCircle() {
105
- android.util.Log.d("CircleView", "createOrUpdateCircle 被调用")
106
- android.util.Log.d("CircleView", "aMap: $aMap, center: $center, radius: $radius")
107
-
108
- // 必须同时有地图实例和圆心才能创建
109
- val map = aMap ?: run {
110
- android.util.Log.w("CircleView", "⚠️ aMap 为 null,无法创建圆形")
111
- return
112
- }
113
-
114
- val centerPoint = center ?: run {
115
- android.util.Log.w("CircleView", "⚠️ center 为 null,无法创建圆形")
116
- return
117
- }
91
+ val map = aMap ?: return
92
+ val centerPoint = center ?: return
118
93
 
119
94
  if (circle == null) {
120
- android.util.Log.d("CircleView", "创建新圆形 - center: $centerPoint, radius: $radius")
121
- val options = CircleOptions()
122
- .center(centerPoint)
123
- .radius(radius)
124
- .fillColor(Color.argb(50, 0, 0, 255)) // 默认半透明蓝色
125
- .strokeColor(Color.BLUE) // 默认蓝色边框
126
- .strokeWidth(10f) // 默认边框宽度
127
-
128
- circle = map.addCircle(options)
129
- android.util.Log.d("CircleView", "✅ 圆形创建成功: $circle")
95
+ circle = map.addCircle(
96
+ CircleOptions()
97
+ .center(centerPoint)
98
+ .radius(radius)
99
+ .fillColor(fillColor)
100
+ .strokeColor(strokeColor)
101
+ .strokeWidth(strokeWidth)
102
+ )
130
103
  }
131
104
  }
132
105
 
@@ -1,6 +1,9 @@
1
1
  package expo.modules.gaodemap.overlays
2
2
 
3
3
  import android.content.Context
4
+ import android.graphics.Bitmap
5
+ import android.graphics.Canvas
6
+ import android.view.View
4
7
  import com.amap.api.maps.AMap
5
8
  import com.amap.api.maps.model.BitmapDescriptorFactory
6
9
  import com.amap.api.maps.model.LatLng
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoGaodeMap.types.d.ts","sourceRoot":"","sources":["../src/ExpoGaodeMap.types.ts"],"names":[],"mappings":"AAYA,cAAc,SAAS,CAAC;AAGxB,YAAY,EAEV,MAAM,EACN,KAAK,EACL,cAAc,EACd,YAAY,EACZ,MAAM,EAGN,YAAY,EACZ,WAAW,EAGX,WAAW,EACX,SAAS,EACT,eAAe,EAGf,WAAW,EACX,aAAa,EACb,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,eAAe,EACf,YAAY,GACb,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,OAAO,EACP,YAAY,EACZ,gBAAgB,EAChB,cAAc,GACf,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;OAEG;IACH,gBAAgB,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,CAAC;IAE1C;;OAEG;IACH,eAAe,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACrE,CAAC;AAEF;;GAEG;AACH,YAAY,EAAE,YAAY,IAAI,qBAAqB,EAAE,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"ExpoGaodeMap.types.d.ts","sourceRoot":"","sources":["../src/ExpoGaodeMap.types.ts"],"names":[],"mappings":"AAGA,cAAc,SAAS,CAAC;AAGxB,YAAY,EAEV,MAAM,EACN,KAAK,EACL,cAAc,EACd,YAAY,EACZ,MAAM,EAGN,YAAY,EACZ,WAAW,EAGX,WAAW,EACX,SAAS,EACT,eAAe,EAGf,WAAW,EACX,aAAa,EACb,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,eAAe,EACf,YAAY,GACb,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,OAAO,EACP,YAAY,EACZ,gBAAgB,EAChB,cAAc,GACf,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;OAEG;IACH,gBAAgB,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,CAAC;IAE1C;;OAEG;IACH,eAAe,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACrE,CAAC;AAEF;;GAEG;AACH,YAAY,EAAE,YAAY,IAAI,qBAAqB,EAAE,MAAM,SAAS,CAAC"}
@@ -1,13 +1,3 @@
1
- /*
2
- * @Author : 尚博信_王强 wangqiang03@sunboxsoft.com
3
- * @Date : 2025-11-13 14:03:56
4
- * @LastEditors : 尚博信_王强 wangqiang03@sunboxsoft.com
5
- * @LastEditTime : 2025-11-13 14:30:00
6
- * @FilePath : /expo-gaode-map/src/ExpoGaodeMap.types.ts
7
- * @Description : 高德地图 Expo Module 主类型定义文件
8
- *
9
- * Copyright (c) 2025 by 尚博信_王强, All Rights Reserved.
10
- */
11
1
  // 导出所有类型定义
12
2
  export * from './types';
13
3
  export { MapType, LocationMode, LocationAccuracy, CoordinateType, } from './types';
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoGaodeMap.types.js","sourceRoot":"","sources":["../src/ExpoGaodeMap.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,WAAW;AACX,cAAc,SAAS,CAAC;AA8BxB,OAAO,EACL,OAAO,EACP,YAAY,EACZ,gBAAgB,EAChB,cAAc,GACf,MAAM,SAAS,CAAC","sourcesContent":["/*\n * @Author : 尚博信_王强 wangqiang03@sunboxsoft.com\n * @Date : 2025-11-13 14:03:56\n * @LastEditors : 尚博信_王强 wangqiang03@sunboxsoft.com\n * @LastEditTime : 2025-11-13 14:30:00\n * @FilePath : /expo-gaode-map/src/ExpoGaodeMap.types.ts\n * @Description : 高德地图 Expo Module 主类型定义文件\n * \n * Copyright (c) 2025 by 尚博信_王强, All Rights Reserved. \n */\n\n// 导出所有类型定义\nexport * from './types';\n\n// 重新导出常用类型,方便直接从主模块导入\nexport type {\n // 通用类型\n LatLng,\n Point,\n CameraPosition,\n LatLngBounds,\n MapPoi,\n \n // 地图视图\n MapViewProps,\n CameraEvent,\n \n // 定位\n Coordinates,\n ReGeocode,\n LocationOptions,\n \n // 覆盖物\n MarkerProps,\n PolylineProps,\n PolygonProps,\n CircleProps,\n HeatMapProps,\n MultiPointProps,\n ClusterProps,\n} from './types';\n\nexport {\n MapType,\n LocationMode,\n LocationAccuracy,\n CoordinateType,\n} from './types';\n\n/**\n * Expo 模块事件类型\n */\nexport type ExpoGaodeMapModuleEvents = {\n /**\n * 定位更新事件\n */\n onLocationUpdate: (location: any) => void;\n \n /**\n * 定位错误事件\n */\n onLocationError: (error: { code: number; message: string }) => void;\n};\n\n/**\n * Expo 地图视图属性(用于主视图组件)\n */\nexport type { MapViewProps as ExpoGaodeMapViewProps } from './types';\n"]}
1
+ {"version":3,"file":"ExpoGaodeMap.types.js","sourceRoot":"","sources":["../src/ExpoGaodeMap.types.ts"],"names":[],"mappings":"AAEA,WAAW;AACX,cAAc,SAAS,CAAC;AA8BxB,OAAO,EACL,OAAO,EACP,YAAY,EACZ,gBAAgB,EAChB,cAAc,GACf,MAAM,SAAS,CAAC","sourcesContent":["\n\n// 导出所有类型定义\nexport * from './types';\n\n// 重新导出常用类型,方便直接从主模块导入\nexport type {\n // 通用类型\n LatLng,\n Point,\n CameraPosition,\n LatLngBounds,\n MapPoi,\n \n // 地图视图\n MapViewProps,\n CameraEvent,\n \n // 定位\n Coordinates,\n ReGeocode,\n LocationOptions,\n \n // 覆盖物\n MarkerProps,\n PolylineProps,\n PolygonProps,\n CircleProps,\n HeatMapProps,\n MultiPointProps,\n ClusterProps,\n} from './types';\n\nexport {\n MapType,\n LocationMode,\n LocationAccuracy,\n CoordinateType,\n} from './types';\n\n/**\n * Expo 模块事件类型\n */\nexport type ExpoGaodeMapModuleEvents = {\n /**\n * 定位更新事件\n */\n onLocationUpdate: (location: any) => void;\n \n /**\n * 定位错误事件\n */\n onLocationError: (error: { code: number; message: string }) => void;\n};\n\n/**\n * Expo 地图视图属性(用于主视图组件)\n */\nexport type { MapViewProps as ExpoGaodeMapViewProps } from './types';\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoGaodeMapModule.d.ts","sourceRoot":"","sources":["../src/ExpoGaodeMapModule.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,YAAY,EAAuB,MAAM,MAAM,CAAC;AACzD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAGrE,OAAO,OAAO,kBAAmB,SAAQ,YAAY,CAAC,wBAAwB,CAAC;CAG9E;;AAGD,wBAAuE"}
1
+ {"version":3,"file":"ExpoGaodeMapModule.d.ts","sourceRoot":"","sources":["../src/ExpoGaodeMapModule.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAuB,MAAM,MAAM,CAAC;AACzD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAGrE,OAAO,OAAO,kBAAmB,SAAQ,YAAY,CAAC,wBAAwB,CAAC;CAG9E;;AAGD,wBAAuE"}
@@ -1,13 +1,3 @@
1
- /*
2
- * @Author : 尚博信_王强 wangqiang03@sunboxsoft.com
3
- * @Date : 2025-11-13 14:03:56
4
- * @LastEditors : 尚博信_王强 wangqiang03@sunboxsoft.com
5
- * @LastEditTime : 2025-11-13 14:58:00
6
- * @FilePath : /expo-gaode-map/src/ExpoGaodeMapModule.ts
7
- * @Description :
8
- *
9
- * Copyright (c) 2025 by 尚博信_王强, All Rights Reserved.
10
- */
11
1
  import { requireNativeModule } from 'expo';
12
2
  // This call loads the native module object from the JSI.
13
3
  export default requireNativeModule('ExpoGaodeMap');
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoGaodeMapModule.js","sourceRoot":"","sources":["../src/ExpoGaodeMapModule.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAgB,mBAAmB,EAAE,MAAM,MAAM,CAAC;AASzD,yDAAyD;AACzD,eAAe,mBAAmB,CAAqB,cAAc,CAAC,CAAC","sourcesContent":["/*\n * @Author : 尚博信_王强 wangqiang03@sunboxsoft.com\n * @Date : 2025-11-13 14:03:56\n * @LastEditors : 尚博信_王强 wangqiang03@sunboxsoft.com\n * @LastEditTime : 2025-11-13 14:58:00\n * @FilePath : /expo-gaode-map/src/ExpoGaodeMapModule.ts\n * @Description : \n * \n * Copyright (c) 2025 by 尚博信_王强, All Rights Reserved. \n */\nimport { NativeModule, requireNativeModule } from 'expo';\nimport type { ExpoGaodeMapModuleEvents } from './ExpoGaodeMap.types';\n\n\ndeclare class ExpoGaodeMapModule extends NativeModule<ExpoGaodeMapModuleEvents> {\n // 地图控制方法已移至 MapView 的 ref 调用\n // 使用方式: mapRef.current.moveCamera() 等\n}\n\n// This call loads the native module object from the JSI.\nexport default requireNativeModule<ExpoGaodeMapModule>('ExpoGaodeMap');\n"]}
1
+ {"version":3,"file":"ExpoGaodeMapModule.js","sourceRoot":"","sources":["../src/ExpoGaodeMapModule.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,MAAM,CAAC;AASzD,yDAAyD;AACzD,eAAe,mBAAmB,CAAqB,cAAc,CAAC,CAAC","sourcesContent":["\nimport { NativeModule, requireNativeModule } from 'expo';\nimport type { ExpoGaodeMapModuleEvents } from './ExpoGaodeMap.types';\n\n\ndeclare class ExpoGaodeMapModule extends NativeModule<ExpoGaodeMapModuleEvents> {\n // 地图控制方法已移至 MapView 的 ref 调用\n // 使用方式: mapRef.current.moveCamera() 等\n}\n\n// This call loads the native module object from the JSI.\nexport default requireNativeModule<ExpoGaodeMapModule>('ExpoGaodeMap');\n"]}