379 lines
12 KiB
Kotlin
379 lines
12 KiB
Kotlin
package com.mogo.map
|
||
|
||
import android.os.Looper
|
||
import com.mogo.eagle.core.data.map.MogoLocation
|
||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.i
|
||
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
|
||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_MAP
|
||
import com.mogo.map.MogoData.Companion.mogoMapData
|
||
import com.mogo.map.entities.BusStation
|
||
import com.mogo.map.entities.CrossRoad
|
||
import com.mogo.map.entities.Lane
|
||
import com.mogo.map.location.GDLocationClient.Companion.gdLocationClient
|
||
import com.mogo.map.utils.HDMapUtils.getHDCityCode
|
||
import com.zhidaoauto.map.data.point.LonLatPoint
|
||
import com.zhidaoauto.map.data.road.CenterLine
|
||
import com.zhidaoauto.map.data.road.RoadCross
|
||
import com.zhidaoauto.map.data.road.RoadNameInfo
|
||
import com.zhidaoauto.map.data.road.RoadRectInfos
|
||
import com.zhidaoauto.map.data.road.RoutePath
|
||
import com.zhidaoauto.map.data.routeinfo.RoadInfo
|
||
import com.zhidaoauto.map.sdk.open.MapAutoApi
|
||
import com.zhidaoauto.map.sdk.open.abs.IResult
|
||
import com.zhidaoauto.map.sdk.open.abs.OnHdDataDownByCityListener
|
||
import com.zhidaoauto.map.sdk.open.data.CityInfo
|
||
import com.zhidaoauto.map.sdk.open.data.MapDataApi
|
||
import java.util.concurrent.CountDownLatch
|
||
import java.util.concurrent.TimeUnit.SECONDS
|
||
import java.util.concurrent.atomic.AtomicReference
|
||
|
||
/**
|
||
* 地图数据工具,涉及到数据调用可能会有耗时,建议IO操作
|
||
* 地图call回调在主线程,有需要io操作的业务建议切换线程或由MapDataWrapper线程池操作
|
||
*/
|
||
object MapDataWrapper : IMogoData {
|
||
|
||
private const val TAG = "MapDataWrapper"
|
||
|
||
fun init() {
|
||
mogoMapData.init(this)
|
||
}
|
||
|
||
/**
|
||
* 设置debug模式
|
||
*/
|
||
override fun setDebugMode(debugMode: Boolean) {
|
||
MapAutoApi.setDebugMode(debugMode)
|
||
}
|
||
|
||
/**
|
||
* 获取车道中心线数据
|
||
* @param lon 经度
|
||
* @param lat 纬度
|
||
* @param angle 角度
|
||
* @param call 回调
|
||
*/
|
||
@Synchronized
|
||
override fun getCenterLineInfo(
|
||
lon: Double,
|
||
lat: Double,
|
||
angle: Float,
|
||
call: ((CenterLine?) -> Unit)
|
||
) {
|
||
MapDataApi.getCenterLineInfo(
|
||
lon,
|
||
lat,
|
||
angle,
|
||
object : IResult<CenterLine> {
|
||
override fun result(
|
||
code: Int,
|
||
result: CenterLine?
|
||
) {
|
||
call.invoke(result)
|
||
}
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 按距离获取道路数据
|
||
* @param lon 经度
|
||
* @param lat 纬度
|
||
* @param angle 角度
|
||
* @param call 回调
|
||
*/
|
||
@Synchronized
|
||
override fun getCenterLineRangeInfo(
|
||
lon: Double,
|
||
lat: Double,
|
||
angle: Float,
|
||
distance: Float,
|
||
call: ((CenterLine?) -> Unit)
|
||
) {
|
||
try {
|
||
MapDataApi.getCenterLineRangeInfo(lon, lat, angle, distance, false, 6,
|
||
object : IResult<CenterLine> {
|
||
override fun result(code: Int, result: CenterLine?) {
|
||
call.invoke(result)
|
||
}
|
||
})
|
||
} catch (t: Throwable) {
|
||
t.printStackTrace()
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取车道限速
|
||
* @param lon 经度
|
||
* @param lat 纬度
|
||
* @param angle 角度
|
||
* @param call 回调
|
||
*/
|
||
@Synchronized
|
||
override fun getLimitSpeed(lon: Double, lat: Double, angle: Float, call: ((Int) -> Unit)) {
|
||
MapDataApi.getLimitSpeed(lon, lat, angle, object : IResult<RoadInfo> {
|
||
override fun result(code: Int, result: RoadInfo?) {
|
||
call.invoke(result?.speed ?: 0)
|
||
}
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 获取道路角度
|
||
* @param lon 经度
|
||
* @param lat 纬度
|
||
* @param angle 角度
|
||
* @param call 回调(主线程)
|
||
*/
|
||
@Synchronized
|
||
override fun getRoadAngle(lon: Double, lat: Double, angle: Float, call: ((Double) -> Unit)) {
|
||
MapDataApi.getRoadRectInfo(lon, lat, angle, object : IResult<RoadRectInfos> {
|
||
override fun result(code: Int, result: RoadRectInfos?) {
|
||
call.invoke(result?.angle ?: 0.0)
|
||
}
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 获取道路宽度
|
||
*/
|
||
@Synchronized
|
||
override fun getRoadWidth(
|
||
lon: Double,
|
||
lat: Double,
|
||
angle: Float,
|
||
isGpsLocation: Boolean,
|
||
isRTK: Boolean
|
||
): Float {
|
||
val singlePointRoadInfo =
|
||
MapDataApi.getSinglePointMatchRoad(lon, lat, angle, isGpsLocation, isRTK)
|
||
return singlePointRoadInfo?.laneWidth ?: 0.0f
|
||
}
|
||
|
||
/**
|
||
* 获取行车方向
|
||
*
|
||
* @return
|
||
*/
|
||
@Synchronized
|
||
override fun getAngle(
|
||
startLon: Double,
|
||
startLat: Double,
|
||
endLon: Double,
|
||
endLat: Double
|
||
): Float {
|
||
return MapAutoApi.getAngle(startLon, startLat, endLon, endLat)
|
||
}
|
||
|
||
/**
|
||
* 获取瓦片id
|
||
*
|
||
* @param lon 经度
|
||
* @param lat 纬度
|
||
* @return 瓦片id
|
||
*/
|
||
@Synchronized
|
||
override fun getTileId(lon: Double, lat: Double): Long {
|
||
return MapAutoApi.getTileID(lon, lat, 13) // 13为默认获取瓦片层级级别
|
||
}
|
||
|
||
@Synchronized
|
||
override fun getCityCode(): Int? {
|
||
return getHDCityCode(gdLocationClient.lastCityCode)
|
||
}
|
||
|
||
/**
|
||
* 通过cityCode获取HDMap对应缓存城市
|
||
*/
|
||
@Synchronized
|
||
override fun cacheHDDataByCity(
|
||
progress: (cityId: Int, progress: Double) -> Unit,
|
||
result: (cityId: Int, state: Int) -> Unit
|
||
) {
|
||
val gdCityCode = gdLocationClient.lastCityCode
|
||
i(M_MAP + TAG, "gdCityCode is:$gdCityCode")
|
||
val id = getHDCityCode(gdCityCode)
|
||
if (id != null && id > 0) {
|
||
MapDataApi.cacheHDDataByCity(id, object : OnHdDataDownByCityListener {
|
||
override fun onMapHDDataCacheProgressByCity(id: Int, p: Double) {
|
||
progress.invoke(id, p * 100)
|
||
}
|
||
|
||
override fun onMapHDDataCacheStateByCity(id: Int, state: Int) {
|
||
result.invoke(id, state)
|
||
}
|
||
})
|
||
}else{
|
||
result.invoke(0, 0)
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* 通过经纬度信息,获取HDMap对应缓存城市
|
||
*/
|
||
@Synchronized
|
||
override fun cacheHDDataByCityByLonLat(
|
||
location: MogoLocation,
|
||
progress: (cityId: Int, progress: Double) -> Unit,
|
||
result: (cityId: Int, state: Int) -> Unit
|
||
) {
|
||
i(M_MAP + TAG, "location lon is:" + location.longitude + ",lat is:" + location.latitude)
|
||
MapDataApi.cacheHDDataByCityByLonLat(
|
||
location.longitude, location.latitude,
|
||
object : OnHdDataDownByCityListener {
|
||
override fun onMapHDDataCacheProgressByCity(id: Int, p: Double) {
|
||
progress.invoke(id, p * 100)
|
||
}
|
||
|
||
override fun onMapHDDataCacheStateByCity(id: Int, state: Int) {
|
||
result.invoke(id, state)
|
||
}
|
||
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 当前城市离线数据是否已缓存
|
||
*/
|
||
@Synchronized
|
||
override fun isCityDataCached(cache: ((Boolean) -> Unit)) {
|
||
val cityCode = gdLocationClient.lastCityCode
|
||
i(M_MAP + TAG, "gdCityCode is:$cityCode")
|
||
val id = getHDCityCode(cityCode)
|
||
if (id != null) {
|
||
MapDataApi.getAllCityCode(object : IResult<ArrayList<CityInfo>> {
|
||
override fun result(code: Int, result: ArrayList<CityInfo>?) {
|
||
if (result != null) {
|
||
for (cityInfo in result) {
|
||
if (id == cityInfo.cityCode) {
|
||
cache.invoke(cityInfo.isCache)
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
})
|
||
} else {
|
||
cache.invoke(false)
|
||
}
|
||
}
|
||
|
||
@Synchronized
|
||
override fun cancelDownloadCacheData() {
|
||
MapDataApi.cancelCacheHDData()
|
||
}
|
||
|
||
override fun getRoadInfo(
|
||
lon: Double,
|
||
lat: Double,
|
||
angle: Float
|
||
): com.mogo.map.entities.RoadInfo {
|
||
if (Looper.getMainLooper() == Looper.myLooper()) {
|
||
throw AssertionError()
|
||
}
|
||
val latch = CountDownLatch(1)
|
||
var tempCode: Int = Int.MIN_VALUE
|
||
var tempData: RoadNameInfo? = null
|
||
Logger.d(TAG, "getRoadInfo --- 1 ---")
|
||
MapDataApi.getRoadName(lon, lat, angle, object : IResult<RoadNameInfo> {
|
||
override fun result(code: Int, result: RoadNameInfo?) {
|
||
try {
|
||
Logger.d(TAG, "getRoadInfo ==> code: $code, result: $result")
|
||
tempCode = code
|
||
tempData = result
|
||
} finally {
|
||
latch.countDown()
|
||
}
|
||
}
|
||
})
|
||
try {
|
||
if (latch.await(5, SECONDS)) {
|
||
Logger.d(TAG, "getRoadInfo --- 2 ---: code -> $tempCode, data -> $tempData")
|
||
} else {
|
||
Logger.d(TAG, "getRoadInfo --- 3 ---: code -> $tempCode, data -> $tempData")
|
||
}
|
||
} catch (e: InterruptedException) {
|
||
e.printStackTrace()
|
||
}
|
||
return com.mogo.map.entities.RoadInfo(
|
||
tempCode,
|
||
tempData?.tile_id?.toLong() ?: 0L,
|
||
tempData?.road_id?.toInt() ?: 0,
|
||
tempData?.road_name ?: ""
|
||
)
|
||
}
|
||
|
||
override fun getLaneInfo(tileId: Long, roadId: Int): List<Lane> {
|
||
return MapDataApi.getLaneInfo(tileId, roadId)?.map { itx ->
|
||
Lane(
|
||
itx.laneId,
|
||
itx.laneWidth,
|
||
itx.laneLatLonPoints.map { Pair(it.longitude, it.latitude) })
|
||
} ?: emptyList()
|
||
}
|
||
|
||
@Synchronized
|
||
override fun getBusStation(
|
||
routeList: ArrayList<LonLatPoint>,
|
||
resultUnit: ((MutableList<BusStation>) -> Unit)
|
||
) {
|
||
val resultList = mutableListOf<BusStation>()
|
||
MapDataApi.getBusStation(routeList, object : IResult<RoutePath> {
|
||
override fun result(code: Int, result: RoutePath?) {
|
||
result?.steps?.forEach {
|
||
it?.busStations.forEach {
|
||
val busStation = BusStation(
|
||
it.busStationPoints,
|
||
it.id.toLong(),
|
||
it.roadId,
|
||
it.type,
|
||
-1,
|
||
-1
|
||
)
|
||
resultList.add(busStation)
|
||
}
|
||
}
|
||
resultUnit.invoke(resultList)
|
||
}
|
||
})
|
||
}
|
||
|
||
override fun getCrossRoad(lon: Double, lat: Double, angle: Double): CrossRoad? {
|
||
if (Looper.getMainLooper() == Looper.myLooper()) {
|
||
throw AssertionError()
|
||
}
|
||
val latch = CountDownLatch(1)
|
||
Logger.d(TAG, "getCrossRoad --- 1 ---")
|
||
val temp = AtomicReference<CrossRoad>()
|
||
MapDataApi.getCrossRoad(lon, lat, angle.toFloat(), object : IResult<RoadCross> {
|
||
|
||
override fun result(code: Int, result: RoadCross?) {
|
||
try {
|
||
Logger.d(TAG, "getCrossRoad --- 1 - 1 ---")
|
||
temp.set(
|
||
CrossRoad(
|
||
result?.status ?: 0,
|
||
result?.tile_id ?: "",
|
||
result?.cross_id ?: "",
|
||
result?.tile_id_end ?: "",
|
||
result?.cross_id_end ?: ""
|
||
)
|
||
)
|
||
} finally {
|
||
latch.countDown()
|
||
}
|
||
}
|
||
})
|
||
try {
|
||
Logger.d(TAG, "getCrossRoad --- 2 ---")
|
||
if (latch.await(5, SECONDS)) {
|
||
Logger.d(TAG, "getCrossRoad --- 3 ---")
|
||
} else {
|
||
Logger.d(TAG, "getCrossRoad --- 4 ---")
|
||
}
|
||
} catch (e: InterruptedException) {
|
||
e.printStackTrace()
|
||
}
|
||
return temp.get()
|
||
}
|
||
} |