expo-gaode-map 0.1.0
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/.eslintrc.js +5 -0
- package/PUBLISHING.md +244 -0
- package/README.md +990 -0
- package/android/build.gradle +48 -0
- package/android/src/main/AndroidManifest.xml +40 -0
- package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapModule.kt +455 -0
- package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapView.kt +337 -0
- package/android/src/main/java/expo/modules/gaodemap/managers/CameraManager.kt +128 -0
- package/android/src/main/java/expo/modules/gaodemap/managers/OverlayManager.kt +324 -0
- package/android/src/main/java/expo/modules/gaodemap/managers/UIManager.kt +122 -0
- package/android/src/main/java/expo/modules/gaodemap/modules/LocationManager.kt +247 -0
- package/android/src/main/java/expo/modules/gaodemap/modules/SDKInitializer.kt +45 -0
- package/android/src/main/java/expo/modules/gaodemap/overlays/CircleView.kt +151 -0
- package/android/src/main/java/expo/modules/gaodemap/overlays/ClusterView.kt +127 -0
- package/android/src/main/java/expo/modules/gaodemap/overlays/HeatMapView.kt +97 -0
- package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerView.kt +204 -0
- package/android/src/main/java/expo/modules/gaodemap/overlays/MultiPointView.kt +103 -0
- package/android/src/main/java/expo/modules/gaodemap/overlays/PolygonView.kt +114 -0
- package/android/src/main/java/expo/modules/gaodemap/overlays/PolylineView.kt +138 -0
- package/build/ExpoGaodeMap.types.d.ts +24 -0
- package/build/ExpoGaodeMap.types.d.ts.map +1 -0
- package/build/ExpoGaodeMap.types.js +14 -0
- package/build/ExpoGaodeMap.types.js.map +1 -0
- package/build/ExpoGaodeMapModule.d.ts +7 -0
- package/build/ExpoGaodeMapModule.d.ts.map +1 -0
- package/build/ExpoGaodeMapModule.js +14 -0
- package/build/ExpoGaodeMapModule.js.map +1 -0
- package/build/ExpoGaodeMapView.d.ts +31 -0
- package/build/ExpoGaodeMapView.d.ts.map +1 -0
- package/build/ExpoGaodeMapView.js +141 -0
- package/build/ExpoGaodeMapView.js.map +1 -0
- package/build/components/overlays/Circle.d.ts +18 -0
- package/build/components/overlays/Circle.d.ts.map +1 -0
- package/build/components/overlays/Circle.js +63 -0
- package/build/components/overlays/Circle.js.map +1 -0
- package/build/components/overlays/Cluster.d.ts +22 -0
- package/build/components/overlays/Cluster.d.ts.map +1 -0
- package/build/components/overlays/Cluster.js +35 -0
- package/build/components/overlays/Cluster.js.map +1 -0
- package/build/components/overlays/HeatMap.d.ts +21 -0
- package/build/components/overlays/HeatMap.d.ts.map +1 -0
- package/build/components/overlays/HeatMap.js +34 -0
- package/build/components/overlays/HeatMap.js.map +1 -0
- package/build/components/overlays/Marker.d.ts +17 -0
- package/build/components/overlays/Marker.d.ts.map +1 -0
- package/build/components/overlays/Marker.js +57 -0
- package/build/components/overlays/Marker.js.map +1 -0
- package/build/components/overlays/MultiPoint.d.ts +21 -0
- package/build/components/overlays/MultiPoint.d.ts.map +1 -0
- package/build/components/overlays/MultiPoint.js +34 -0
- package/build/components/overlays/MultiPoint.js.map +1 -0
- package/build/components/overlays/Polygon.d.ts +22 -0
- package/build/components/overlays/Polygon.d.ts.map +1 -0
- package/build/components/overlays/Polygon.js +100 -0
- package/build/components/overlays/Polygon.js.map +1 -0
- package/build/components/overlays/Polyline.d.ts +20 -0
- package/build/components/overlays/Polyline.d.ts.map +1 -0
- package/build/components/overlays/Polyline.js +60 -0
- package/build/components/overlays/Polyline.js.map +1 -0
- package/build/components/overlays/index.d.ts +8 -0
- package/build/components/overlays/index.d.ts.map +1 -0
- package/build/components/overlays/index.js +18 -0
- package/build/components/overlays/index.js.map +1 -0
- package/build/index.d.ts +10 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +28 -0
- package/build/index.js.map +1 -0
- package/build/modules/AMapLocation.d.ts +58 -0
- package/build/modules/AMapLocation.d.ts.map +1 -0
- package/build/modules/AMapLocation.js +141 -0
- package/build/modules/AMapLocation.js.map +1 -0
- package/build/modules/AMapSDK.d.ts +27 -0
- package/build/modules/AMapSDK.d.ts.map +1 -0
- package/build/modules/AMapSDK.js +43 -0
- package/build/modules/AMapSDK.js.map +1 -0
- package/build/modules/AMapView.d.ts +39 -0
- package/build/modules/AMapView.d.ts.map +1 -0
- package/build/modules/AMapView.js +61 -0
- package/build/modules/AMapView.js.map +1 -0
- package/build/types/common.types.d.ts +133 -0
- package/build/types/common.types.d.ts.map +1 -0
- package/build/types/common.types.js +31 -0
- package/build/types/common.types.js.map +1 -0
- package/build/types/index.d.ts +12 -0
- package/build/types/index.d.ts.map +1 -0
- package/build/types/index.js +17 -0
- package/build/types/index.js.map +1 -0
- package/build/types/location.types.d.ts +306 -0
- package/build/types/location.types.d.ts.map +1 -0
- package/build/types/location.types.js +93 -0
- package/build/types/location.types.js.map +1 -0
- package/build/types/map-view.types.d.ts +213 -0
- package/build/types/map-view.types.d.ts.map +1 -0
- package/build/types/map-view.types.js +6 -0
- package/build/types/map-view.types.js.map +1 -0
- package/build/types/overlays.types.d.ts +296 -0
- package/build/types/overlays.types.d.ts.map +1 -0
- package/build/types/overlays.types.js +6 -0
- package/build/types/overlays.types.js.map +1 -0
- package/build/types/sdk.types.d.ts +113 -0
- package/build/types/sdk.types.d.ts.map +1 -0
- package/build/types/sdk.types.js +6 -0
- package/build/types/sdk.types.js.map +1 -0
- package/docs/followUserLocation.md +186 -0
- package/expo-module.config.json +9 -0
- package/ios/ExpoGaodeMap.podspec +29 -0
- package/ios/ExpoGaodeMapModule.swift +48 -0
- package/ios/ExpoGaodeMapView.swift +38 -0
- package/package.json +45 -0
- package/src/ExpoGaodeMap.types.ts +68 -0
- package/src/ExpoGaodeMapModule.ts +21 -0
- package/src/ExpoGaodeMapView.tsx +151 -0
- package/src/components/overlays/Circle.tsx +73 -0
- package/src/components/overlays/Cluster.tsx +38 -0
- package/src/components/overlays/HeatMap.tsx +37 -0
- package/src/components/overlays/Marker.tsx +66 -0
- package/src/components/overlays/MultiPoint.tsx +37 -0
- package/src/components/overlays/Polygon.tsx +107 -0
- package/src/components/overlays/Polyline.tsx +69 -0
- package/src/components/overlays/index.ts +18 -0
- package/src/index.ts +55 -0
- package/src/modules/AMapLocation.ts +164 -0
- package/src/modules/AMapSDK.ts +48 -0
- package/src/modules/AMapView.ts +68 -0
- package/src/types/README.md +186 -0
- package/src/types/common.types.ts +155 -0
- package/src/types/index.ts +74 -0
- package/src/types/location.types.ts +364 -0
- package/src/types/map-view.types.ts +249 -0
- package/src/types/overlays.types.ts +346 -0
- package/src/types/sdk.types.ts +128 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
package expo.modules.gaodemap.managers
|
|
2
|
+
|
|
3
|
+
import android.util.Log
|
|
4
|
+
import com.amap.api.maps.AMap
|
|
5
|
+
import com.amap.api.maps.model.LatLng
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 覆盖物管理器
|
|
9
|
+
* 负责地图上所有覆盖物的添加、删除、更新
|
|
10
|
+
*/
|
|
11
|
+
class OverlayManager(private val aMap: AMap) {
|
|
12
|
+
|
|
13
|
+
companion object {
|
|
14
|
+
private const val TAG = "OverlayManager"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// 覆盖物存储
|
|
18
|
+
private val circles = mutableMapOf<String, com.amap.api.maps.model.Circle>()
|
|
19
|
+
private val markers = mutableMapOf<String, com.amap.api.maps.model.Marker>()
|
|
20
|
+
private val polylines = mutableMapOf<String, com.amap.api.maps.model.Polyline>()
|
|
21
|
+
private val polygons = mutableMapOf<String, com.amap.api.maps.model.Polygon>()
|
|
22
|
+
|
|
23
|
+
// ==================== 圆形覆盖物 ====================
|
|
24
|
+
|
|
25
|
+
fun addCircle(id: String, props: Map<String, Any>) {
|
|
26
|
+
Log.d(TAG, "🔵 addCircle: id=$id")
|
|
27
|
+
|
|
28
|
+
@Suppress("UNCHECKED_CAST")
|
|
29
|
+
val center = props["center"] as? Map<String, Double>
|
|
30
|
+
val radius = (props["radius"] as? Number)?.toDouble() ?: 1000.0
|
|
31
|
+
val fillColor = (props["fillColor"] as? Number)?.toInt() ?: android.graphics.Color.argb(50, 0, 0, 255)
|
|
32
|
+
val strokeColor = (props["strokeColor"] as? Number)?.toInt() ?: android.graphics.Color.BLUE
|
|
33
|
+
val strokeWidth = (props["strokeWidth"] as? Number)?.toFloat() ?: 10f
|
|
34
|
+
|
|
35
|
+
if (center != null) {
|
|
36
|
+
val lat = center["latitude"] ?: 0.0
|
|
37
|
+
val lng = center["longitude"] ?: 0.0
|
|
38
|
+
val latLng = LatLng(lat, lng)
|
|
39
|
+
|
|
40
|
+
val options = com.amap.api.maps.model.CircleOptions()
|
|
41
|
+
.center(latLng)
|
|
42
|
+
.radius(radius)
|
|
43
|
+
.fillColor(fillColor)
|
|
44
|
+
.strokeColor(strokeColor)
|
|
45
|
+
.strokeWidth(strokeWidth)
|
|
46
|
+
|
|
47
|
+
val circle = aMap.addCircle(options)
|
|
48
|
+
circles[id] = circle
|
|
49
|
+
Log.d(TAG, "✅ 圆形创建成功")
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
fun removeCircle(id: String) {
|
|
54
|
+
circles[id]?.let { circle ->
|
|
55
|
+
circle.remove()
|
|
56
|
+
circles.remove(id)
|
|
57
|
+
Log.d(TAG, "✅ 圆形已移除: $id")
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
fun updateCircle(id: String, props: Map<String, Any>) {
|
|
62
|
+
circles[id]?.let { circle ->
|
|
63
|
+
@Suppress("UNCHECKED_CAST")
|
|
64
|
+
val center = props["center"] as? Map<String, Double>
|
|
65
|
+
val radius = (props["radius"] as? Number)?.toDouble()
|
|
66
|
+
val fillColor = (props["fillColor"] as? Number)?.toInt()
|
|
67
|
+
val strokeColor = (props["strokeColor"] as? Number)?.toInt()
|
|
68
|
+
val strokeWidth = (props["strokeWidth"] as? Number)?.toFloat()
|
|
69
|
+
|
|
70
|
+
center?.let {
|
|
71
|
+
val lat = it["latitude"] ?: 0.0
|
|
72
|
+
val lng = it["longitude"] ?: 0.0
|
|
73
|
+
circle.center = LatLng(lat, lng)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
radius?.let { circle.radius = it }
|
|
77
|
+
fillColor?.let { circle.fillColor = it }
|
|
78
|
+
strokeColor?.let { circle.strokeColor = it }
|
|
79
|
+
strokeWidth?.let { circle.strokeWidth = it }
|
|
80
|
+
|
|
81
|
+
Log.d(TAG, "✅ 圆形已更新: $id")
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ==================== 标记点 ====================
|
|
86
|
+
|
|
87
|
+
fun addMarker(id: String, props: Map<String, Any>) {
|
|
88
|
+
Log.d(TAG, "📍 addMarker: id=$id")
|
|
89
|
+
|
|
90
|
+
@Suppress("UNCHECKED_CAST")
|
|
91
|
+
val position = props["position"] as? Map<String, Double>
|
|
92
|
+
val title = props["title"] as? String
|
|
93
|
+
val draggable = props["draggable"] as? Boolean ?: false
|
|
94
|
+
|
|
95
|
+
if (position != null) {
|
|
96
|
+
val lat = position["latitude"] ?: 0.0
|
|
97
|
+
val lng = position["longitude"] ?: 0.0
|
|
98
|
+
val latLng = LatLng(lat, lng)
|
|
99
|
+
|
|
100
|
+
val options = com.amap.api.maps.model.MarkerOptions()
|
|
101
|
+
.position(latLng)
|
|
102
|
+
.draggable(draggable)
|
|
103
|
+
|
|
104
|
+
title?.let { options.title(it) }
|
|
105
|
+
|
|
106
|
+
val marker = aMap.addMarker(options)
|
|
107
|
+
|
|
108
|
+
if (!title.isNullOrEmpty()) {
|
|
109
|
+
marker?.showInfoWindow()
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
markers[id] = marker
|
|
113
|
+
Log.d(TAG, "✅ 标记点创建成功")
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
fun removeMarker(id: String) {
|
|
118
|
+
markers[id]?.let { marker ->
|
|
119
|
+
marker.remove()
|
|
120
|
+
markers.remove(id)
|
|
121
|
+
Log.d(TAG, "✅ 标记点已移除: $id")
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
fun updateMarker(id: String, props: Map<String, Any>) {
|
|
126
|
+
markers[id]?.let { marker ->
|
|
127
|
+
@Suppress("UNCHECKED_CAST")
|
|
128
|
+
val position = props["position"] as? Map<String, Double>
|
|
129
|
+
val title = props["title"] as? String
|
|
130
|
+
val draggable = props["draggable"] as? Boolean
|
|
131
|
+
|
|
132
|
+
position?.let {
|
|
133
|
+
val lat = it["latitude"] ?: 0.0
|
|
134
|
+
val lng = it["longitude"] ?: 0.0
|
|
135
|
+
marker.position = LatLng(lat, lng)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
title?.let { marker.title = it }
|
|
139
|
+
draggable?.let { marker.isDraggable = it }
|
|
140
|
+
|
|
141
|
+
Log.d(TAG, "✅ 标记点已更新: $id")
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// ==================== 折线 ====================
|
|
146
|
+
|
|
147
|
+
fun addPolyline(id: String, props: Map<String, Any>) {
|
|
148
|
+
Log.d(TAG, "📏 addPolyline: id=$id")
|
|
149
|
+
|
|
150
|
+
@Suppress("UNCHECKED_CAST")
|
|
151
|
+
val points = props["points"] as? List<Map<String, Double>>
|
|
152
|
+
val width = (props["width"] as? Number)?.toFloat() ?: 10f
|
|
153
|
+
|
|
154
|
+
val colorValue = props["color"]
|
|
155
|
+
val color = when (colorValue) {
|
|
156
|
+
is Long -> colorValue.toInt()
|
|
157
|
+
is Int -> colorValue
|
|
158
|
+
is Double -> colorValue.toInt()
|
|
159
|
+
else -> android.graphics.Color.RED
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (points != null && points.isNotEmpty()) {
|
|
163
|
+
val latLngs = points.map { point ->
|
|
164
|
+
val lat = point["latitude"] ?: 0.0
|
|
165
|
+
val lng = point["longitude"] ?: 0.0
|
|
166
|
+
LatLng(lat, lng)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
val options = com.amap.api.maps.model.PolylineOptions()
|
|
170
|
+
.addAll(latLngs)
|
|
171
|
+
.width(width)
|
|
172
|
+
.color(color)
|
|
173
|
+
|
|
174
|
+
val polyline = aMap.addPolyline(options)
|
|
175
|
+
polylines[id] = polyline
|
|
176
|
+
Log.d(TAG, "✅ 折线创建成功")
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
fun removePolyline(id: String) {
|
|
181
|
+
polylines[id]?.let { polyline ->
|
|
182
|
+
polyline.remove()
|
|
183
|
+
polylines.remove(id)
|
|
184
|
+
Log.d(TAG, "✅ 折线已移除: $id")
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
fun updatePolyline(id: String, props: Map<String, Any>) {
|
|
189
|
+
polylines[id]?.let { polyline ->
|
|
190
|
+
@Suppress("UNCHECKED_CAST")
|
|
191
|
+
val points = props["points"] as? List<Map<String, Double>>
|
|
192
|
+
val width = (props["width"] as? Number)?.toFloat()
|
|
193
|
+
val color = (props["color"] as? Number)?.toInt()
|
|
194
|
+
|
|
195
|
+
points?.let {
|
|
196
|
+
val latLngs = it.map { point ->
|
|
197
|
+
val lat = point["latitude"] ?: 0.0
|
|
198
|
+
val lng = point["longitude"] ?: 0.0
|
|
199
|
+
LatLng(lat, lng)
|
|
200
|
+
}
|
|
201
|
+
polyline.points = latLngs
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
width?.let { polyline.width = it }
|
|
205
|
+
color?.let { polyline.color = it }
|
|
206
|
+
|
|
207
|
+
Log.d(TAG, "✅ 折线已更新: $id")
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// ==================== 多边形 ====================
|
|
212
|
+
|
|
213
|
+
fun addPolygon(id: String, props: Map<String, Any>) {
|
|
214
|
+
Log.d(TAG, "🔷 addPolygon: id=$id")
|
|
215
|
+
|
|
216
|
+
@Suppress("UNCHECKED_CAST")
|
|
217
|
+
val points = props["points"] as? List<Map<String, Double>>
|
|
218
|
+
|
|
219
|
+
val fillColorValue = props["fillColor"]
|
|
220
|
+
val fillColor = when (fillColorValue) {
|
|
221
|
+
is Long -> fillColorValue.toInt()
|
|
222
|
+
is Int -> fillColorValue
|
|
223
|
+
is Double -> fillColorValue.toInt()
|
|
224
|
+
else -> android.graphics.Color.argb(50, 0, 0, 255)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
val strokeColorValue = props["strokeColor"]
|
|
228
|
+
val strokeColor = when (strokeColorValue) {
|
|
229
|
+
is Long -> strokeColorValue.toInt()
|
|
230
|
+
is Int -> strokeColorValue
|
|
231
|
+
is Double -> strokeColorValue.toInt()
|
|
232
|
+
else -> android.graphics.Color.BLUE
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
val strokeWidth = (props["strokeWidth"] as? Number)?.toFloat() ?: 10f
|
|
236
|
+
val zIndex = (props["zIndex"] as? Number)?.toFloat() ?: 0f
|
|
237
|
+
|
|
238
|
+
if (points != null && points.size >= 3) {
|
|
239
|
+
val latLngs = points.map { point ->
|
|
240
|
+
val lat = point["latitude"] ?: 0.0
|
|
241
|
+
val lng = point["longitude"] ?: 0.0
|
|
242
|
+
LatLng(lat, lng)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
val options = com.amap.api.maps.model.PolygonOptions()
|
|
246
|
+
.addAll(latLngs)
|
|
247
|
+
.fillColor(fillColor)
|
|
248
|
+
.strokeColor(strokeColor)
|
|
249
|
+
.strokeWidth(strokeWidth)
|
|
250
|
+
.zIndex(zIndex)
|
|
251
|
+
|
|
252
|
+
val polygon = aMap.addPolygon(options)
|
|
253
|
+
polygons[id] = polygon
|
|
254
|
+
Log.d(TAG, "✅ 多边形创建成功")
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
fun removePolygon(id: String) {
|
|
259
|
+
polygons[id]?.let { polygon ->
|
|
260
|
+
polygon.remove()
|
|
261
|
+
polygons.remove(id)
|
|
262
|
+
Log.d(TAG, "✅ 多边形已移除: $id")
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
fun updatePolygon(id: String, props: Map<String, Any>) {
|
|
267
|
+
polygons[id]?.let { polygon ->
|
|
268
|
+
@Suppress("UNCHECKED_CAST")
|
|
269
|
+
val points = props["points"] as? List<Map<String, Double>>
|
|
270
|
+
|
|
271
|
+
val fillColorValue = props["fillColor"]
|
|
272
|
+
val fillColor = when (fillColorValue) {
|
|
273
|
+
is Long -> fillColorValue.toInt()
|
|
274
|
+
is Int -> fillColorValue
|
|
275
|
+
is Double -> fillColorValue.toInt()
|
|
276
|
+
else -> null
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
val strokeColorValue = props["strokeColor"]
|
|
280
|
+
val strokeColor = when (strokeColorValue) {
|
|
281
|
+
is Long -> strokeColorValue.toInt()
|
|
282
|
+
is Int -> strokeColorValue
|
|
283
|
+
is Double -> strokeColorValue.toInt()
|
|
284
|
+
else -> null
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
val strokeWidth = (props["strokeWidth"] as? Number)?.toFloat()
|
|
288
|
+
val zIndex = (props["zIndex"] as? Number)?.toFloat()
|
|
289
|
+
|
|
290
|
+
points?.let {
|
|
291
|
+
val latLngs = it.map { point ->
|
|
292
|
+
val lat = point["latitude"] ?: 0.0
|
|
293
|
+
val lng = point["longitude"] ?: 0.0
|
|
294
|
+
LatLng(lat, lng)
|
|
295
|
+
}
|
|
296
|
+
polygon.points = latLngs
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
fillColor?.let { polygon.fillColor = it }
|
|
300
|
+
strokeColor?.let { polygon.strokeColor = it }
|
|
301
|
+
strokeWidth?.let { polygon.strokeWidth = it }
|
|
302
|
+
zIndex?.let { polygon.zIndex = it }
|
|
303
|
+
|
|
304
|
+
Log.d(TAG, "✅ 多边形已更新: $id")
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* 清理所有覆盖物
|
|
310
|
+
*/
|
|
311
|
+
fun clear() {
|
|
312
|
+
circles.values.forEach { it.remove() }
|
|
313
|
+
circles.clear()
|
|
314
|
+
|
|
315
|
+
markers.values.forEach { it.remove() }
|
|
316
|
+
markers.clear()
|
|
317
|
+
|
|
318
|
+
polylines.values.forEach { it.remove() }
|
|
319
|
+
polylines.clear()
|
|
320
|
+
|
|
321
|
+
polygons.values.forEach { it.remove() }
|
|
322
|
+
polygons.clear()
|
|
323
|
+
}
|
|
324
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
package expo.modules.gaodemap.managers
|
|
2
|
+
|
|
3
|
+
import com.amap.api.maps.AMap
|
|
4
|
+
import com.amap.api.maps.model.MyLocationStyle
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* UI 和手势管理器
|
|
8
|
+
* 负责地图控件显示、手势控制、图层显示等
|
|
9
|
+
*/
|
|
10
|
+
class UIManager(private val aMap: AMap) {
|
|
11
|
+
|
|
12
|
+
// ==================== 控件显示 ====================
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 设置是否显示缩放控件
|
|
16
|
+
*/
|
|
17
|
+
fun setShowsZoomControls(show: Boolean) {
|
|
18
|
+
aMap.uiSettings.isZoomControlsEnabled = show
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 设置是否显示指南针
|
|
23
|
+
*/
|
|
24
|
+
fun setShowsCompass(show: Boolean) {
|
|
25
|
+
aMap.uiSettings.isCompassEnabled = show
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 设置是否显示比例尺
|
|
30
|
+
*/
|
|
31
|
+
fun setShowsScale(show: Boolean) {
|
|
32
|
+
aMap.uiSettings.isScaleControlsEnabled = show
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ==================== 手势控制 ====================
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 设置是否启用缩放手势
|
|
39
|
+
*/
|
|
40
|
+
fun setZoomEnabled(enabled: Boolean) {
|
|
41
|
+
aMap.uiSettings.isZoomGesturesEnabled = enabled
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 设置是否启用滚动手势
|
|
46
|
+
*/
|
|
47
|
+
fun setScrollEnabled(enabled: Boolean) {
|
|
48
|
+
aMap.uiSettings.isScrollGesturesEnabled = enabled
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 设置是否启用旋转手势
|
|
53
|
+
*/
|
|
54
|
+
fun setRotateEnabled(enabled: Boolean) {
|
|
55
|
+
aMap.uiSettings.isRotateGesturesEnabled = enabled
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 设置是否启用倾斜手势
|
|
60
|
+
*/
|
|
61
|
+
fun setTiltEnabled(enabled: Boolean) {
|
|
62
|
+
aMap.uiSettings.isTiltGesturesEnabled = enabled
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ==================== 图层显示 ====================
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 设置是否显示用户位置
|
|
69
|
+
* @param show 是否显示
|
|
70
|
+
* @param followUserLocation 是否跟随用户位置(默认 false,只显示不移动地图)
|
|
71
|
+
*/
|
|
72
|
+
fun setShowsUserLocation(show: Boolean, followUserLocation: Boolean = false) {
|
|
73
|
+
if (show) {
|
|
74
|
+
val myLocationStyle = MyLocationStyle()
|
|
75
|
+
// 根据参数选择定位类型
|
|
76
|
+
val locationType = if (followUserLocation) {
|
|
77
|
+
MyLocationStyle.LOCATION_TYPE_FOLLOW // 跟随用户位置
|
|
78
|
+
} else {
|
|
79
|
+
MyLocationStyle.LOCATION_TYPE_SHOW // 只显示,不移动地图
|
|
80
|
+
}
|
|
81
|
+
myLocationStyle.myLocationType(locationType)
|
|
82
|
+
aMap.myLocationStyle = myLocationStyle
|
|
83
|
+
aMap.isMyLocationEnabled = true
|
|
84
|
+
} else {
|
|
85
|
+
aMap.isMyLocationEnabled = false
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* 设置是否显示交通路况
|
|
91
|
+
*/
|
|
92
|
+
fun setShowsTraffic(show: Boolean) {
|
|
93
|
+
aMap.isTrafficEnabled = show
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* 设置是否显示建筑物
|
|
98
|
+
*/
|
|
99
|
+
fun setShowsBuildings(show: Boolean) {
|
|
100
|
+
aMap.showBuildings(show)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* 设置是否显示室内地图
|
|
105
|
+
*/
|
|
106
|
+
fun setShowsIndoorMap(show: Boolean) {
|
|
107
|
+
aMap.showIndoorMap(show)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* 设置地图类型
|
|
112
|
+
*/
|
|
113
|
+
fun setMapType(type: Int) {
|
|
114
|
+
aMap.mapType = when (type) {
|
|
115
|
+
1 -> AMap.MAP_TYPE_SATELLITE // 卫星地图
|
|
116
|
+
2 -> AMap.MAP_TYPE_NIGHT // 夜间地图
|
|
117
|
+
3 -> AMap.MAP_TYPE_NAVI // 导航地图
|
|
118
|
+
4 -> AMap.MAP_TYPE_BUS // 公交地图
|
|
119
|
+
else -> AMap.MAP_TYPE_NORMAL // 标准地图
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
package expo.modules.gaodemap.modules
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.util.Log
|
|
5
|
+
import com.amap.api.location.AMapLocation
|
|
6
|
+
import com.amap.api.location.AMapLocationClient
|
|
7
|
+
import com.amap.api.location.AMapLocationClientOption
|
|
8
|
+
import com.amap.api.maps.model.LatLng
|
|
9
|
+
import expo.modules.kotlin.Promise
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 定位管理器
|
|
13
|
+
*/
|
|
14
|
+
class LocationManager(private val context: Context) {
|
|
15
|
+
companion object {
|
|
16
|
+
private const val TAG = "LocationManager"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
private var locationClient: AMapLocationClient? = null
|
|
20
|
+
private var locationOption: AMapLocationClientOption? = null
|
|
21
|
+
private var isLocationStarted = false
|
|
22
|
+
private var onLocationUpdate: ((Map<String, Any?>) -> Unit)? = null
|
|
23
|
+
|
|
24
|
+
init {
|
|
25
|
+
initLocationClient()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 设置定位更新回调
|
|
30
|
+
*/
|
|
31
|
+
fun setOnLocationUpdate(callback: (Map<String, Any?>) -> Unit) {
|
|
32
|
+
onLocationUpdate = callback
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 开始连续定位
|
|
37
|
+
*/
|
|
38
|
+
fun start() {
|
|
39
|
+
if (locationClient == null) {
|
|
40
|
+
initLocationClient()
|
|
41
|
+
}
|
|
42
|
+
locationClient?.startLocation()
|
|
43
|
+
isLocationStarted = true
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 停止定位
|
|
48
|
+
*/
|
|
49
|
+
fun stop() {
|
|
50
|
+
locationClient?.stopLocation()
|
|
51
|
+
isLocationStarted = false
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* 是否正在定位
|
|
56
|
+
*/
|
|
57
|
+
fun isStarted(): Boolean = isLocationStarted
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 获取当前位置(单次定位)
|
|
61
|
+
*/
|
|
62
|
+
fun getCurrentLocation(promise: Promise) {
|
|
63
|
+
val onceOption = AMapLocationClientOption().apply {
|
|
64
|
+
isOnceLocation = true
|
|
65
|
+
locationOption?.let { opt ->
|
|
66
|
+
locationMode = opt.locationMode
|
|
67
|
+
isNeedAddress = opt.isNeedAddress
|
|
68
|
+
httpTimeOut = opt.httpTimeOut
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
val tempClient = AMapLocationClient(context)
|
|
73
|
+
tempClient.setLocationOption(onceOption)
|
|
74
|
+
tempClient.setLocationListener { location ->
|
|
75
|
+
if (location != null && location.errorCode == 0) {
|
|
76
|
+
promise.resolve(formatLocation(location))
|
|
77
|
+
} else {
|
|
78
|
+
promise.reject("LOCATION_ERROR", location?.errorInfo ?: "定位失败", null)
|
|
79
|
+
}
|
|
80
|
+
tempClient.stopLocation()
|
|
81
|
+
tempClient.onDestroy()
|
|
82
|
+
}
|
|
83
|
+
tempClient.startLocation()
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* 坐标转换
|
|
88
|
+
*/
|
|
89
|
+
fun coordinateConvert(
|
|
90
|
+
coordinate: Map<String, Double>,
|
|
91
|
+
type: Int,
|
|
92
|
+
promise: Promise
|
|
93
|
+
) {
|
|
94
|
+
val lat = coordinate["latitude"] ?: 0.0
|
|
95
|
+
val lng = coordinate["longitude"] ?: 0.0
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
val sourceLatLng = LatLng(lat, lng)
|
|
99
|
+
// 高德 SDK 会自动处理坐标转换
|
|
100
|
+
promise.resolve(
|
|
101
|
+
mapOf(
|
|
102
|
+
"latitude" to sourceLatLng.latitude,
|
|
103
|
+
"longitude" to sourceLatLng.longitude
|
|
104
|
+
)
|
|
105
|
+
)
|
|
106
|
+
} catch (e: Exception) {
|
|
107
|
+
promise.reject("CONVERT_ERROR", "坐标转换失败: ${e.message}", e)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ==================== 配置方法 ====================
|
|
112
|
+
|
|
113
|
+
fun setLocatingWithReGeocode(isReGeocode: Boolean) {
|
|
114
|
+
getOrCreateLocationOption().isNeedAddress = isReGeocode
|
|
115
|
+
applyLocationOption()
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
fun setLocationMode(mode: Int) {
|
|
119
|
+
val locationMode = when (mode) {
|
|
120
|
+
1 -> AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
|
|
121
|
+
2 -> AMapLocationClientOption.AMapLocationMode.Battery_Saving
|
|
122
|
+
3 -> AMapLocationClientOption.AMapLocationMode.Device_Sensors
|
|
123
|
+
else -> AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
|
|
124
|
+
}
|
|
125
|
+
getOrCreateLocationOption().locationMode = locationMode
|
|
126
|
+
applyLocationOption()
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
fun setInterval(interval: Int) {
|
|
130
|
+
getOrCreateLocationOption().interval = interval.toLong()
|
|
131
|
+
applyLocationOption()
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
fun setOnceLocation(isOnceLocation: Boolean) {
|
|
135
|
+
getOrCreateLocationOption().isOnceLocation = isOnceLocation
|
|
136
|
+
applyLocationOption()
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
fun setSensorEnable(sensorEnable: Boolean) {
|
|
140
|
+
getOrCreateLocationOption().isSensorEnable = sensorEnable
|
|
141
|
+
applyLocationOption()
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
fun setWifiScan(wifiScan: Boolean) {
|
|
145
|
+
getOrCreateLocationOption().isWifiScan = wifiScan
|
|
146
|
+
applyLocationOption()
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
fun setGpsFirst(gpsFirst: Boolean) {
|
|
150
|
+
getOrCreateLocationOption().isGpsFirst = gpsFirst
|
|
151
|
+
applyLocationOption()
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
fun setOnceLocationLatest(onceLocationLatest: Boolean) {
|
|
155
|
+
getOrCreateLocationOption().isOnceLocationLatest = onceLocationLatest
|
|
156
|
+
applyLocationOption()
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
fun setGeoLanguage(language: String) {
|
|
160
|
+
val geoLanguage = when (language) {
|
|
161
|
+
"EN" -> AMapLocationClientOption.GeoLanguage.EN
|
|
162
|
+
"ZH" -> AMapLocationClientOption.GeoLanguage.ZH
|
|
163
|
+
else -> AMapLocationClientOption.GeoLanguage.DEFAULT
|
|
164
|
+
}
|
|
165
|
+
getOrCreateLocationOption().geoLanguage = geoLanguage
|
|
166
|
+
applyLocationOption()
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
fun setLocationCacheEnable(locationCacheEnable: Boolean) {
|
|
170
|
+
getOrCreateLocationOption().isLocationCacheEnable = locationCacheEnable
|
|
171
|
+
applyLocationOption()
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
fun setHttpTimeOut(httpTimeOut: Int) {
|
|
175
|
+
getOrCreateLocationOption().httpTimeOut = httpTimeOut.toLong()
|
|
176
|
+
applyLocationOption()
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* 销毁资源
|
|
181
|
+
*/
|
|
182
|
+
fun destroy() {
|
|
183
|
+
locationClient?.stopLocation()
|
|
184
|
+
locationClient?.onDestroy()
|
|
185
|
+
locationClient = null
|
|
186
|
+
locationOption = null
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// ==================== 私有方法 ====================
|
|
190
|
+
|
|
191
|
+
private fun initLocationClient() {
|
|
192
|
+
if (locationClient == null) {
|
|
193
|
+
locationClient = AMapLocationClient(context).apply {
|
|
194
|
+
setLocationListener { location ->
|
|
195
|
+
if (location != null && location.errorCode == 0) {
|
|
196
|
+
onLocationUpdate?.invoke(formatLocation(location))
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
locationOption = AMapLocationClientOption().apply {
|
|
202
|
+
locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
|
|
203
|
+
isNeedAddress = true
|
|
204
|
+
interval = 2000
|
|
205
|
+
httpTimeOut = 30000
|
|
206
|
+
}
|
|
207
|
+
locationClient?.setLocationOption(locationOption)
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
private fun getOrCreateLocationOption(): AMapLocationClientOption {
|
|
212
|
+
if (locationOption == null) {
|
|
213
|
+
locationOption = AMapLocationClientOption()
|
|
214
|
+
}
|
|
215
|
+
return locationOption!!
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
private fun applyLocationOption() {
|
|
219
|
+
locationClient?.setLocationOption(locationOption)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
private fun formatLocation(location: AMapLocation): Map<String, Any?> {
|
|
223
|
+
return mapOf(
|
|
224
|
+
"latitude" to location.latitude,
|
|
225
|
+
"longitude" to location.longitude,
|
|
226
|
+
"altitude" to location.altitude,
|
|
227
|
+
"accuracy" to location.accuracy,
|
|
228
|
+
"heading" to location.bearing,
|
|
229
|
+
"speed" to location.speed,
|
|
230
|
+
"timestamp" to location.time,
|
|
231
|
+
"address" to location.address,
|
|
232
|
+
"country" to location.country,
|
|
233
|
+
"province" to location.province,
|
|
234
|
+
"city" to location.city,
|
|
235
|
+
"district" to location.district,
|
|
236
|
+
"cityCode" to location.cityCode,
|
|
237
|
+
"adCode" to location.adCode,
|
|
238
|
+
"street" to location.street,
|
|
239
|
+
"streetNumber" to location.streetNum,
|
|
240
|
+
"poiName" to location.poiName,
|
|
241
|
+
"aoiName" to location.aoiName,
|
|
242
|
+
"description" to location.locationDetail,
|
|
243
|
+
"coordType" to location.coordType,
|
|
244
|
+
"buildingId" to location.buildingId
|
|
245
|
+
)
|
|
246
|
+
}
|
|
247
|
+
}
|