package expo.modules.gaodemap.navigation.utils import com.amap.api.maps.model.LatLng import com.amap.api.navi.model.* /** * 数据转换工具类 */ object Converters { /** * 转换坐标点为 NaviLatLng(用于步行、骑行) */ fun parseNaviLatLng(map: Map): NaviLatLng { val lat = (map["latitude"] as? Number)?.toDouble() ?: throw Exception("latitude is required") val lng = (map["longitude"] as? Number)?.toDouble() ?: throw Exception("longitude is required") return NaviLatLng(lat, lng) } /** * 转换坐标点为 NaviPoi(用于驾车、货车) */ fun parseNaviPoi(map: Map): NaviPoi { val lat = (map["latitude"] as? Number)?.toDouble() ?: throw Exception("latitude is required") val lng = (map["longitude"] as? Number)?.toDouble() ?: throw Exception("longitude is required") val name = map["name"] as? String val poiId = map["poiId"] as? String // NaviPoi 构造函数需要的是地图库的 LatLng 类型 return NaviPoi(name, LatLng(lat, lng), poiId) } /** * 转换途经点列表 */ fun parseWaypoints(list: List>?): List { return list?.map { parseNaviPoi(it) } ?: emptyList() } /** * 转换途经点列表(NaviLatLng) */ fun parseWaypointsLatLng(list: List>?): List { return list?.map { parseNaviLatLng(it) } ?: emptyList() } /** * 转换避让区域(多边形) * 输入结构:[[{latitude, longitude}, ...], ...] * 每个多边形至少 3 个点才有效 */ @Suppress("UNCHECKED_CAST") fun parseAvoidPolygons(raw: Any?): List> { val polygons = raw as? List<*> ?: return emptyList() return polygons.mapNotNull { polygonRaw -> val pointsRaw = polygonRaw as? List<*> ?: return@mapNotNull null val points = pointsRaw.mapNotNull { pointRaw -> val point = pointRaw as? Map ?: return@mapNotNull null try { parseNaviLatLng(point) } catch (_: Exception) { null } } if (points.size >= 3) points else null } } /** * 转换导航路径信息(用于 getNaviInfo) * Android SDK 中导航信息通过路径对象获取 */ fun convertNaviPathInfo(path: AMapNaviPath): Map { return mapOf( "naviMode" to 0, "currentRoadName" to "", "nextRoadName" to "", "curStepRetainDistance" to 0, "curStepRetainTime" to 0, "pathRetainDistance" to path.allLength, "pathRetainTime" to path.allTime, "currentSpeed" to 0, "iconType" to 0, "iconDirection" to 0, "currentSegmentIndex" to 0, "currentLinkIndex" to 0, "currentPointIndex" to 0, "routeRemainTrafficLightCount" to 0, "driveDistance" to 0, "driveTime" to 0 ) } /** * 转换路径步骤(简化版本,只使用确实存在的属性) */ fun convertSteps(steps: List?): List> { return steps?.map { step -> mapOf( "instruction" to "", "road" to "", "distance" to step.length, "duration" to 0, "polyline" to convertCoords(step.coords), "tollDistance" to step.chargeLength, "tollCost" to step.tollCost ) } ?: emptyList() } /** * 转换坐标列表(NaviLatLng) */ fun convertCoords(coords: List?): List> { return coords?.map { coord -> mapOf( "latitude" to coord.latitude, "longitude" to coord.longitude ) } ?: emptyList() } /** * 转换路径结果(只使用确实存在的属性) */ fun convertNaviPath(path: AMapNaviPath, routeId: Int? = null): Map { val payload = mutableMapOf( "distance" to path.allLength, "duration" to path.allTime, "tollDistance" to 0, "tollCost" to path.tollCost, "trafficLightCount" to path.trafficLightCount, "steps" to convertSteps(path.steps), "polyline" to convertCoords(path.coordList) ) if (routeId != null) { payload["id"] = routeId payload["routeId"] = routeId } return payload } /** * 转换驾车路径结果 */ fun convertDriveRouteResult(paths: Map?): Map { val routes = paths?.entries?.map { (id, path) -> convertNaviPath(path, id) } ?: emptyList() return mapOf( "routes" to routes, "taxiCost" to 0 ) } /** * 转换多路线信息 */ fun convertMultiRouteInfo(paths: Map?): List> { return paths?.entries?.map { (id, path) -> mapOf( "id" to id, "routeId" to id, "distance" to path.allLength, "duration" to path.allTime, "tollCost" to path.tollCost, "trafficLightCount" to path.trafficLightCount, "strategyDesc" to "" ) } ?: emptyList() } }