expo-gaode-map-navigation 2.0.5 → 2.0.6
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/README.md +52 -1
- package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapView.kt +182 -86
- package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapViewModule.kt +5 -2
- package/android/src/main/java/expo/modules/gaodemap/map/managers/UIManager.kt +19 -5
- package/android/src/main/java/expo/modules/gaodemap/map/overlays/MarkerView.kt +319 -48
- package/android/src/main/java/expo/modules/gaodemap/map/overlays/MarkerViewModule.kt +3 -3
- package/build/index.d.ts +8 -4
- package/build/index.d.ts.map +1 -1
- package/build/index.js +79 -1
- package/build/index.js.map +1 -1
- package/build/map/ExpoGaodeMapModule.d.ts +4 -4
- package/build/map/ExpoGaodeMapModule.d.ts.map +1 -1
- package/build/map/ExpoGaodeMapModule.js +10 -8
- package/build/map/ExpoGaodeMapModule.js.map +1 -1
- package/build/map/ExpoGaodeMapView.d.ts.map +1 -1
- package/build/map/ExpoGaodeMapView.js +79 -17
- package/build/map/ExpoGaodeMapView.js.map +1 -1
- package/build/map/components/overlays/Cluster.d.ts.map +1 -1
- package/build/map/components/overlays/Cluster.js +12 -0
- package/build/map/components/overlays/Cluster.js.map +1 -1
- package/build/map/components/overlays/Marker.d.ts.map +1 -1
- package/build/map/components/overlays/Marker.js +70 -6
- package/build/map/components/overlays/Marker.js.map +1 -1
- package/build/map/types/common.types.d.ts +29 -5
- package/build/map/types/common.types.d.ts.map +1 -1
- package/build/map/types/common.types.js +5 -5
- package/build/map/types/common.types.js.map +1 -1
- package/build/map/types/index.d.ts +2 -1
- package/build/map/types/index.d.ts.map +1 -1
- package/build/map/types/index.js.map +1 -1
- package/build/map/types/location.types.d.ts +23 -0
- package/build/map/types/location.types.d.ts.map +1 -1
- package/build/map/types/location.types.js.map +1 -1
- package/build/map/types/map-view.types.d.ts +20 -22
- package/build/map/types/map-view.types.d.ts.map +1 -1
- package/build/map/types/map-view.types.js.map +1 -1
- package/build/map/types/overlays.types.d.ts +9 -2
- package/build/map/types/overlays.types.d.ts.map +1 -1
- package/build/map/types/overlays.types.js.map +1 -1
- package/build/map/types/route-playback.types.d.ts +12 -0
- package/build/map/types/route-playback.types.d.ts.map +1 -0
- package/build/map/types/route-playback.types.js +2 -0
- package/build/map/types/route-playback.types.js.map +1 -0
- package/build/types/route.types.d.ts +10 -1
- package/build/types/route.types.d.ts.map +1 -1
- package/build/types/route.types.js +2 -0
- package/build/types/route.types.js.map +1 -1
- package/ios/map/ExpoGaodeMapView.swift +151 -76
- package/ios/map/ExpoGaodeMapViewModule.swift +14 -1
- package/ios/map/managers/UIManager.swift +5 -4
- package/ios/map/overlays/ClusterView.swift +207 -147
- package/ios/map/overlays/ClusterViewModule.swift +5 -1
- package/ios/map/overlays/MarkerView.swift +214 -60
- package/ios/map/overlays/MarkerViewModule.swift +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
- 🧭 **实时导航 UI**:提供 `NaviView` 组件,内置完整的导航界面、语音播报、转向指引、路况显示等。
|
|
10
10
|
- 🛣️ **独立路径规划**:支持“先算路、再导航”的高级模式,可实现多路线对比与选择。
|
|
11
11
|
- ⚙️ **策略丰富**:支持速度优先、避让拥堵、少收费、不走高速等多种算路策略。
|
|
12
|
-
-
|
|
12
|
+
- ✅ **开箱即用**:封装了 Android/iOS 原生导航 SDK,统一 JS 接口。
|
|
13
13
|
|
|
14
14
|
## 安装
|
|
15
15
|
|
|
@@ -247,6 +247,57 @@ import { MapView, Circle, Polygon } from 'expo-gaode-map-navigation';
|
|
|
247
247
|
</MapView>
|
|
248
248
|
```
|
|
249
249
|
|
|
250
|
+
### 视口控制
|
|
251
|
+
|
|
252
|
+
导航包的 `MapViewRef` 同样支持:
|
|
253
|
+
|
|
254
|
+
- `moveCamera(position, duration?)`
|
|
255
|
+
- `getCameraPosition()`
|
|
256
|
+
- `fitToCoordinates(points, options?)`
|
|
257
|
+
|
|
258
|
+
```tsx
|
|
259
|
+
await mapRef.current?.fitToCoordinates(routePoints, {
|
|
260
|
+
duration: 500,
|
|
261
|
+
paddingFactor: 0.2,
|
|
262
|
+
maxZoom: 18,
|
|
263
|
+
});
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
注意:
|
|
267
|
+
|
|
268
|
+
- 这里的用户层 API 形状尽量和 `expo-gaode-map` 保持一致
|
|
269
|
+
- 但底层地图实现仍然绑定导航 SDK,不与 `core` 共用同一套 MapView 实现
|
|
270
|
+
|
|
271
|
+
### 公交算路 fallback(回退)
|
|
272
|
+
|
|
273
|
+
`calculateTransitRoute` 会在运行时回退到 `expo-gaode-map-web-api`:
|
|
274
|
+
|
|
275
|
+
```ts
|
|
276
|
+
import { calculateTransitRoute, RouteType } from 'expo-gaode-map-navigation';
|
|
277
|
+
|
|
278
|
+
const result = await calculateTransitRoute({
|
|
279
|
+
type: RouteType.TRANSIT,
|
|
280
|
+
from: { latitude: 39.9, longitude: 116.4 },
|
|
281
|
+
to: { latitude: 39.91, longitude: 116.41 },
|
|
282
|
+
city1: '010',
|
|
283
|
+
city2: '010',
|
|
284
|
+
});
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
使用前请确认:
|
|
288
|
+
|
|
289
|
+
- 已安装 `expo-gaode-map-web-api`
|
|
290
|
+
- 已在 `ExpoGaodeMapModule.initSDK({ webKey })` 中提供 `webKey`
|
|
291
|
+
|
|
292
|
+
如果缺少依赖或 `webKey`,运行时会抛出明确错误。
|
|
293
|
+
|
|
294
|
+
### API 边界
|
|
295
|
+
|
|
296
|
+
- 导航包内置地图能力,但地图实现与 `expo-gaode-map` 独立维护
|
|
297
|
+
- 用户层输入输出会尽量与核心包保持一致,例如 `LatLngPoint`、`fitToCoordinates`
|
|
298
|
+
- 可共享的范围仅限纯 TS 的 route / AOI 数据适配工具、文档和测试思路
|
|
299
|
+
- 原生地图桥接、overlay 宿主逻辑、MapView facade 不会和核心包合并
|
|
300
|
+
|
|
250
301
|
## API 参考
|
|
251
302
|
|
|
252
303
|
### DriveStrategy (驾车策略)
|
|
@@ -2,6 +2,7 @@ package expo.modules.gaodemap.map
|
|
|
2
2
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
4
|
import android.content.Context
|
|
5
|
+
import android.os.SystemClock
|
|
5
6
|
import android.view.View
|
|
6
7
|
import android.view.ViewGroup
|
|
7
8
|
import com.amap.api.maps.AMap
|
|
@@ -32,6 +33,10 @@ import androidx.core.graphics.withTranslation
|
|
|
32
33
|
@SuppressLint("ViewConstructor")
|
|
33
34
|
class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(context, appContext) {
|
|
34
35
|
|
|
36
|
+
init {
|
|
37
|
+
orientation = VERTICAL
|
|
38
|
+
}
|
|
39
|
+
|
|
35
40
|
/**
|
|
36
41
|
* 拦截 React Native 的 ViewManager 操作
|
|
37
42
|
* 重写 requestLayout 防止在移除视图时触发布局异常
|
|
@@ -44,13 +49,76 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
|
|
|
44
49
|
}
|
|
45
50
|
}
|
|
46
51
|
|
|
52
|
+
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
|
53
|
+
val measuredWidth = View.MeasureSpec.getSize(widthMeasureSpec)
|
|
54
|
+
val measuredHeight = View.MeasureSpec.getSize(heightMeasureSpec)
|
|
55
|
+
|
|
56
|
+
setMeasuredDimension(measuredWidth, measuredHeight)
|
|
57
|
+
|
|
58
|
+
for (i in 0 until childCount) {
|
|
59
|
+
val child = getChildAt(i) ?: continue
|
|
60
|
+
if (child.visibility == View.GONE) {
|
|
61
|
+
continue
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (child === mapView) {
|
|
65
|
+
val childWidthSpec = View.MeasureSpec.makeMeasureSpec(measuredWidth, View.MeasureSpec.EXACTLY)
|
|
66
|
+
val childHeightSpec = View.MeasureSpec.makeMeasureSpec(measuredHeight, View.MeasureSpec.EXACTLY)
|
|
67
|
+
child.measure(childWidthSpec, childHeightSpec)
|
|
68
|
+
continue
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
val lp = child.layoutParams
|
|
72
|
+
val childWidthSpec = when {
|
|
73
|
+
lp?.width != null && lp.width > 0 ->
|
|
74
|
+
View.MeasureSpec.makeMeasureSpec(lp.width, View.MeasureSpec.EXACTLY)
|
|
75
|
+
else ->
|
|
76
|
+
View.MeasureSpec.makeMeasureSpec(measuredWidth, View.MeasureSpec.AT_MOST)
|
|
77
|
+
}
|
|
78
|
+
val childHeightSpec = when {
|
|
79
|
+
lp?.height != null && lp.height > 0 ->
|
|
80
|
+
View.MeasureSpec.makeMeasureSpec(lp.height, View.MeasureSpec.EXACTLY)
|
|
81
|
+
else ->
|
|
82
|
+
View.MeasureSpec.makeMeasureSpec(measuredHeight, View.MeasureSpec.AT_MOST)
|
|
83
|
+
}
|
|
84
|
+
child.measure(childWidthSpec, childHeightSpec)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
|
|
89
|
+
val width = right - left
|
|
90
|
+
val height = bottom - top
|
|
91
|
+
|
|
92
|
+
for (i in 0 until childCount) {
|
|
93
|
+
val child = getChildAt(i) ?: continue
|
|
94
|
+
if (child.visibility == View.GONE) {
|
|
95
|
+
continue
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (child === mapView) {
|
|
99
|
+
child.layout(0, 0, width, height)
|
|
100
|
+
continue
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
val childWidth = child.measuredWidth
|
|
104
|
+
val childHeight = child.measuredHeight
|
|
105
|
+
child.layout(0, 0, childWidth, childHeight)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
47
109
|
// Props 存储
|
|
48
110
|
/** 地图类型 */
|
|
49
|
-
internal var mapType: Int =
|
|
111
|
+
internal var mapType: Int = 1
|
|
50
112
|
/** 初始相机位置 */
|
|
51
113
|
internal var initialCameraPosition: Map<String, Any?>? = null
|
|
52
114
|
/** 是否跟随用户位置 */
|
|
53
115
|
internal var followUserLocation: Boolean = false
|
|
116
|
+
/** 是否显示底图文字标注 */
|
|
117
|
+
private var labelsEnabled: Boolean = true
|
|
118
|
+
/** 是否显示定位按钮 */
|
|
119
|
+
private var myLocationButtonEnabled: Boolean = false
|
|
120
|
+
/** 相机移动事件节流间隔 */
|
|
121
|
+
private var cameraEventThrottleMs: Long = 32L
|
|
54
122
|
/** 自定义地图样式配置(缓存) */
|
|
55
123
|
private var customMapStyleData: Map<String, Any>? = null
|
|
56
124
|
|
|
@@ -59,26 +127,17 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
|
|
|
59
127
|
|
|
60
128
|
// 事件派发器
|
|
61
129
|
private val onMapPress by EventDispatcher()
|
|
130
|
+
private val onPressPoi by EventDispatcher()
|
|
62
131
|
private val onMapLongPress by EventDispatcher()
|
|
63
132
|
private val onLoad by EventDispatcher()
|
|
64
133
|
private val onLocation by EventDispatcher()
|
|
65
134
|
private val onCameraMove by EventDispatcher()
|
|
66
135
|
private val onCameraIdle by EventDispatcher()
|
|
67
136
|
|
|
68
|
-
// 事件节流控制
|
|
69
|
-
/** 相机移动事件节流间隔(毫秒) */
|
|
70
|
-
private val CAMERA_MOVE_THROTTLE_MS = 100L
|
|
71
|
-
/** 上次触发相机移动事件的时间戳 */
|
|
72
|
-
private var lastCameraMoveTime = 0L
|
|
73
137
|
/** 缓存的相机移动事件数据 */
|
|
74
138
|
private var pendingCameraMoveData: Map<String, Any>? = null
|
|
75
|
-
|
|
76
|
-
private
|
|
77
|
-
pendingCameraMoveData?.let { data ->
|
|
78
|
-
onCameraMove(data)
|
|
79
|
-
pendingCameraMoveData = null
|
|
80
|
-
}
|
|
81
|
-
}
|
|
139
|
+
private var pendingCameraMoveDispatch: Runnable? = null
|
|
140
|
+
private var lastCameraMoveDispatchAt: Long = 0L
|
|
82
141
|
|
|
83
142
|
// 高德地图视图
|
|
84
143
|
private lateinit var mapView: MapView
|
|
@@ -127,7 +186,7 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
|
|
|
127
186
|
isMapLoaded = true
|
|
128
187
|
|
|
129
188
|
// 应用缓存的 Props
|
|
130
|
-
if (mapType !=
|
|
189
|
+
if (mapType != 1) {
|
|
131
190
|
setMapType(mapType)
|
|
132
191
|
}
|
|
133
192
|
|
|
@@ -142,6 +201,9 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
|
|
|
142
201
|
uiManager.setCustomMapStyle(styleData)
|
|
143
202
|
}
|
|
144
203
|
|
|
204
|
+
uiManager.setLabelsEnabled(labelsEnabled)
|
|
205
|
+
uiManager.setMyLocationButtonEnabled(myLocationButtonEnabled)
|
|
206
|
+
|
|
145
207
|
onLoad(mapOf("loaded" to true))
|
|
146
208
|
}
|
|
147
209
|
} catch (_: Exception) {
|
|
@@ -172,49 +234,8 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
|
|
|
172
234
|
// 通知辅助监听器
|
|
173
235
|
cameraChangeListeners.forEach { it.onCameraChange(cameraPosition) }
|
|
174
236
|
|
|
175
|
-
// 相机移动中 - 应用节流优化
|
|
176
237
|
cameraPosition?.let {
|
|
177
|
-
|
|
178
|
-
val visibleRegion = aMap.projection.visibleRegion
|
|
179
|
-
val eventData = mapOf(
|
|
180
|
-
"cameraPosition" to mapOf(
|
|
181
|
-
"target" to mapOf(
|
|
182
|
-
"latitude" to it.target.latitude,
|
|
183
|
-
"longitude" to it.target.longitude
|
|
184
|
-
),
|
|
185
|
-
"zoom" to it.zoom,
|
|
186
|
-
"tilt" to it.tilt,
|
|
187
|
-
"bearing" to it.bearing
|
|
188
|
-
),
|
|
189
|
-
"latLngBounds" to mapOf(
|
|
190
|
-
"northeast" to mapOf(
|
|
191
|
-
"latitude" to visibleRegion.farRight.latitude,
|
|
192
|
-
"longitude" to visibleRegion.farRight.longitude
|
|
193
|
-
),
|
|
194
|
-
"southwest" to mapOf(
|
|
195
|
-
"latitude" to visibleRegion.nearLeft.latitude,
|
|
196
|
-
"longitude" to visibleRegion.nearLeft.longitude
|
|
197
|
-
)
|
|
198
|
-
)
|
|
199
|
-
)
|
|
200
|
-
|
|
201
|
-
// 节流逻辑:100ms 内只触发一次
|
|
202
|
-
if (currentTime - lastCameraMoveTime >= CAMERA_MOVE_THROTTLE_MS) {
|
|
203
|
-
// 超过节流时间,立即触发事件
|
|
204
|
-
lastCameraMoveTime = currentTime
|
|
205
|
-
onCameraMove(eventData)
|
|
206
|
-
// 清除待处理的事件和定时器
|
|
207
|
-
mainHandler.removeCallbacks(throttleRunnable)
|
|
208
|
-
pendingCameraMoveData = null
|
|
209
|
-
} else {
|
|
210
|
-
// 在节流时间内,缓存事件数据,使用定时器延迟触发
|
|
211
|
-
pendingCameraMoveData = eventData
|
|
212
|
-
mainHandler.removeCallbacks(throttleRunnable)
|
|
213
|
-
mainHandler.postDelayed(
|
|
214
|
-
throttleRunnable,
|
|
215
|
-
CAMERA_MOVE_THROTTLE_MS - (currentTime - lastCameraMoveTime)
|
|
216
|
-
)
|
|
217
|
-
}
|
|
238
|
+
dispatchCameraMoveEvent(buildCameraEventData(it))
|
|
218
239
|
}
|
|
219
240
|
}
|
|
220
241
|
|
|
@@ -222,30 +243,10 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
|
|
|
222
243
|
// 通知辅助监听器
|
|
223
244
|
cameraChangeListeners.forEach { it.onCameraChangeFinish(cameraPosition) }
|
|
224
245
|
|
|
225
|
-
|
|
246
|
+
flushPendingCameraMoveEvent()
|
|
247
|
+
|
|
226
248
|
cameraPosition?.let {
|
|
227
|
-
|
|
228
|
-
onCameraIdle(mapOf(
|
|
229
|
-
"cameraPosition" to mapOf(
|
|
230
|
-
"target" to mapOf(
|
|
231
|
-
"latitude" to it.target.latitude,
|
|
232
|
-
"longitude" to it.target.longitude
|
|
233
|
-
),
|
|
234
|
-
"zoom" to it.zoom,
|
|
235
|
-
"tilt" to it.tilt,
|
|
236
|
-
"bearing" to it.bearing
|
|
237
|
-
),
|
|
238
|
-
"latLngBounds" to mapOf(
|
|
239
|
-
"northeast" to mapOf(
|
|
240
|
-
"latitude" to visibleRegion.farRight.latitude,
|
|
241
|
-
"longitude" to visibleRegion.farRight.longitude
|
|
242
|
-
),
|
|
243
|
-
"southwest" to mapOf(
|
|
244
|
-
"latitude" to visibleRegion.nearLeft.latitude,
|
|
245
|
-
"longitude" to visibleRegion.nearLeft.longitude
|
|
246
|
-
)
|
|
247
|
-
)
|
|
248
|
-
))
|
|
249
|
+
onCameraIdle(buildCameraEventData(it))
|
|
249
250
|
}
|
|
250
251
|
}
|
|
251
252
|
})
|
|
@@ -312,6 +313,17 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
|
|
|
312
313
|
))
|
|
313
314
|
}
|
|
314
315
|
|
|
316
|
+
aMap.setOnPOIClickListener { poi ->
|
|
317
|
+
onPressPoi(mapOf(
|
|
318
|
+
"id" to poi.poiId,
|
|
319
|
+
"name" to poi.name,
|
|
320
|
+
"position" to mapOf(
|
|
321
|
+
"latitude" to poi.coordinate.latitude,
|
|
322
|
+
"longitude" to poi.coordinate.longitude
|
|
323
|
+
)
|
|
324
|
+
))
|
|
325
|
+
}
|
|
326
|
+
|
|
315
327
|
aMap.setOnMapLongClickListener { latLng ->
|
|
316
328
|
onMapLongPress(mapOf(
|
|
317
329
|
"latitude" to latLng.latitude,
|
|
@@ -415,6 +427,24 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
|
|
|
415
427
|
fun setShowsBuildings(show: Boolean) = uiManager.setShowsBuildings(show)
|
|
416
428
|
/** 设置是否显示室内地图 */
|
|
417
429
|
fun setShowsIndoorMap(show: Boolean) = uiManager.setShowsIndoorMap(show)
|
|
430
|
+
/** 设置是否显示底图文字标注 */
|
|
431
|
+
fun setLabelsEnabled(enabled: Boolean) {
|
|
432
|
+
labelsEnabled = enabled
|
|
433
|
+
uiManager.setLabelsEnabled(enabled)
|
|
434
|
+
}
|
|
435
|
+
/** 设置是否显示定位按钮 */
|
|
436
|
+
fun setMyLocationButtonEnabled(enabled: Boolean) {
|
|
437
|
+
myLocationButtonEnabled = enabled
|
|
438
|
+
uiManager.setMyLocationButtonEnabled(enabled)
|
|
439
|
+
}
|
|
440
|
+
/** 设置相机移动事件节流间隔 */
|
|
441
|
+
fun setCameraEventThrottleMs(throttleMs: Int) {
|
|
442
|
+
cameraEventThrottleMs = throttleMs.toLong().coerceAtLeast(0L)
|
|
443
|
+
if (cameraEventThrottleMs == 0L) {
|
|
444
|
+
pendingCameraMoveDispatch?.let(mainHandler::removeCallbacks)
|
|
445
|
+
pendingCameraMoveDispatch = null
|
|
446
|
+
}
|
|
447
|
+
}
|
|
418
448
|
|
|
419
449
|
/**
|
|
420
450
|
* 设置自定义地图样式
|
|
@@ -591,8 +621,8 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
|
|
|
591
621
|
@Suppress("unused")
|
|
592
622
|
fun onDestroy() {
|
|
593
623
|
try {
|
|
594
|
-
|
|
595
|
-
|
|
624
|
+
pendingCameraMoveDispatch?.let(mainHandler::removeCallbacks)
|
|
625
|
+
pendingCameraMoveDispatch = null
|
|
596
626
|
pendingCameraMoveData = null
|
|
597
627
|
|
|
598
628
|
// 清理 Handler 回调,防止内存泄露
|
|
@@ -600,6 +630,7 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
|
|
|
600
630
|
|
|
601
631
|
// 清理所有地图监听器
|
|
602
632
|
aMap.setOnMapClickListener(null)
|
|
633
|
+
aMap.setOnPOIClickListener(null)
|
|
603
634
|
aMap.setOnMapLongClickListener(null)
|
|
604
635
|
aMap.setOnMapLoadedListener(null)
|
|
605
636
|
aMap.setOnCameraChangeListener(null)
|
|
@@ -634,9 +665,10 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
|
|
|
634
665
|
override fun addView(child: View?, index: Int) {
|
|
635
666
|
if (child is MarkerView) {
|
|
636
667
|
child.setMap(aMap)
|
|
637
|
-
// MarkerView
|
|
638
|
-
//
|
|
639
|
-
|
|
668
|
+
// MarkerView 需要保留可测量尺寸,否则 Android 无法正确处理
|
|
669
|
+
// Text / View 的 maxWidth 等布局约束,最终会被测成整行宽度。
|
|
670
|
+
// 这里保留 WRAP_CONTENT,并继续移到屏幕外,避免影响可见布局。
|
|
671
|
+
val params = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
|
|
640
672
|
child.layoutParams = params
|
|
641
673
|
child.translationX = -10000f // 移到屏幕外
|
|
642
674
|
child.translationY = -10000f
|
|
@@ -746,7 +778,71 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
|
|
|
746
778
|
return false
|
|
747
779
|
}
|
|
748
780
|
|
|
749
|
-
|
|
750
|
-
|
|
781
|
+
private fun buildCameraEventData(cameraPosition: com.amap.api.maps.model.CameraPosition): Map<String, Any> {
|
|
782
|
+
val visibleRegion = aMap.projection.visibleRegion
|
|
783
|
+
return mapOf(
|
|
784
|
+
"cameraPosition" to mapOf(
|
|
785
|
+
"target" to mapOf(
|
|
786
|
+
"latitude" to cameraPosition.target.latitude,
|
|
787
|
+
"longitude" to cameraPosition.target.longitude
|
|
788
|
+
),
|
|
789
|
+
"zoom" to cameraPosition.zoom,
|
|
790
|
+
"tilt" to cameraPosition.tilt,
|
|
791
|
+
"bearing" to cameraPosition.bearing
|
|
792
|
+
),
|
|
793
|
+
"latLngBounds" to mapOf(
|
|
794
|
+
"northeast" to mapOf(
|
|
795
|
+
"latitude" to visibleRegion.farRight.latitude,
|
|
796
|
+
"longitude" to visibleRegion.farRight.longitude
|
|
797
|
+
),
|
|
798
|
+
"southwest" to mapOf(
|
|
799
|
+
"latitude" to visibleRegion.nearLeft.latitude,
|
|
800
|
+
"longitude" to visibleRegion.nearLeft.longitude
|
|
801
|
+
)
|
|
802
|
+
)
|
|
803
|
+
)
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
private fun dispatchCameraMoveEvent(eventData: Map<String, Any>) {
|
|
807
|
+
val throttleMs = cameraEventThrottleMs.coerceAtLeast(0L)
|
|
808
|
+
if (throttleMs == 0L) {
|
|
809
|
+
pendingCameraMoveData = null
|
|
810
|
+
pendingCameraMoveDispatch?.let(mainHandler::removeCallbacks)
|
|
811
|
+
pendingCameraMoveDispatch = null
|
|
812
|
+
lastCameraMoveDispatchAt = SystemClock.uptimeMillis()
|
|
813
|
+
onCameraMove(eventData)
|
|
814
|
+
return
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
pendingCameraMoveData = eventData
|
|
818
|
+
|
|
819
|
+
val now = SystemClock.uptimeMillis()
|
|
820
|
+
val elapsed = now - lastCameraMoveDispatchAt
|
|
821
|
+
if (elapsed >= throttleMs) {
|
|
822
|
+
pendingCameraMoveDispatch?.let(mainHandler::removeCallbacks)
|
|
823
|
+
pendingCameraMoveDispatch = null
|
|
824
|
+
flushPendingCameraMoveEvent(now)
|
|
825
|
+
return
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
if (pendingCameraMoveDispatch != null) {
|
|
829
|
+
return
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
val delay = (throttleMs - elapsed).coerceAtLeast(0L)
|
|
833
|
+
val runnable = Runnable {
|
|
834
|
+
pendingCameraMoveDispatch = null
|
|
835
|
+
flushPendingCameraMoveEvent()
|
|
836
|
+
}
|
|
837
|
+
pendingCameraMoveDispatch = runnable
|
|
838
|
+
mainHandler.postDelayed(runnable, delay)
|
|
751
839
|
}
|
|
840
|
+
|
|
841
|
+
private fun flushPendingCameraMoveEvent(timestamp: Long = SystemClock.uptimeMillis()) {
|
|
842
|
+
val eventData = pendingCameraMoveData ?: return
|
|
843
|
+
pendingCameraMoveData = null
|
|
844
|
+
lastCameraMoveDispatchAt = timestamp
|
|
845
|
+
onCameraMove(eventData)
|
|
846
|
+
}
|
|
847
|
+
|
|
752
848
|
}
|
|
@@ -11,7 +11,7 @@ class ExpoGaodeMapViewModule : Module() {
|
|
|
11
11
|
Name("ExpoGaodeMapView")
|
|
12
12
|
|
|
13
13
|
View(ExpoGaodeMapView::class) {
|
|
14
|
-
Events("onMapPress", "onMapLongPress", "onLoad", "onLocation", "onCameraMove", "onCameraIdle")
|
|
14
|
+
Events("onMapPress", "onPressPoi", "onMapLongPress", "onLoad", "onLocation", "onCameraMove", "onCameraIdle")
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
|
|
@@ -54,13 +54,16 @@ class ExpoGaodeMapViewModule : Module() {
|
|
|
54
54
|
Prop<Boolean>("trafficEnabled") { view, show -> view.setShowsTraffic(show) }
|
|
55
55
|
Prop<Boolean>("buildingsEnabled") { view, show -> view.setShowsBuildings(show) }
|
|
56
56
|
Prop<Boolean>("indoorViewEnabled") { view, show -> view.setShowsIndoorMap(show) }
|
|
57
|
+
Prop<Boolean>("labelsEnabled") { view, enabled -> view.setLabelsEnabled(enabled) }
|
|
58
|
+
Prop<Boolean>("myLocationButtonEnabled") { view, enabled -> view.setMyLocationButtonEnabled(enabled) }
|
|
59
|
+
Prop<Int>("cameraEventThrottleMs") { view, throttleMs -> view.setCameraEventThrottleMs(throttleMs) }
|
|
57
60
|
|
|
58
61
|
Prop<Map<String, Any>?>("customMapStyle") { view, styleData ->
|
|
59
62
|
styleData?.let { view.setCustomMapStyle(it) }
|
|
60
63
|
}
|
|
61
64
|
|
|
62
65
|
OnViewDidUpdateProps { view: ExpoGaodeMapView ->
|
|
63
|
-
if (view.mapType !=
|
|
66
|
+
if (view.mapType != 1) {
|
|
64
67
|
view.setMapType(view.mapType)
|
|
65
68
|
}
|
|
66
69
|
|
|
@@ -46,6 +46,13 @@ class UIManager(private val aMap: AMap, private val context: Context) : Location
|
|
|
46
46
|
fun setShowsScale(show: Boolean) {
|
|
47
47
|
aMap.uiSettings.isScaleControlsEnabled = show
|
|
48
48
|
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 设置是否显示定位按钮
|
|
52
|
+
*/
|
|
53
|
+
fun setMyLocationButtonEnabled(enabled: Boolean) {
|
|
54
|
+
aMap.uiSettings.isMyLocationButtonEnabled = enabled
|
|
55
|
+
}
|
|
49
56
|
|
|
50
57
|
// ==================== 手势控制 ====================
|
|
51
58
|
|
|
@@ -336,17 +343,24 @@ class UIManager(private val aMap: AMap, private val context: Context) : Location
|
|
|
336
343
|
fun setShowsIndoorMap(show: Boolean) {
|
|
337
344
|
aMap.showIndoorMap(show)
|
|
338
345
|
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* 设置是否显示底图文字标注
|
|
349
|
+
*/
|
|
350
|
+
fun setLabelsEnabled(enabled: Boolean) {
|
|
351
|
+
aMap.showMapText(enabled)
|
|
352
|
+
}
|
|
339
353
|
|
|
340
354
|
/**
|
|
341
355
|
* 设置地图类型
|
|
342
356
|
*/
|
|
343
357
|
fun setMapType(type: Int) {
|
|
344
358
|
aMap.mapType = when (type) {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
else -> AMap.MAP_TYPE_NORMAL // 标准地图
|
|
359
|
+
2 -> AMap.MAP_TYPE_SATELLITE // 卫星地图
|
|
360
|
+
3 -> AMap.MAP_TYPE_NIGHT // 夜间地图
|
|
361
|
+
4 -> AMap.MAP_TYPE_NAVI // 导航地图
|
|
362
|
+
5 -> AMap.MAP_TYPE_BUS // 公交地图
|
|
363
|
+
else -> AMap.MAP_TYPE_NORMAL // 标准地图 (1, 以及兼容旧值 0)
|
|
350
364
|
}
|
|
351
365
|
}
|
|
352
366
|
|