预警信息导航功能

This commit is contained in:
squallzhjch 2023-09-20 09:42:53 +08:00
parent 923475b199
commit 607d4c290a
9 changed files with 453 additions and 319 deletions

View File

@ -16,7 +16,7 @@ data class NaviRoute(
//方向 //方向
var direct: Int = 0, var direct: Int = 0,
//道路名称 //道路名称
var name: String = "", var name: RenderEntity? = null,
//路段总长 //路段总长
var length: Double = 0.0, var length: Double = 0.0,
//当前link在整段路径中的起点 //当前link在整段路径中的起点

View File

@ -200,7 +200,7 @@ class RealmOperateHelper() {
var link: RenderEntity? = null var link: RenderEntity? = null
val realm = getSelectTaskRealmInstance() val realm = getSelectTaskRealmInstance()
val realmR = val realmR =
getSelectTaskRealmTools(RenderEntity::class.java, true).equalTo("table", "OMDB_RD_LINK") realm.where(RenderEntity::class.java).equalTo("table", "OMDB_RD_LINK")
.equalTo("properties['${LinkTable.linkPid}']", linkPid).findFirst() .equalTo("properties['${LinkTable.linkPid}']", linkPid).findFirst()
if (realmR != null) { if (realmR != null) {
link = realm.copyFromRealm(realmR) link = realm.copyFromRealm(realmR)
@ -287,14 +287,14 @@ class RealmOperateHelper() {
.findAll() .findAll()
} else { } else {
// 查询realm中对应tile号的数据 // 查询realm中对应tile号的数据
if(Constant.CATCH_ALL){ if (Constant.CATCH_ALL) {
realmList = getSelectTaskRealmTools(RenderEntity::class.java, false) realmList = getSelectTaskRealmTools(RenderEntity::class.java, false)
.greaterThanOrEqualTo("tileX", xStart) .greaterThanOrEqualTo("tileX", xStart)
.lessThanOrEqualTo("tileX", xEnd) .lessThanOrEqualTo("tileX", xEnd)
.greaterThanOrEqualTo("tileY", yStart) .greaterThanOrEqualTo("tileY", yStart)
.lessThanOrEqualTo("tileY", yEnd) .lessThanOrEqualTo("tileY", yEnd)
.findAll() .findAll()
}else{ } else {
realmList = getSelectTaskRealmTools(RenderEntity::class.java, false) realmList = getSelectTaskRealmTools(RenderEntity::class.java, false)
.greaterThanOrEqualTo("tileX", xStart) .greaterThanOrEqualTo("tileX", xStart)
.lessThanOrEqualTo("tileX", xEnd) .lessThanOrEqualTo("tileX", xEnd)

View File

@ -27,6 +27,7 @@ import com.blankj.utilcode.util.ClipboardUtils
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import com.navinfo.collect.library.data.entity.RenderEntity import com.navinfo.collect.library.data.entity.RenderEntity
import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.collect.library.map.NIMapController import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.map.handler.MeasureLayerHandler import com.navinfo.collect.library.map.handler.MeasureLayerHandler
import com.navinfo.omqs.Constant import com.navinfo.omqs.Constant
@ -38,6 +39,7 @@ import com.navinfo.omqs.databinding.ActivityMainBinding
import com.navinfo.omqs.http.offlinemapdownload.OfflineMapDownloadManager import com.navinfo.omqs.http.offlinemapdownload.OfflineMapDownloadManager
import com.navinfo.omqs.tools.LayerConfigUtils import com.navinfo.omqs.tools.LayerConfigUtils
import com.navinfo.omqs.ui.activity.BaseActivity import com.navinfo.omqs.ui.activity.BaseActivity
import com.navinfo.omqs.ui.dialog.LoadingDialog
import com.navinfo.omqs.ui.fragment.console.ConsoleFragment import com.navinfo.omqs.ui.fragment.console.ConsoleFragment
import com.navinfo.omqs.ui.fragment.itemlist.ItemListFragment import com.navinfo.omqs.ui.fragment.itemlist.ItemListFragment
import com.navinfo.omqs.ui.fragment.offlinemap.OfflineMapFragment import com.navinfo.omqs.ui.fragment.offlinemap.OfflineMapFragment
@ -47,6 +49,7 @@ import com.navinfo.omqs.ui.fragment.tasklist.TaskManagerFragment
import com.navinfo.omqs.ui.other.BaseToast import com.navinfo.omqs.ui.other.BaseToast
import com.navinfo.omqs.ui.widget.RecyclerViewSpacesItemDecoration import com.navinfo.omqs.ui.widget.RecyclerViewSpacesItemDecoration
import com.navinfo.omqs.util.FlowEventBus import com.navinfo.omqs.util.FlowEventBus
import com.navinfo.omqs.util.NaviStatus
import com.navinfo.omqs.util.SignUtil import com.navinfo.omqs.util.SignUtil
import com.navinfo.omqs.util.SpeakMode import com.navinfo.omqs.util.SpeakMode
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@ -66,6 +69,12 @@ class MainActivity : BaseActivity() {
private lateinit var binding: ActivityMainBinding private lateinit var binding: ActivityMainBinding
private val viewModel by viewModels<MainViewModel>() private val viewModel by viewModels<MainViewModel>()
private val loadingDialog by lazy {
MaterialAlertDialogBuilder(
this,
com.google.android.material.R.style.MaterialAlertDialog_Material3_Animation
).setMessage("正在计算路线中...").setCancelable(false).show()
}
/** /**
* 左侧fragment * 左侧fragment
@ -280,9 +289,10 @@ class MainActivity : BaseActivity() {
//道路绑定,名称变化 //道路绑定,名称变化
viewModel.liveDataRoadName.observe(this) { viewModel.liveDataRoadName.observe(this) {
if (it != null) { if (it != null) {
binding.mainActivityRoadName.visibility = View.VISIBLE
binding.mainActivityRoadName.text = it.properties["name"] binding.mainActivityRoadName.text = it.properties["name"]
} else { } else {
binding.mainActivityRoadName.text = " " binding.mainActivityRoadName.visibility = View.INVISIBLE
} }
} }
@ -325,7 +335,7 @@ class MainActivity : BaseActivity() {
7, RoundingMode.HALF_UP 7, RoundingMode.HALF_UP
) )
},${BigDecimal(it.latitude).setScale(7, RoundingMode.HALF_UP)}" },${BigDecimal(it.latitude).setScale(7, RoundingMode.HALF_UP)}"
if(Constant.AUTO_LOCATION){ if (Constant.AUTO_LOCATION) {
viewModel.startAutoLocationTimer() viewModel.startAutoLocationTimer()
} }
binding.mainActivityLocation.setImageResource(R.drawable.icon_location) binding.mainActivityLocation.setImageResource(R.drawable.icon_location)
@ -334,8 +344,8 @@ class MainActivity : BaseActivity() {
Log.e("qj", "异常 $e") Log.e("qj", "异常 $e")
} }
} }
viewModel.liveDataAutoLocation.observe(this){ viewModel.liveDataAutoLocation.observe(this) {
if(it==true){ if (it == true) {
onClickLocation() onClickLocation()
} }
} }
@ -418,6 +428,52 @@ class MainActivity : BaseActivity() {
Toast.makeText(this, it, Toast.LENGTH_SHORT).show() Toast.makeText(this, it, Toast.LENGTH_SHORT).show()
} }
viewModel.liveDataNaviStatus.observe(this) {
when (it) {
NaviStatus.NAVI_STATUS_PATH_ERROR_BLOCKED -> {
Toast.makeText(
this,
"路径不通,请检查",
Toast.LENGTH_SHORT
).show()
if (loadingDialog.isShowing)
loadingDialog.dismiss()
}
NaviStatus.NAVI_STATUS_PATH_PLANNING -> {
if (!loadingDialog.isShowing)
loadingDialog.show()
}
NaviStatus.NAVI_STATUS_PATH_ERROR_NODE -> {
Toast.makeText(
this,
"查询link基本信息表失败node表",
Toast.LENGTH_SHORT
).show()
loadingDialog.dismiss()
}
NaviStatus.NAVI_STATUS_PATH_ERROR_DIRECTION -> {
Toast.makeText(
this,
"查询link基本信息表失败方向表",
Toast.LENGTH_SHORT
).show()
loadingDialog.dismiss()
}
NaviStatus.NAVI_STATUS_PATH_SUCCESS -> {
loadingDialog.dismiss()
}
NaviStatus.NAVI_STATUS_DISTANCE_OFF -> {
Toast.makeText(
this,
"偏离路线",
Toast.LENGTH_SHORT
).show()
}
NaviStatus.NAVI_STATUS_DIRECTION_OFF -> TODO()
}
}
viewModel.liveDataItemList.observe(this) { viewModel.liveDataItemList.observe(this) {
if (it.isNotEmpty()) { if (it.isNotEmpty()) {
if (leftFragment == null || leftFragment !is ItemListFragment) { if (leftFragment == null || leftFragment !is ItemListFragment) {
@ -1102,7 +1158,7 @@ class MainActivity : BaseActivity() {
* 路径规划 * 路径规划
*/ */
fun onClickRouteFragment() { fun onClickRouteFragment() {
Toast.makeText(this, "功能开发中", Toast.LENGTH_SHORT).show() viewModel.planningPath()
} }
/** /**

View File

@ -86,7 +86,7 @@ class MainViewModel @Inject constructor(
private var mCameraDialog: CommonDialog? = null private var mCameraDialog: CommonDialog? = null
//路径计算 //路径计算
val liveDataPlanningPathStatus = MutableLiveData<Int>() val liveDataNaviStatus = MutableLiveData<NaviStatus>()
//地图点击捕捉到的质检数据ID列表 //地图点击捕捉到的质检数据ID列表
val liveDataQsRecordIdList = MutableLiveData<List<String>>() val liveDataQsRecordIdList = MutableLiveData<List<String>>()
@ -124,6 +124,7 @@ class MainViewModel @Inject constructor(
*/ */
val listDataMessage = MutableLiveData<String>() val listDataMessage = MutableLiveData<String>()
private var traceTag: String = "TRACE_TAG" private var traceTag: String = "TRACE_TAG"
/** /**
@ -201,9 +202,11 @@ class MainViewModel @Inject constructor(
/** /**
* 测量类型 * 测量类型
*/ */
var measuringType: MeasureLayerHandler.MEASURE_TYPE = var measuringType: MeasureLayerHandler.MEASURE_TYPE = MeasureLayerHandler.MEASURE_TYPE.DISTANCE
MeasureLayerHandler.MEASURE_TYPE.DISTANCE
/**
* 捕捉到的上一条link
*/
var linkIdCache = "" var linkIdCache = ""
private var lastNiLocaion: NiLocation? = null private var lastNiLocaion: NiLocation? = null
@ -230,8 +233,8 @@ class MainViewModel @Inject constructor(
//导航信息 //导航信息
private var naviEngine: NaviEngine? = null private var naviEngine: NaviEngine? = null
//规划成功 // 0:不导航 1导航 2暂停
private var naviPathSuccess = false private var naviEngineStatus = 0
// 定义一个互斥锁 // 定义一个互斥锁
private val naviMutex = Mutex() private val naviMutex = Mutex()
@ -257,8 +260,7 @@ class MainViewModel @Inject constructor(
/** /**
* 处理点击道路捕捉回调功能 * 处理点击道路捕捉回调功能
*/ */
mapController.mMapView.addOnNIMapClickListener( mapController.mMapView.addOnNIMapClickListener(TAG,
TAG,
//处理地图点击操作 //处理地图点击操作
object : OnGeoPointClickListener { object : OnGeoPointClickListener {
override fun onMapClick(tag: String, point: GeoPoint) { override fun onMapClick(tag: String, point: GeoPoint) {
@ -283,8 +285,7 @@ class MainViewModel @Inject constructor(
*/ */
object : OnQsRecordItemClickListener { object : OnQsRecordItemClickListener {
override fun onQsRecordList(tag: String, list: MutableList<String>) { override fun onQsRecordList(tag: String, list: MutableList<String>) {
if (tag == TAG) if (tag == TAG) liveDataQsRecordIdList.value = list
liveDataQsRecordIdList.value = list
} }
}, },
/** /**
@ -292,8 +293,7 @@ class MainViewModel @Inject constructor(
*/ */
object : OnTaskLinkItemClickListener { object : OnTaskLinkItemClickListener {
override fun onTaskLink(tag: String, taskLinkId: String) { override fun onTaskLink(tag: String, taskLinkId: String) {
if (tag == TAG) if (tag == TAG) liveDataTaskLink.value = taskLinkId
liveDataTaskLink.value = taskLinkId
} }
}, },
/** /**
@ -301,8 +301,7 @@ class MainViewModel @Inject constructor(
*/ */
object : ONNoteItemClickListener { object : ONNoteItemClickListener {
override fun onNote(tag: String, noteId: String) { override fun onNote(tag: String, noteId: String) {
if (tag == TAG) if (tag == TAG) liveDataNoteId.value = noteId
liveDataNoteId.value = noteId
} }
}, },
@ -311,11 +310,9 @@ class MainViewModel @Inject constructor(
*/ */
object : OnNiLocationItemListener { object : OnNiLocationItemListener {
override fun onNiLocation(tag: String, index: Int, it: NiLocation) { override fun onNiLocation(tag: String, index: Int, it: NiLocation) {
if (tag == TAG) if (tag == TAG) liveDataNILocationList.value = it
liveDataNILocationList.value = it
} }
} })
)
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
getTaskBean() getTaskBean()
@ -339,26 +336,26 @@ class MainViewModel @Inject constructor(
socketServer = SocketServer(mapController, traceDataBase, sharedPreferences) socketServer = SocketServer(mapController, traceDataBase, sharedPreferences)
viewModelScope.launch(Dispatchers.Default) { viewModelScope.launch(Dispatchers.Default) {
// naviTestFlow().collect { point -> naviTestFlow().collect { point ->
// if (naviPathSuccess) { if (naviEngineStatus == 1) {
// naviEngine?.let { naviEngine?.let {
// naviMutex.lock() naviMutex.lock()
// it.bindingRoute(null, point) it.bindingRoute(null, point)
// naviMutex.unlock() naviMutex.unlock()
// } }
// } }
// } }
} }
} }
// fun naviTestFlow(): Flow<GeoPoint> = flow { fun naviTestFlow(): Flow<GeoPoint> = flow {
//
// while (true) { while (true) {
// emit(mapController.mMapView.vtmMap.mapPosition.geoPoint) emit(mapController.mMapView.vtmMap.mapPosition.geoPoint)
// delay(1000) delay(1000)
// } }
// } }
/** /**
* 获取当前任务 * 获取当前任务
@ -369,55 +366,68 @@ class MainViewModel @Inject constructor(
val res = realm.where(TaskBean::class.java).equalTo("id", id).findFirst() val res = realm.where(TaskBean::class.java).equalTo("id", id).findFirst()
if (res != null) { if (res != null) {
currentTaskBean = realm.copyFromRealm(res) currentTaskBean = realm.copyFromRealm(res)
// planningPath(currentTaskBean!!)
} }
realm.close() realm.close()
} }
/**
private fun planningPath(taskBean: TaskBean) { * 规划路径
if (taskBean.status == FileManager.Companion.FileDownloadStatus.DONE) { */
// Toast.makeText(context, "正在计算导航路径", Toast.LENGTH_SHORT).show() fun planningPath() {
viewModelScope.launch(Dispatchers.Default) { viewModelScope.launch(Dispatchers.Default) {
naviMutex.lock() naviMutex.lock()
naviEngine = NaviEngine( getTaskBean()
niMapController = mapController, if (currentTaskBean != null && currentTaskBean!!.status == FileManager.Companion.FileDownloadStatus.DONE) {
naviEngine = NaviEngine(niMapController = mapController,
realmOperateHelper = realmOperateHelper,
callback = object : OnNaviEngineCallbackListener { callback = object : OnNaviEngineCallbackListener {
override fun planningPathSuccess() {
naviPathSuccess = true override fun planningPathStatus(status: NaviStatus) {
listDataMessage.postValue("导航路径规划完成") when (status) {
NaviStatus.NAVI_STATUS_PATH_PLANNING -> naviEngineStatus = 0
NaviStatus.NAVI_STATUS_PATH_ERROR_NODE -> naviEngineStatus = 0
NaviStatus.NAVI_STATUS_PATH_ERROR_DIRECTION -> naviEngineStatus = 0
NaviStatus.NAVI_STATUS_PATH_ERROR_BLOCKED -> naviEngineStatus = 0
NaviStatus.NAVI_STATUS_PATH_SUCCESS -> naviEngineStatus = 1
NaviStatus.NAVI_STATUS_DISTANCE_OFF -> {
}
NaviStatus.NAVI_STATUS_DIRECTION_OFF -> {}
}
liveDataNaviStatus.postValue(status)
} }
override fun planningPathError(errorCode: Int, errorMessage: String) { override suspend fun bindingResults(
naviPathSuccess = false route: NaviRoute?,
listDataMessage.postValue(errorMessage) list: List<NaviRouteItem>
} ) {
override fun bindingResults(list: List<NaviRouteItem>) {
val signList = mutableListOf<SignBean>() val signList = mutableListOf<SignBean>()
for (naviRouteItem in list) { for (naviRouteItem in list) {
val signBean = SignBean( val signBean = SignBean(
iconId = SignUtil.getSignIcon(naviRouteItem.data), iconId = SignUtil.getSignIcon(naviRouteItem.data),
iconText = SignUtil.getSignIconText(naviRouteItem.data), iconText = SignUtil.getSignIconText(naviRouteItem.data),
linkId = naviRouteItem.linkId, linkId = naviRouteItem.linkId,
distance = naviRouteItem.distance, distance = naviRouteItem.distance,
name = SignUtil.getSignNameText(naviRouteItem.data), name = SignUtil.getSignNameText(naviRouteItem.data),
bottomRightText = SignUtil.getSignBottomRightText(naviRouteItem.data), bottomRightText = SignUtil.getSignBottomRightText(
naviRouteItem.data
),
renderEntity = naviRouteItem.data, renderEntity = naviRouteItem.data,
isMoreInfo = SignUtil.isMoreInfo(naviRouteItem.data), isMoreInfo = SignUtil.isMoreInfo(naviRouteItem.data),
index = SignUtil.getRoadInfoIndex(naviRouteItem.data) index = SignUtil.getRoadInfoIndex(naviRouteItem.data)
) )
signList.add(signBean) signList.add(signBean)
} }
if (route != null) {
liveDataRoadName.postValue(route.name)
captureTopSign(route)
}
liveDataSignList.postValue(signList) liveDataSignList.postValue(signList)
} }
}) })
listDataMessage.postValue("开始导航路径规划") naviEngine!!.planningPath(currentTaskBean!!)
naviEngine!!.planningPath(taskBean)
naviMutex.unlock() naviMutex.unlock()
} }
} else {
listDataMessage.postValue("数据未安装,无法计算导航路径")
} }
} }
@ -439,8 +449,7 @@ class MainViewModel @Inject constructor(
var list = mutableListOf<QsRecordBean>() var list = mutableListOf<QsRecordBean>()
val realm = realmOperateHelper.getRealmDefaultInstance() val realm = realmOperateHelper.getRealmDefaultInstance()
realm.executeTransaction { realm.executeTransaction {
val objects = val objects = realmOperateHelper.getRealmTools(QsRecordBean::class.java).findAll()
realmOperateHelper.getRealmTools(QsRecordBean::class.java).findAll()
list = realm.copyFromRealm(objects) list = realm.copyFromRealm(objects)
} }
realm.close() realm.close()
@ -529,8 +538,10 @@ class MainViewModel @Inject constructor(
//增加间距判断 //增加间距判断
if (lastNiLocaion != null) { if (lastNiLocaion != null) {
disance = GeometryTools.getDistance( disance = GeometryTools.getDistance(
location.latitude, location.longitude, location.latitude,
lastNiLocaion!!.latitude, lastNiLocaion!!.longitude location.longitude,
lastNiLocaion!!.latitude,
lastNiLocaion!!.longitude
) )
} }
//室内整理工具时不能进行轨迹存储判断轨迹间隔要超过2.5并小于60米 //室内整理工具时不能进行轨迹存储判断轨迹间隔要超过2.5并小于60米
@ -570,18 +581,17 @@ class MainViewModel @Inject constructor(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val itemList = realmOperateHelper.queryElement( val itemList = realmOperateHelper.queryElement(
GeometryTools.createPoint( GeometryTools.createPoint(
point.longitude, point.longitude, point.latitude
point.latitude
), ),
buffer = 2.4, catchAll = false, buffer = 2.4, catchAll = false,
) )
//增加道路线过滤原则 //增加道路线过滤原则
val filterResult = itemList.filter { val filterResult = itemList.filter {
if(isHighRoad()){ if (isHighRoad()) {
mapController.mMapView.mapLevel>=it.zoomMin&&mapController.mMapView.mapLevel<=it.zoomMax mapController.mMapView.mapLevel >= it.zoomMin && mapController.mMapView.mapLevel <= it.zoomMax
}else{ } else {
//关闭时过滤道路线捕捉s //关闭时过滤道路线捕捉s
mapController.mMapView.mapLevel>=it.zoomMin&&mapController.mMapView.mapLevel<=it.zoomMax&&it.code!=DataCodeEnum.OMDB_RD_LINK.code mapController.mMapView.mapLevel >= it.zoomMin && mapController.mMapView.mapLevel <= it.zoomMax && it.code != DataCodeEnum.OMDB_RD_LINK.code
} }
}.toList() }.toList()
if (filterResult.size == 1) { if (filterResult.size == 1) {
@ -592,6 +602,108 @@ class MainViewModel @Inject constructor(
} }
} }
/**
* 获取道路属性
*/
private suspend fun captureTopSign(route: NaviRoute) {
try {
captureLinkState = true
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//看板数据
val signList = mutableListOf<SignBean>()
val topSignList = mutableListOf<SignBean>()
mapController.lineHandler.linksLayer.clear()
if (linkIdCache != route.linkId) {
mapController.lineHandler.showLine(route.pointList)
var elementList = realmOperateHelper.queryLinkByLinkPid(route.linkId)
for (element in elementList) {
when (element.code) {
DataCodeEnum.OMDB_MULTI_DIGITIZED.code,//上下线分离
DataCodeEnum.OMDB_CON_ACCESS.code,//全封闭
-> {
val signBean = SignBean(
iconId = SignUtil.getSignIcon(element),
iconText = SignUtil.getSignIconText(element),
linkId = route.linkId,
name = SignUtil.getSignNameText(element),
bottomRightText = SignUtil.getSignBottomRightText(element),
renderEntity = element,
isMoreInfo = SignUtil.isMoreInfo(element),
index = SignUtil.getRoadInfoIndex(element)
)
if (signBean.iconText != "") {
topSignList.add(
signBean
)
}
}
DataCodeEnum.OMDB_LANE_NUM.code, //车道数
DataCodeEnum.OMDB_RD_LINK_KIND.code,//种别,
DataCodeEnum.OMDB_RD_LINK_FUNCTION_CLASS.code, // 功能等级,
DataCodeEnum.OMDB_LINK_SPEEDLIMIT.code, //线限速,
DataCodeEnum.OMDB_LINK_DIRECT.code,//道路方向,
DataCodeEnum.OMDB_RAMP.code, //匝道
DataCodeEnum.OMDB_BRIDGE.code,//桥
DataCodeEnum.OMDB_TUNNEL.code,//隧道
DataCodeEnum.OMDB_ROUNDABOUT.code,//环岛
DataCodeEnum.OMDB_LINK_ATTRIBUTE_MAIN_SIDE_ACCESS.code,//出入口
DataCodeEnum.OMDB_LINK_ATTRIBUTE_FORNTAGE.code,//辅路
DataCodeEnum.OMDB_LINK_ATTRIBUTE_SA.code,//SA
DataCodeEnum.OMDB_LINK_ATTRIBUTE_PA.code,//PA
DataCodeEnum.OMDB_LINK_FORM1_1.code,
DataCodeEnum.OMDB_LINK_FORM1_2.code,
DataCodeEnum.OMDB_LINK_FORM1_3.code,
DataCodeEnum.OMDB_LINK_FORM2_1.code,
DataCodeEnum.OMDB_LINK_FORM2_2.code,
DataCodeEnum.OMDB_LINK_FORM2_3.code,
DataCodeEnum.OMDB_LINK_FORM2_4.code,
DataCodeEnum.OMDB_LINK_FORM2_5.code,
DataCodeEnum.OMDB_LINK_FORM2_6.code,
DataCodeEnum.OMDB_LINK_FORM2_7.code,
DataCodeEnum.OMDB_LINK_FORM2_8.code,
DataCodeEnum.OMDB_LINK_FORM2_9.code,
DataCodeEnum.OMDB_LINK_FORM2_10.code,
DataCodeEnum.OMDB_LINK_FORM2_11.code,
DataCodeEnum.OMDB_LINK_FORM2_12.code,
DataCodeEnum.OMDB_LINK_FORM2_13.code,
DataCodeEnum.OMDB_VIADUCT.code,
-> {
val signBean = SignBean(
iconId = SignUtil.getSignIcon(element),
iconText = SignUtil.getSignIconText(element),
linkId = route.linkId,
name = SignUtil.getSignNameText(element),
bottomRightText = SignUtil.getSignBottomRightText(element),
renderEntity = element,
isMoreInfo = SignUtil.isMoreInfo(element),
index = SignUtil.getRoadInfoIndex(element)
)
topSignList.add(
signBean
)
}
}
}
liveDataTopSignList.postValue(topSignList.distinctBy { it.name }
.sortedBy { it.index })
val speechText = SignUtil.getRoadSpeechText(topSignList)
withContext(Dispatchers.Main) {
speakMode?.speakText(speechText)
}
linkIdCache = route.linkId ?: ""
}
}
} catch (e: Exception) {
}
}
/** /**
* 捕获道路和面板 * 捕获道路和面板
*/ */
@ -616,22 +728,18 @@ class MainViewModel @Inject constructor(
var hisRoadName = false var hisRoadName = false
if (linkList.isNotEmpty()) { if (linkList.isNotEmpty()) {
val link = linkList[0]
val linkId = link.properties[RenderEntity.Companion.LinkTable.linkPid]
//看板数据 //看板数据
val signList = mutableListOf<SignBean>() val signList = mutableListOf<SignBean>()
val topSignList = mutableListOf<SignBean>() val topSignList = mutableListOf<SignBean>()
mapController.lineHandler.linksLayer.clear() mapController.lineHandler.linksLayer.clear()
val link = linkList[0]
val linkId = link.properties[RenderEntity.Companion.LinkTable.linkPid]
if (linkIdCache != linkId) { if (linkIdCache != linkId) {
mapController.lineHandler.showLine(link.geometry) mapController.lineHandler.showLine(link.geometry)
linkId?.let { linkId?.let {
var elementList = realmOperateHelper.queryLinkByLinkPid(it) var elementList = realmOperateHelper.queryLinkByLinkPid(it)
for (element in elementList) { for (element in elementList) {
if (element.code == DataCodeEnum.OMDB_LINK_NAME.code) { if (element.code == DataCodeEnum.OMDB_LINK_NAME.code) {
hisRoadName = true hisRoadName = true
liveDataRoadName.postValue(element) liveDataRoadName.postValue(element)
@ -693,7 +801,6 @@ class MainViewModel @Inject constructor(
-> topSignList.add( -> topSignList.add(
signBean signBean
) )
DataCodeEnum.OMDB_SPEEDLIMIT.code,//常规点限速 DataCodeEnum.OMDB_SPEEDLIMIT.code,//常规点限速
DataCodeEnum.OMDB_SPEEDLIMIT_COND.code,//条件点限速 DataCodeEnum.OMDB_SPEEDLIMIT_COND.code,//条件点限速
DataCodeEnum.OMDB_SPEEDLIMIT_VAR.code,//可变点限速 DataCodeEnum.OMDB_SPEEDLIMIT_VAR.code,//可变点限速
@ -702,40 +809,34 @@ class MainViewModel @Inject constructor(
DataCodeEnum.OMDB_LANEINFO.code,//车信 DataCodeEnum.OMDB_LANEINFO.code,//车信
DataCodeEnum.OMDB_WARNINGSIGN.code,//危险信息 DataCodeEnum.OMDB_WARNINGSIGN.code,//危险信息
DataCodeEnum.OMDB_TOLLGATE.code,//收费站 DataCodeEnum.OMDB_TOLLGATE.code,//收费站
-> signList.add( -> {
signBean signList.add(
) signBean
)
}
} }
} }
val realm = realmOperateHelper.getSelectTaskRealmInstance() val realm = realmOperateHelper.getSelectTaskRealmInstance()
val entityList = val entityList = realmOperateHelper.getSelectTaskRealmTools(
realmOperateHelper.getSelectTaskRealmTools( RenderEntity::class.java, true
RenderEntity::class.java, ).and().equalTo("table", DataCodeEnum.OMDB_RESTRICTION.name).and()
true .equalTo(
) "properties['linkIn']", it
.and() ).findAll()
.equalTo("table", DataCodeEnum.OMDB_RESTRICTION.name)
.and()
.equalTo(
"properties['linkIn']", it
).findAll()
if (entityList.isNotEmpty()) { if (entityList.isNotEmpty()) {
val outList = entityList.distinct() val outList = entityList.distinct()
for (i in outList.indices) { for (i in outList.indices) {
val outLink = outList[i].properties["linkOut"] val outLink = outList[i].properties["linkOut"]
val linkOutEntity = val linkOutEntity = realmOperateHelper.getSelectTaskRealmTools(
realmOperateHelper.getSelectTaskRealmTools( RenderEntity::class.java, true
RenderEntity::class.java, ).equalTo("table", DataCodeEnum.OMDB_RD_LINK.name).and()
true .equalTo(
) "properties['${RenderEntity.Companion.LinkTable.linkPid}']",
.equalTo("table", DataCodeEnum.OMDB_RD_LINK.name).and() outLink
.equalTo( ).findFirst()
"properties['${RenderEntity.Companion.LinkTable.linkPid}']",
outLink
).findFirst()
if (linkOutEntity != null) { if (linkOutEntity != null) {
mapController.lineHandler.linksLayer.addLine( mapController.lineHandler.linksLayer.addLine(
linkOutEntity.geometry, 0x7DFF0000 linkOutEntity.geometry, 0x7DFF0000
@ -743,8 +844,7 @@ class MainViewModel @Inject constructor(
} }
} }
mapController.lineHandler.linksLayer.addLine( mapController.lineHandler.linksLayer.addLine(
link.geometry, link.geometry, Color.BLUE
Color.BLUE
) )
realm.close() realm.close()
} }
@ -785,7 +885,6 @@ class MainViewModel @Inject constructor(
mapPosition.setBearing(0f) // 锁定角度,自动将地图旋转到正北方向 mapPosition.setBearing(0f) // 锁定角度,自动将地图旋转到正北方向
mapController.mMapView.vtmMap.setMapPosition(mapPosition) mapController.mMapView.vtmMap.setMapPosition(mapPosition)
mapController.locationLayerHandler.animateToCurrentPosition() mapController.locationLayerHandler.animateToCurrentPosition()
planningPath(currentTaskBean!!)
} }
/** /**
@ -794,7 +893,7 @@ class MainViewModel @Inject constructor(
fun onClickMenu() { fun onClickMenu() {
menuState = !menuState menuState = !menuState
liveDataMenuState.postValue(menuState) liveDataMenuState.postValue(menuState)
naviEngine!!.bindingRoute(null, mapController.mMapView.vtmMap.mapPosition.geoPoint) // naviEngine!!.bindingRoute(null, mapController.mMapView.vtmMap.mapPosition.geoPoint)
} }
override fun onCleared() { override fun onCleared() {
@ -955,6 +1054,11 @@ class MainViewModel @Inject constructor(
linkIdCache = "" linkIdCache = ""
mapController.lineHandler.removeLine() mapController.lineHandler.removeLine()
liveDataSignList.value = mutableListOf() liveDataSignList.value = mutableListOf()
if (bSelectRoad && naviEngineStatus == 1) {
naviEngineStatus = 2
} else if (naviEngineStatus == 2) {
naviEngineStatus = 1
}
} }
/** /**
@ -1044,9 +1148,7 @@ class MainViewModel @Inject constructor(
} }
fun sendServerCommand( fun sendServerCommand(
context: Context, context: Context, traceVideoBean: TraceVideoBean, indoorToolsCommand: IndoorToolsCommand
traceVideoBean: TraceVideoBean,
indoorToolsCommand: IndoorToolsCommand
) { ) {
if (TextUtils.isEmpty(Constant.INDOOR_IP)) { if (TextUtils.isEmpty(Constant.INDOOR_IP)) {
@ -1060,8 +1162,7 @@ class MainViewModel @Inject constructor(
val url = "http://${Constant.INDOOR_IP}:8080/sensor/service/${traceVideoBean.command}?" val url = "http://${Constant.INDOOR_IP}:8080/sensor/service/${traceVideoBean.command}?"
when (val result = networkService.sendServerCommand( when (val result = networkService.sendServerCommand(
url = url, url = url, traceVideoBean = traceVideoBean
traceVideoBean = traceVideoBean
)) { )) {
is NetResult.Success<*> -> { is NetResult.Success<*> -> {
@ -1074,9 +1175,7 @@ class MainViewModel @Inject constructor(
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
Toast.makeText( Toast.makeText(
context, context, "命令成功。", Toast.LENGTH_LONG
"命令成功。",
Toast.LENGTH_LONG
).show() ).show()
liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_SUCCESS) liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_SUCCESS)
@ -1086,8 +1185,7 @@ class MainViewModel @Inject constructor(
//启动双向控制服务 //启动双向控制服务
if (socketServer != null && socketServer!!.isServerClose) { if (socketServer != null && socketServer!!.isServerClose) {
socketServer!!.connect( socketServer!!.connect(
Constant.INDOOR_IP, Constant.INDOOR_IP, this@MainViewModel
this@MainViewModel
) )
} }
@ -1098,8 +1196,7 @@ class MainViewModel @Inject constructor(
context, context,
"命令无效${defaultUserResponse.errmsg}", "命令无效${defaultUserResponse.errmsg}",
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
) ).show()
.show()
} }
liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_FAILURE) liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_FAILURE)
} }
@ -1107,9 +1204,7 @@ class MainViewModel @Inject constructor(
} catch (e: IOException) { } catch (e: IOException) {
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
Toast.makeText( Toast.makeText(
context, context, "${e.message}", Toast.LENGTH_SHORT
"${e.message}",
Toast.LENGTH_SHORT
).show() ).show()
} }
} }
@ -1119,11 +1214,8 @@ class MainViewModel @Inject constructor(
is NetResult.Error<*> -> { is NetResult.Error<*> -> {
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
Toast.makeText( Toast.makeText(
context, context, "${result.exception.message}", Toast.LENGTH_SHORT
"${result.exception.message}", ).show()
Toast.LENGTH_SHORT
)
.show()
} }
liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_FAILURE) liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_FAILURE)
} }
@ -1131,11 +1223,8 @@ class MainViewModel @Inject constructor(
is NetResult.Failure<*> -> { is NetResult.Failure<*> -> {
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
Toast.makeText( Toast.makeText(
context, context, "${result.code}:${result.msg}", Toast.LENGTH_SHORT
"${result.code}:${result.msg}", ).show()
Toast.LENGTH_SHORT
)
.show()
} }
liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_FAILURE) liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_FAILURE)
} }
@ -1158,8 +1247,7 @@ class MainViewModel @Inject constructor(
if (niLocation != null) { if (niLocation != null) {
mapController.markerHandle.addMarker( mapController.markerHandle.addMarker(
GeoPoint( GeoPoint(
niLocation.latitude, niLocation.latitude, niLocation.longitude
niLocation.longitude
), traceTag, "", niLocation as java.lang.Object ), traceTag, "", niLocation as java.lang.Object
) )
} }
@ -1197,9 +1285,7 @@ class MainViewModel @Inject constructor(
override fun onConnect(success: Boolean) { override fun onConnect(success: Boolean) {
if (!success && socketServer != null) { if (!success && socketServer != null) {
BaseToast.makeText( BaseToast.makeText(
mapController.mMapView.context, mapController.mMapView.context, "轨迹反向控制服务失败,请确认连接是否正常!", Toast.LENGTH_SHORT
"轨迹反向控制服务失败,请确认连接是否正常!",
Toast.LENGTH_SHORT
).show() ).show()
} }
} }
@ -1228,9 +1314,7 @@ class MainViewModel @Inject constructor(
Log.e("qj", "反向控制$currentIndexNiLocation") Log.e("qj", "反向控制$currentIndexNiLocation")
} else { } else {
BaseToast.makeText( BaseToast.makeText(
mapController.mMapView.context, mapController.mMapView.context, "没有找到对应轨迹点!", Toast.LENGTH_SHORT
"没有找到对应轨迹点!",
Toast.LENGTH_SHORT
).show() ).show()
} }
} }
@ -1274,8 +1358,7 @@ class MainViewModel @Inject constructor(
startTimer() startTimer()
} }
} else { } else {
Toast.makeText(mapController.mMapView.context, "无数据了!", Toast.LENGTH_LONG) Toast.makeText(mapController.mMapView.context, "无数据了!", Toast.LENGTH_LONG).show()
.show()
cancelTrace() cancelTrace()
} }
} }
@ -1292,13 +1375,13 @@ class MainViewModel @Inject constructor(
/** /**
* 开启自动定位 * 开启自动定位
*/ */
fun startAutoLocationTimer(){ fun startAutoLocationTimer() {
if (autoLocationTimer != null) { if (autoLocationTimer != null) {
cancelAutoLocation() cancelAutoLocation()
} }
autoLocationTimer = fixedRateTimer("", false, disAutoLocationTime, disAutoLocationTime) { autoLocationTimer = fixedRateTimer("", false, disAutoLocationTime, disAutoLocationTime) {
liveDataAutoLocation.postValue(true) liveDataAutoLocation.postValue(true)
Log.e("qj","自动定位开始执行") Log.e("qj", "自动定位开始执行")
startAutoLocationTimer() startAutoLocationTimer()
} }
} }
@ -1371,9 +1454,7 @@ class MainViewModel @Inject constructor(
} else { } else {
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
Toast.makeText( Toast.makeText(
mapController.mMapView.context, mapController.mMapView.context, "未查询到数据", Toast.LENGTH_SHORT
"未查询到数据",
Toast.LENGTH_SHORT
).show() ).show()
} }
} }
@ -1396,9 +1477,7 @@ class MainViewModel @Inject constructor(
} else { } else {
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
Toast.makeText( Toast.makeText(
mapController.mMapView.context, mapController.mMapView.context, "未查询到数据", Toast.LENGTH_SHORT
"未查询到数据",
Toast.LENGTH_SHORT
).show() ).show()
} }
} }
@ -1415,9 +1494,7 @@ class MainViewModel @Inject constructor(
dialog.dismiss() dialog.dismiss()
} else { } else {
Toast.makeText( Toast.makeText(
mapController.mMapView.context, mapController.mMapView.context, "输入格式不正确", Toast.LENGTH_SHORT
"输入格式不正确",
Toast.LENGTH_SHORT
).show() ).show()
} }
} }

View File

@ -79,6 +79,7 @@ class SignAdapter(private var listener: OnSignAdapterClickListener?) :
val bd = holder.viewBinding val bd = holder.viewBinding
if (item.iconId != 0) { if (item.iconId != 0) {
bd.signMainIconBg.visibility = View.VISIBLE
if (item.renderEntity.code == DataCodeEnum.OMDB_WARNINGSIGN.code) { if (item.renderEntity.code == DataCodeEnum.OMDB_WARNINGSIGN.code) {
try { try {
var typeCode = "${item.iconId}" var typeCode = "${item.iconId}"
@ -110,6 +111,8 @@ class SignAdapter(private var listener: OnSignAdapterClickListener?) :
} else { } else {
bd.signMainIconBg.setImageResource(item.iconId) bd.signMainIconBg.setImageResource(item.iconId)
} }
}else{
bd.signMainIconBg.visibility = View.INVISIBLE
} }
bd.signMainIcon.text = item.iconText bd.signMainIcon.text = item.iconText
@ -144,7 +147,7 @@ class SignAdapter(private var listener: OnSignAdapterClickListener?) :
val bd = holder.viewBinding val bd = holder.viewBinding
bd.signMoreIconsLayout.removeAllViews() bd.signMoreIconsLayout.removeAllViews()
bd.signBottomText.text = item.name bd.signBottomText.text = item.name
bd.signBottomRightText.text = item.distance.toString() bd.signBottomRightText.text = "${item.distance}"
val list = SignUtil.getLineInfoIcons(item.renderEntity) val list = SignUtil.getLineInfoIcons(item.renderEntity)
val lineViewS = View(context) val lineViewS = View(context)
lineViewS.layoutParams = ViewGroup.LayoutParams(24, 80) lineViewS.layoutParams = ViewGroup.LayoutParams(24, 80)
@ -216,13 +219,13 @@ class SignAdapter(private var listener: OnSignAdapterClickListener?) :
holder.tag = item.name + position holder.tag = item.name + position
} }
override fun refreshData(newData: List<SignBean>) { // override fun refreshData(newData: List<SignBean>) {
super.refreshData(newData) // super.refreshData(newData)
for (i in newData.indices) { //// ?这是要干嘛 for (i in newData.indices) {
if (selectMoreInfoTag == newData[i].name + i) { //// if (selectMoreInfoTag == newData[i].name + i) {
return //// return
} //// }
} //// }
} // }
} }

View File

@ -152,6 +152,7 @@ class TaskListAdapter(
if (taskBean.status == FileDownloadStatus.DONE) { if (taskBean.status == FileDownloadStatus.DONE) {
binding.taskDownloadBtn.visibility = View.INVISIBLE binding.taskDownloadBtn.visibility = View.INVISIBLE
binding.taskUploadBtn.visibility = View.VISIBLE binding.taskUploadBtn.visibility = View.VISIBLE
} else { } else {
binding.taskDownloadBtn.visibility = View.VISIBLE binding.taskDownloadBtn.visibility = View.VISIBLE
binding.taskUploadBtn.visibility = View.INVISIBLE binding.taskUploadBtn.visibility = View.INVISIBLE

View File

@ -7,6 +7,7 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.navinfo.omqs.R import com.navinfo.omqs.R
@ -14,6 +15,8 @@ import com.navinfo.omqs.databinding.FragmentTaskListBinding
import com.navinfo.omqs.http.taskdownload.TaskDownloadManager import com.navinfo.omqs.http.taskdownload.TaskDownloadManager
import com.navinfo.omqs.http.taskupload.TaskUploadManager import com.navinfo.omqs.http.taskupload.TaskUploadManager
import com.navinfo.omqs.tools.FileManager import com.navinfo.omqs.tools.FileManager
import com.navinfo.omqs.ui.activity.map.MainActivity
import com.navinfo.omqs.ui.activity.map.MainViewModel
import com.navinfo.omqs.ui.fragment.BaseFragment import com.navinfo.omqs.ui.fragment.BaseFragment
import com.navinfo.omqs.ui.other.shareViewModels import com.navinfo.omqs.ui.other.shareViewModels
import com.yanzhenjie.recyclerview.SwipeMenuCreator import com.yanzhenjie.recyclerview.SwipeMenuCreator
@ -58,9 +61,6 @@ class TaskListFragment : BaseFragment() {
Toast.makeText(context, "正在校验", Toast.LENGTH_SHORT).show() Toast.makeText(context, "正在校验", Toast.LENGTH_SHORT).show()
viewModel.checkUploadTask(binding.root.context, taskBean) viewModel.checkUploadTask(binding.root.context, taskBean)
} }
else -> {
}
} }
} }
} }

View File

@ -9,43 +9,70 @@ import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.utils.GeometryTools import com.navinfo.collect.library.utils.GeometryTools
import com.navinfo.omqs.bean.NaviRoute import com.navinfo.omqs.bean.NaviRoute
import com.navinfo.omqs.bean.NaviRouteItem import com.navinfo.omqs.bean.NaviRouteItem
import com.navinfo.omqs.db.RealmOperateHelper
import io.realm.Realm import io.realm.Realm
import io.realm.RealmQuery
import org.locationtech.jts.geom.LineString import org.locationtech.jts.geom.LineString
import org.locationtech.jts.geom.Point import org.locationtech.jts.geom.Point
import org.oscim.core.GeoPoint import org.oscim.core.GeoPoint
public interface OnNaviEngineCallbackListener { public interface OnNaviEngineCallbackListener {
fun planningPathSuccess() fun planningPathStatus(code: NaviStatus)
fun planningPathError(errorCode: Int, errorMessage: String)
fun bindingResults(list: List<NaviRouteItem>) // fun planningPathError(errorCode: NaviStatus, errorMessage: String)
suspend fun bindingResults(route: NaviRoute?, list: List<NaviRouteItem>)
}
enum class NaviStatus {
NAVI_STATUS_PATH_PLANNING, //路径规划中
NAVI_STATUS_PATH_ERROR_NODE,//node点缺失
NAVI_STATUS_PATH_ERROR_DIRECTION,//缺少方向
NAVI_STATUS_PATH_ERROR_BLOCKED,//路径不通
NAVI_STATUS_PATH_SUCCESS,//路径规划成功
NAVI_STATUS_DISTANCE_OFF,//距离偏离
NAVI_STATUS_DIRECTION_OFF,//方向偏离
} }
class NaviEngine(val niMapController: NIMapController, val callback: OnNaviEngineCallbackListener) { class NaviEngine(
private val niMapController: NIMapController,
private val realmOperateHelper: RealmOperateHelper,
val callback: OnNaviEngineCallbackListener
) {
/**
private val QUERY_KEY_LIST = arrayOf( * 要查询的要素列表
*/
private val QUERY_KEY_ITEM_LIST = arrayOf(
DataCodeEnum.OMDB_ELECTRONICEYE.name,
DataCodeEnum.OMDB_SPEEDLIMIT.name, DataCodeEnum.OMDB_SPEEDLIMIT.name,
DataCodeEnum.OMDB_SPEEDLIMIT_COND.name, DataCodeEnum.OMDB_SPEEDLIMIT_COND.name,
DataCodeEnum.OMDB_SPEEDLIMIT_VAR.name, DataCodeEnum.OMDB_SPEEDLIMIT_VAR.name,
DataCodeEnum.OMDB_TRAFFICLIGHT.name, DataCodeEnum.OMDB_TRAFFICLIGHT.name,
DataCodeEnum.OMDB_RESTRICTION.name, // DataCodeEnum.OMDB_RESTRICTION.name,
DataCodeEnum.OMDB_LANEINFO.name, DataCodeEnum.OMDB_LANEINFO.name,
DataCodeEnum.OMDB_TRAFFIC_SIGN.name, DataCodeEnum.OMDB_TRAFFIC_SIGN.name,
DataCodeEnum.OMDB_WARNINGSIGN.name, DataCodeEnum.OMDB_WARNINGSIGN.name,
DataCodeEnum.OMDB_TOLLGATE.name DataCodeEnum.OMDB_TOLLGATE.name
) )
/**
* 要查询的link基本信息列表
*/
private val QUERY_KEY_LINK_INFO_LIST = arrayOf(
DataCodeEnum.OMDB_RD_LINK.name,
DataCodeEnum.OMDB_LINK_DIRECT.name,
DataCodeEnum.OMDB_LINK_NAME.name,
)
/** /**
* 偏离距离 单位 * 偏离距离 单位
*/ */
private val DEVIATION_DISTANCE = 150000 private val DEVIATION_DISTANCE = 15
/** /**
* 偏离次数上限 * 偏离次数上限
*/ */
private val DEVIATION_COUNT = 3 private val DEVIATION_COUNT = 5
/** /**
* 局部匹配时走过的路段还记录100米 * 局部匹配时走过的路段还记录100米
@ -107,6 +134,7 @@ class NaviEngine(val niMapController: NIMapController, val callback: OnNaviEngin
*/ */
var tempRoutList = mutableListOf<NaviRoute>() var tempRoutList = mutableListOf<NaviRoute>()
/** /**
* 所有路段集合 * 所有路段集合
*/ */
@ -149,9 +177,9 @@ class NaviEngine(val niMapController: NIMapController, val callback: OnNaviEngin
* 计算路径 * 计算路径
*/ */
suspend fun planningPath(taskBean: TaskBean) { suspend fun planningPath(taskBean: TaskBean) {
callback.planningPathStatus(NaviStatus.NAVI_STATUS_PATH_PLANNING)
val pathList = mutableListOf<NaviRoute>() val pathList = mutableListOf<NaviRoute>()
val realm = Realm.getDefaultInstance() val realm = realmOperateHelper.getSelectTaskRealmInstance()
for (link in taskBean.hadLinkDvoList) { for (link in taskBean.hadLinkDvoList) {
//测线不参与导航 //测线不参与导航
if (link.linkStatus == 3) { if (link.linkStatus == 3) {
@ -162,37 +190,55 @@ class NaviEngine(val niMapController: NIMapController, val callback: OnNaviEngin
) )
route.pointList = GeometryTools.getGeoPoints(link.geometry) route.pointList = GeometryTools.getGeoPoints(link.geometry)
//查询每条link的snodeenode
val res1 = realm.where(RenderEntity::class.java)
.equalTo("table", DataCodeEnum.OMDB_RD_LINK.name).and()
.equalTo("properties['linkPid']", link.linkPid).findFirst()
res1?.let {
val snodePid = it.properties["snodePid"] val res = realm.where(RenderEntity::class.java).`in`("table", QUERY_KEY_LINK_INFO_LIST)
if (snodePid != null) { .equalTo("properties['linkPid']", link.linkPid).findAll()
route.sNode = snodePid var bHasNode = false
} var bHasDir = false
val enodePid = it.properties["enodePid"] var bHasName = false
if (enodePid != null) { if (res != null) {
route.eNode = enodePid for (entity in res) {
when (entity.code) {
DataCodeEnum.OMDB_RD_LINK.code -> {
bHasNode = true
val snodePid = entity.properties["snodePid"]
if (snodePid != null) {
route.sNode = snodePid
} else {
bHasNode = false
}
val enodePid = entity.properties["enodePid"]
if (enodePid != null) {
route.eNode = enodePid
} else {
bHasNode = false
}
}
DataCodeEnum.OMDB_LINK_DIRECT.code -> {
val direct = entity.properties["direct"]
if (direct != null) {
bHasDir = true
route.direct = direct.toInt()
}
}
DataCodeEnum.OMDB_LINK_NAME.code -> {
bHasName = true
route.name = realm.copyFromRealm(entity)
}
}
} }
} }
//查询每条link的方向 if (!bHasNode) {
val res2 = realm.where(RenderEntity::class.java) callback.planningPathStatus(
.equalTo("table", DataCodeEnum.OMDB_LINK_DIRECT.name).and() NaviStatus.NAVI_STATUS_PATH_ERROR_NODE
.equalTo("properties['linkPid']", link.linkPid).findFirst() )
res2?.let { return
val direct = it.properties["direct"]
if (direct != null) {
route.direct = direct.toInt()
}
} }
//查询每条link的名称 if (!bHasDir) {
val res3 = realm.where(RenderEntity::class.java) callback.planningPathStatus(
.equalTo("table", DataCodeEnum.OMDB_LINK_NAME.name).and() NaviStatus.NAVI_STATUS_PATH_ERROR_DIRECTION
.equalTo("properties['linkPid']", link.linkPid).findFirst() )
res3?.let { return
route.name = "${it.properties["name"]}"
} }
pathList.add(route) pathList.add(route)
} }
@ -269,7 +315,9 @@ class NaviEngine(val niMapController: NIMapController, val callback: OnNaviEngin
} else { } else {
if (!bHasLast && !bHasNext) { if (!bHasLast && !bHasNext) {
bBreak = false bBreak = false
callback.planningPathError(1, "路径不连通!") callback.planningPathStatus(
NaviStatus.NAVI_STATUS_PATH_ERROR_BLOCKED
)
realm.close() realm.close()
return return
} }
@ -279,83 +327,20 @@ class NaviEngine(val niMapController: NIMapController, val callback: OnNaviEngin
val itemMap: MutableMap<GeoPoint, MutableList<RenderEntity>> = mutableMapOf() val itemMap: MutableMap<GeoPoint, MutableList<RenderEntity>> = mutableMapOf()
//查询每根link上的关联要素 //查询每根link上的关联要素
for (route in newRouteList) { for (route in newRouteList) {
itemMap.clear()
//常规点限速 //常规点限速
var res = realm.where(RenderEntity::class.java) val res = realm.where(RenderEntity::class.java)
.equalTo("properties['linkPid']", route.linkId).and().`in`( .equalTo("properties['linkPid']", route.linkId).and().`in`(
"table", "table",
QUERY_KEY_LIST QUERY_KEY_ITEM_LIST
).findAll() ).findAll()
if (res != null) { if (res.isNotEmpty()) {
Log.e("jingo", "道路查询预警要素 ${route.linkId} ${res.size}条数据") // Log.e("jingo", "道路查询预警要素 ${route.linkId} ${res.size}条数据")
for (r in res) { for (r in res) {
Log.e("jingo", "道路查询预警要素 ${r.name}") // Log.e("jingo", "道路查询预警要素 ${r.name}")
insertItemToRoute(realm, route, r, itemMap) insertItemToRoute(realm, route, r, itemMap)
} }
} }
// //条件点限速
// res = realm.where(RenderEntity::class.java)
// .equalTo("table", DataCodeEnum.OMDB_SPEEDLIMIT_COND.name).and()
// .equalTo("properties['linkPid']", route.linkId).findAll()
// if(res != null){
// for(r in res)
// insertItemToRoute(realm, route, r, itemMap)
// }
// //可变点限速
// res = realm.where(RenderEntity::class.java)
// .equalTo("table", DataCodeEnum.OMDB_SPEEDLIMIT_VAR.name).and()
// .equalTo("properties['linkPid']", route.linkId).findAll()
// if(res != null){
// for(r in res)
// insertItemToRoute(realm, route, r, itemMap)
// }
// //交通灯
// res = realm.where(RenderEntity::class.java)
// .equalTo("table", DataCodeEnum.OMDB_TRAFFICLIGHT.name).and()
// .equalTo("properties['linkPid']", route.linkId).findAll()
// if(res != null){
// for(r in res)
// insertItemToRoute(realm, route, r, itemMap)
// }
// //普通交限
// res = realm.where(RenderEntity::class.java)
// .equalTo("table", DataCodeEnum.OMDB_RESTRICTION.name).and()
// .equalTo("properties['linkPid']", route.linkId).findAll()
// if(res != null){
// for(r in res)
// insertItemToRoute(realm, route, r, itemMap)
// }
// //车信
// res = realm.where(RenderEntity::class.java)
// .equalTo("table", DataCodeEnum.OMDB_LANEINFO.name).and()
// .equalTo("properties['linkPid']", route.linkId).findAll()
// if(res != null){
// for(r in res)
// insertItemToRoute(realm, route, r, itemMap)
// }
// //交通标牌
// res = realm.where(RenderEntity::class.java)
// .equalTo("table", DataCodeEnum.OMDB_TRAFFIC_SIGN.name).and()
// .equalTo("properties['linkPid']", route.linkId).findAll()
// if(res != null){
// for(r in res)
// insertItemToRoute(realm, route, r, itemMap)
// }
// //警示信息
// res = realm.where(RenderEntity::class.java)
// .equalTo("table", DataCodeEnum.OMDB_WARNINGSIGN.name).and()
// .equalTo("properties['linkPid']", route.linkId).findAll()
// if(res != null){
// for(r in res)
// insertItemToRoute(realm, route, r, itemMap)
// }
// //OMDB_TOLLGATE
// res = realm.where(RenderEntity::class.java)
// .equalTo("table", DataCodeEnum.OMDB_TOLLGATE.name).and()
// .equalTo("properties['linkPid']", route.linkId).findAll()
// if(res != null){
// for(r in res)
// insertItemToRoute(realm, route, r, itemMap)
// }
//对路径上的要素进行排序 //对路径上的要素进行排序
if (itemMap.isNotEmpty()) { if (itemMap.isNotEmpty()) {
route.itemList = mutableListOf() route.itemList = mutableListOf()
@ -367,6 +352,7 @@ class NaviEngine(val niMapController: NIMapController, val callback: OnNaviEngin
val naviRouteItem = NaviRouteItem(i, item, route.linkId) val naviRouteItem = NaviRouteItem(i, item, route.linkId)
route.itemList!!.add(naviRouteItem) route.itemList!!.add(naviRouteItem)
} }
itemMap.remove(point)
} }
} }
route.itemList!!.sortBy { it.index } route.itemList!!.sortBy { it.index }
@ -374,8 +360,8 @@ class NaviEngine(val niMapController: NIMapController, val callback: OnNaviEngin
} }
realm.close() realm.close()
routeList = newRouteList routeList = newRouteList
callback.planningPathSuccess() callback.planningPathStatus(NaviStatus.NAVI_STATUS_PATH_SUCCESS)
niMapController.lineHandler.showLine(geometry!!.toText())
} }
/** /**
@ -399,7 +385,8 @@ class NaviEngine(val niMapController: NIMapController, val callback: OnNaviEngin
val point = GeoPoint( val point = GeoPoint(
footAndDistance.getCoordinate(0).y, footAndDistance.getCoordinate(0).x footAndDistance.getCoordinate(0).y, footAndDistance.getCoordinate(0).x
) )
niMapController.markerHandle.addMarker(point, res.id, res.name) //测试marker
// niMapController.markerHandle.addMarker(point, res.id, res.name)
route.pointList.add(footAndDistance.footIndex + 1, point) route.pointList.add(footAndDistance.footIndex + 1, point)
if (itemMap.containsKey(point)) { if (itemMap.containsKey(point)) {
itemMap[point]!!.add(realm.copyFromRealm(res)) itemMap[point]!!.add(realm.copyFromRealm(res))
@ -421,7 +408,7 @@ class NaviEngine(val niMapController: NIMapController, val callback: OnNaviEngin
/** /**
* 绑定道路 * 绑定道路
*/ */
fun bindingRoute(location: NiLocation?, point: GeoPoint) { suspend fun bindingRoute(location: NiLocation?, point: GeoPoint) {
if (geometry != null) { if (geometry != null) {
//还没有绑定到路径的时候 //还没有绑定到路径的时候
if (routeIndex < 0) { if (routeIndex < 0) {
@ -430,33 +417,31 @@ class NaviEngine(val niMapController: NIMapController, val callback: OnNaviEngin
//定位点到垂足距离不超过30米 //定位点到垂足距离不超过30米
if (pointPairDistance.getMeterDistance() < DEVIATION_DISTANCE) { if (pointPairDistance.getMeterDistance() < DEVIATION_DISTANCE) {
footIndex = pointPairDistance.footIndex footIndex = pointPairDistance.footIndex
Log.e( // Log.e(
"jingo", // "jingo",
"当前绑定到了整条路线的第 $footIndex${pointPairDistance.getMeterDistance()} " // "当前绑定到了整条路线的第 ${footIndex} 点 ${pointPairDistance.getMeterDistance()} "
) // )
val lastRouteIndex = routeIndex val lastRouteIndex = routeIndex
for (i in routeList.indices) { for (i in routeList.indices) {
val route = routeList[i] val route = routeList[i]
if (route.startIndexInPath <= footIndex && route.endIndexIntPath >= footIndex) { if (route.startIndexInPath <= footIndex && route.endIndexIntPath >= footIndex) {
routeIndex = route.indexInPath routeIndex = route.indexInPath
Log.e( // Log.e(
"jingo", // "jingo",
"当前绑定到了整条路线id ${route.linkId} " // "当前绑定到了整条路线id ${route.linkId} "
) // )
niMapController.lineHandler.showLine(route.pointList) // niMapController.lineHandler.showLine(route.pointList)
footPoint = GeoPoint( footPoint = GeoPoint(
pointPairDistance.getCoordinate(0).y, pointPairDistance.getCoordinate(0).y,
pointPairDistance.getCoordinate(0).x pointPairDistance.getCoordinate(0).x
) )
val listPoint = mutableListOf(point, footPoint!!) // val listPoint = mutableListOf(point, footPoint!!)
niMapController.lineHandler.showLine( // niMapController.lineHandler.showLine(
listPoint // listPoint
) // )
if (lastRouteIndex != routeIndex) { if (lastRouteIndex != routeIndex) {
createTempPath() createTempPath()
} }
matchingItem()
errorCount = 0 errorCount = 0
break break
} }
@ -470,31 +455,30 @@ class NaviEngine(val niMapController: NIMapController, val callback: OnNaviEngin
//定位点到垂足距离不超过30米 //定位点到垂足距离不超过30米
if (pointPairDistance.getMeterDistance() < DEVIATION_DISTANCE) { if (pointPairDistance.getMeterDistance() < DEVIATION_DISTANCE) {
footIndex = pointPairDistance.footIndex + tempRoutList[0].startIndexInPath footIndex = pointPairDistance.footIndex + tempRoutList[0].startIndexInPath
Log.e("jingo", "局部 当前绑定到了整条路线的第 $footIndex") // Log.e("jingo", "局部 当前绑定到了整条路线的第 $footIndex 点")
val lastRouteIndex = routeIndex val lastRouteIndex = routeIndex
for (i in tempRoutList.indices) { for (i in tempRoutList.indices) {
val route = tempRoutList[i] val route = tempRoutList[i]
if (route.startIndexInPath <= footIndex && route.endIndexIntPath >= footIndex) { if (route.startIndexInPath <= footIndex && route.endIndexIntPath >= footIndex) {
routeIndex = route.indexInPath routeIndex = route.indexInPath
Log.e( // Log.e(
"jingo", // "jingo",
"局部 当前绑定到了整条路线id ${route.linkId} " // "局部 当前绑定到了整条路线id ${route.linkId} "
) // )
niMapController.lineHandler.showLine(route.pointList) // niMapController.lineHandler.showLine(route.pointList)
footPoint = GeoPoint( footPoint = GeoPoint(
pointPairDistance.getCoordinate(0).y, pointPairDistance.getCoordinate(0).y,
pointPairDistance.getCoordinate(0).x pointPairDistance.getCoordinate(0).x
) )
val listPoint = mutableListOf(point, footPoint!!) // val listPoint = mutableListOf(point, footPoint!!)
niMapController.lineHandler.showLine( // niMapController.lineHandler.showLine(
listPoint // listPoint
) // )
matchingItem()
if (lastRouteIndex != routeIndex) { if (lastRouteIndex != routeIndex) {
createTempPath() createTempPath()
} }
matchingItem()
errorCount = 0 errorCount = 0
break break
} }
@ -510,31 +494,43 @@ class NaviEngine(val niMapController: NIMapController, val callback: OnNaviEngin
* 匹配要素 * 匹配要素
* @point:定位点 * @point:定位点
*/ */
private fun matchingItem() { private suspend fun matchingItem() {
if (routeIndex > -1 && tempRoutList.isNotEmpty() && tempGeometry != null) { if (routeIndex > -1 && tempRoutList.isNotEmpty() && tempGeometry != null) {
Log.e("jingo", "当前${routeIndex} ${tempRoutList[0].startIndexInPath} $footIndex")
//道路前方一定距离范围内的要素信息 //道路前方一定距离范围内的要素信息
val bindingItemList = mutableListOf<NaviRouteItem>() val bindingItemList = mutableListOf<NaviRouteItem>()
//临时局部路径的游标对应整条路径的游标
val tempFootIndex = footIndex + tempRoutList[0].startIndexInPath
//定位点到要素的路径距离 //定位点到要素的路径距离
var distance = 0.0 var distance = 0.0
//计算要素路径距离的点集合 //计算要素路径距离的点集合
val disPoints = mutableListOf(footPoint!!) val disPoints = mutableListOf(footPoint!!)
//下一个要素的起点游标 //下一个要素的起点游标
var tempIndex = footIndex + 1 var tempIndex = footIndex - tempRoutList[0].startIndexInPath + 1
for(route in tempRoutList) { var currentRoute: NaviRoute? = null
if( route.indexInPath < routeIndex) for (route in tempRoutList) {
// if (route.itemList != null) {
// Log.e("jingo", "${route.linkId}我有${route.itemList!!.size}个要素 ")
// }
if (route.indexInPath < routeIndex)
continue continue
if (route.indexInPath == routeIndex) {
currentRoute = route
}
if (route.itemList != null && route.itemList!!.isNotEmpty()) { if (route.itemList != null && route.itemList!!.isNotEmpty()) {
for (naviItem in route.itemList!!) { for (naviItem in route.itemList!!) {
if (naviItem.index > tempFootIndex) { // Log.e(
// "jingo",
// "我是:${naviItem.data.name} 我的点位 ${naviItem.index} 垂足点位 $footIndex"
// )
if (naviItem.index > footIndex) {
val rightI = naviItem.index - tempRoutList[0].startIndexInPath + 1 val rightI = naviItem.index - tempRoutList[0].startIndexInPath + 1
for (i in tempIndex until rightI) { for (i in tempIndex until rightI) {
val geo = tempGeometry!!.coordinates[i] val geo = tempGeometry!!.coordinates[i]
disPoints.add(GeoPoint(geo.y, geo.x)) disPoints.add(GeoPoint(geo.y, geo.x))
} }
tempIndex = rightI tempIndex = rightI + 1
distance = GeometryTools.getDistance(disPoints) distance = GeometryTools.getDistance(disPoints)
// Log.e("jingo", "我的距离${distance} 下一个${tempIndex} 位置${rightI}")
if (distance < FARTHEST_DISPLAY_DISTANCE && distance > -1) { if (distance < FARTHEST_DISPLAY_DISTANCE && distance > -1) {
naviItem.distance = distance.toInt() naviItem.distance = distance.toInt()
bindingItemList.add(naviItem) bindingItemList.add(naviItem)
@ -543,12 +539,12 @@ class NaviEngine(val niMapController: NIMapController, val callback: OnNaviEngin
} }
} }
} }
if(distance >= FARTHEST_DISPLAY_DISTANCE){ if (distance >= FARTHEST_DISPLAY_DISTANCE) {
break break
} }
} }
} }
callback.bindingResults(bindingItemList) callback.bindingResults(currentRoute, bindingItemList)
} }
} }
@ -601,6 +597,7 @@ class NaviEngine(val niMapController: NIMapController, val callback: OnNaviEngin
private fun deviationUp() { private fun deviationUp() {
errorCount++ errorCount++
if (errorCount >= DEVIATION_COUNT) { if (errorCount >= DEVIATION_COUNT) {
callback.planningPathStatus(NaviStatus.NAVI_STATUS_DISTANCE_OFF)
bindingReset() bindingReset()
} }
} }

2
vtm

@ -1 +1 @@
Subproject commit d31e10f1483d49ecec361b79497394c9b7983687 Subproject commit 39b9993b1cc5257d11c872161812ffe890e44bd9