Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
Conflicts: app/src/main/java/com/navinfo/omqs/util/SignUtil.kt
This commit is contained in:
commit
028fda54b5
@ -34,7 +34,8 @@
|
||||
"name": "道路线",
|
||||
"zoomMin": 15,
|
||||
"zoomMax": 17,
|
||||
"catch":true
|
||||
"catch":true,
|
||||
"checkLinkId": true
|
||||
},
|
||||
"2002": {
|
||||
"table": "OMDB_RD_LINK_FUNCTION_CLASS",
|
||||
@ -262,6 +263,7 @@
|
||||
"code": 3014,
|
||||
"name": "人行横道",
|
||||
"catch":true,
|
||||
"checkLinkId": false,
|
||||
"zoomMin": 18,
|
||||
"zoomMax": 20
|
||||
},
|
||||
|
43
app/src/main/java/com/navinfo/omqs/bean/NaviRoute.kt
Normal file
43
app/src/main/java/com/navinfo/omqs/bean/NaviRoute.kt
Normal file
@ -0,0 +1,43 @@
|
||||
package com.navinfo.omqs.bean
|
||||
|
||||
import com.navinfo.collect.library.data.entity.RenderEntity
|
||||
import com.navinfo.collect.library.utils.GeometryTools
|
||||
import org.oscim.core.GeoPoint
|
||||
|
||||
data class NaviRoute(
|
||||
//我是整条路径中的第几段路径
|
||||
var indexInPath: Int = -1,
|
||||
//link id
|
||||
val linkId: String,
|
||||
//起点id
|
||||
var sNode: String = "",
|
||||
//终点id
|
||||
var eNode: String = "",
|
||||
//方向
|
||||
var direct: Int = 0,
|
||||
//道路名称
|
||||
var name: RenderEntity? = null,
|
||||
//路段总长
|
||||
var length: Double = 0.0,
|
||||
//当前link在整段路径中的起点
|
||||
var startIndexInPath: Int = -1,
|
||||
//当前link在整段路径中的终点
|
||||
var endIndexIntPath: Int = -1,
|
||||
var itemList: MutableList<NaviRouteItem>? = null
|
||||
) {
|
||||
var pointList: MutableList<GeoPoint> = mutableListOf()
|
||||
get() {
|
||||
return field
|
||||
}
|
||||
set(value) {
|
||||
length = GeometryTools.getDistance(value)
|
||||
field = value
|
||||
}
|
||||
}
|
||||
|
||||
data class NaviRouteItem(
|
||||
var index: Int,
|
||||
val data: RenderEntity,
|
||||
val linkId: String,
|
||||
var distance: Int = -1
|
||||
)
|
@ -1,24 +0,0 @@
|
||||
package com.navinfo.omqs.bean
|
||||
|
||||
import com.navinfo.collect.library.utils.GeometryTools
|
||||
import com.navinfo.collect.library.utils.GeometryToolsKt
|
||||
import org.locationtech.jts.geom.Geometry
|
||||
import org.oscim.core.GeoPoint
|
||||
|
||||
data class Route(
|
||||
val linkId: String,
|
||||
var sNode: String = "",
|
||||
var eNode: String = "",
|
||||
var direct: Int = 0,
|
||||
var name: String = "",
|
||||
var length: Double = 0.0,
|
||||
) {
|
||||
var pointList: MutableList<GeoPoint> = mutableListOf()
|
||||
get() {
|
||||
return field
|
||||
}
|
||||
set(value) {
|
||||
length = GeometryTools.getDistance(value)
|
||||
field = value
|
||||
}
|
||||
}
|
@ -201,7 +201,7 @@ class RealmOperateHelper() {
|
||||
var link: RenderEntity? = null
|
||||
val realm = getSelectTaskRealmInstance()
|
||||
val realmR =
|
||||
getSelectTaskRealmTools(RenderEntity::class.java, true).equalTo("table", "OMDB_RD_LINK_KIND")
|
||||
realm.where(RenderEntity::class.java).equalTo("table", "OMDB_RD_LINK_KIND")
|
||||
.equalTo("properties['${LinkTable.linkPid}']", linkPid).findFirst()
|
||||
if (realmR != null) {
|
||||
link = realm.copyFromRealm(realmR)
|
||||
@ -288,14 +288,14 @@ class RealmOperateHelper() {
|
||||
.findAll()
|
||||
} else {
|
||||
// 查询realm中对应tile号的数据
|
||||
if(Constant.CATCH_ALL){
|
||||
if (Constant.CATCH_ALL) {
|
||||
realmList = getSelectTaskRealmTools(RenderEntity::class.java, false)
|
||||
.greaterThanOrEqualTo("tileX", xStart)
|
||||
.lessThanOrEqualTo("tileX", xEnd)
|
||||
.greaterThanOrEqualTo("tileY", yStart)
|
||||
.lessThanOrEqualTo("tileY", yEnd)
|
||||
.findAll()
|
||||
}else{
|
||||
} else {
|
||||
realmList = getSelectTaskRealmTools(RenderEntity::class.java, false)
|
||||
.greaterThanOrEqualTo("tileX", xStart)
|
||||
.lessThanOrEqualTo("tileX", xEnd)
|
||||
|
@ -27,6 +27,7 @@ import com.blankj.utilcode.util.ClipboardUtils
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
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.handler.MeasureLayerHandler
|
||||
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.tools.LayerConfigUtils
|
||||
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.itemlist.ItemListFragment
|
||||
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.widget.RecyclerViewSpacesItemDecoration
|
||||
import com.navinfo.omqs.util.FlowEventBus
|
||||
import com.navinfo.omqs.util.NaviStatus
|
||||
import com.navinfo.omqs.util.SignUtil
|
||||
import com.navinfo.omqs.util.SpeakMode
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
@ -66,6 +69,12 @@ class MainActivity : BaseActivity() {
|
||||
|
||||
private lateinit var binding: ActivityMainBinding
|
||||
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
|
||||
@ -280,11 +289,10 @@ class MainActivity : BaseActivity() {
|
||||
//道路绑定,名称变化
|
||||
viewModel.liveDataRoadName.observe(this) {
|
||||
if (it != null) {
|
||||
binding.mainActivityRoadName.text = it.properties["name"]
|
||||
binding.mainActivityRoadName.visibility = View.VISIBLE
|
||||
binding.mainActivityRoadName.text = it.properties["name"]
|
||||
} else {
|
||||
binding.mainActivityRoadName.text = " "
|
||||
binding.mainActivityRoadName.visibility = View.GONE
|
||||
binding.mainActivityRoadName.visibility = View.INVISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
@ -327,7 +335,7 @@ class MainActivity : BaseActivity() {
|
||||
7, RoundingMode.HALF_UP
|
||||
)
|
||||
},${BigDecimal(it.latitude).setScale(7, RoundingMode.HALF_UP)}"
|
||||
if(Constant.AUTO_LOCATION){
|
||||
if (Constant.AUTO_LOCATION) {
|
||||
viewModel.startAutoLocationTimer()
|
||||
}
|
||||
binding.mainActivityLocation.setImageResource(R.drawable.icon_location)
|
||||
@ -336,8 +344,8 @@ class MainActivity : BaseActivity() {
|
||||
Log.e("qj", "异常 $e")
|
||||
}
|
||||
}
|
||||
viewModel.liveDataAutoLocation.observe(this){
|
||||
if(it==true){
|
||||
viewModel.liveDataAutoLocation.observe(this) {
|
||||
if (it == true) {
|
||||
onClickLocation()
|
||||
}
|
||||
}
|
||||
@ -416,8 +424,59 @@ class MainActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.liveDataMessage.observe(this) {
|
||||
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 -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.liveDataItemList.observe(this) {
|
||||
if(it.isNotEmpty()) {
|
||||
if (it.isNotEmpty()) {
|
||||
if (leftFragment == null || leftFragment !is ItemListFragment) {
|
||||
leftFragment = ItemListFragment {
|
||||
binding.mainActivityLeftFragment.visibility = View.GONE
|
||||
@ -1101,7 +1160,7 @@ class MainActivity : BaseActivity() {
|
||||
* 路径规划
|
||||
*/
|
||||
fun onClickRouteFragment() {
|
||||
Toast.makeText(this, "功能开发中", Toast.LENGTH_SHORT).show()
|
||||
viewModel.planningPath()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,6 +57,7 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.locationtech.jts.geom.Geometry
|
||||
import org.locationtech.jts.geom.LineString
|
||||
import org.oscim.core.GeoPoint
|
||||
import org.oscim.core.MapPosition
|
||||
import org.oscim.map.Map
|
||||
@ -86,7 +87,7 @@ class MainViewModel @Inject constructor(
|
||||
private var mCameraDialog: CommonDialog? = null
|
||||
|
||||
//路径计算
|
||||
val liveDataPlanningPathStatus = MutableLiveData<Int>()
|
||||
val liveDataNaviStatus = MutableLiveData<NaviStatus>()
|
||||
|
||||
//地图点击捕捉到的质检数据ID列表
|
||||
val liveDataQsRecordIdList = MutableLiveData<List<String>>()
|
||||
@ -119,6 +120,12 @@ class MainViewModel @Inject constructor(
|
||||
*/
|
||||
val liveDataItemList = MutableLiveData<List<RenderEntity>>()
|
||||
|
||||
/**
|
||||
* 提示信息
|
||||
*/
|
||||
val liveDataMessage = MutableLiveData<String>()
|
||||
|
||||
|
||||
private var traceTag: String = "TRACE_TAG"
|
||||
|
||||
/**
|
||||
@ -196,9 +203,11 @@ class MainViewModel @Inject constructor(
|
||||
/**
|
||||
* 测量类型
|
||||
*/
|
||||
var measuringType: MeasureLayerHandler.MEASURE_TYPE =
|
||||
MeasureLayerHandler.MEASURE_TYPE.DISTANCE
|
||||
var measuringType: MeasureLayerHandler.MEASURE_TYPE = MeasureLayerHandler.MEASURE_TYPE.DISTANCE
|
||||
|
||||
/**
|
||||
* 捕捉到的上一条link
|
||||
*/
|
||||
var linkIdCache = ""
|
||||
|
||||
private var lastNiLocaion: NiLocation? = null
|
||||
@ -223,20 +232,19 @@ class MainViewModel @Inject constructor(
|
||||
private var currentMapZoomLevel: Int = 0
|
||||
|
||||
//导航信息
|
||||
private var naviEngine: NaviEngine = NaviEngine()
|
||||
private var naviEngine: NaviEngine? = null
|
||||
|
||||
// 0:不导航 1:导航 2:暂停
|
||||
private var naviEngineStatus = 0
|
||||
|
||||
// 定义一个互斥锁
|
||||
private val naviMutex = Mutex()
|
||||
|
||||
|
||||
init {
|
||||
|
||||
|
||||
mapController.mMapView.vtmMap.events.bind(Map.UpdateListener { e, mapPosition ->
|
||||
when (e) {
|
||||
Map.SCALE_EVENT, Map.MOVE_EVENT, Map.ROTATE_EVENT -> liveDataCenterPoint.value =
|
||||
mapPosition
|
||||
//Map.CLEAR_EVENT->startAutoLocationTimer()
|
||||
}
|
||||
|
||||
currentMapZoomLevel = mapController.mMapView.vtmMap.mapPosition.zoomLevel
|
||||
@ -253,8 +261,7 @@ class MainViewModel @Inject constructor(
|
||||
/**
|
||||
* 处理点击道路捕捉回调功能
|
||||
*/
|
||||
mapController.mMapView.addOnNIMapClickListener(
|
||||
TAG,
|
||||
mapController.mMapView.addOnNIMapClickListener(TAG,
|
||||
//处理地图点击操作
|
||||
object : OnGeoPointClickListener {
|
||||
override fun onMapClick(tag: String, point: GeoPoint) {
|
||||
@ -279,8 +286,7 @@ class MainViewModel @Inject constructor(
|
||||
*/
|
||||
object : OnQsRecordItemClickListener {
|
||||
override fun onQsRecordList(tag: String, list: MutableList<String>) {
|
||||
if (tag == TAG)
|
||||
liveDataQsRecordIdList.value = list
|
||||
if (tag == TAG) liveDataQsRecordIdList.value = list
|
||||
}
|
||||
},
|
||||
/**
|
||||
@ -288,8 +294,7 @@ class MainViewModel @Inject constructor(
|
||||
*/
|
||||
object : OnTaskLinkItemClickListener {
|
||||
override fun onTaskLink(tag: String, taskLinkId: String) {
|
||||
if (tag == TAG)
|
||||
liveDataTaskLink.value = taskLinkId
|
||||
if (tag == TAG) liveDataTaskLink.value = taskLinkId
|
||||
}
|
||||
},
|
||||
/**
|
||||
@ -297,8 +302,7 @@ class MainViewModel @Inject constructor(
|
||||
*/
|
||||
object : ONNoteItemClickListener {
|
||||
override fun onNote(tag: String, noteId: String) {
|
||||
if (tag == TAG)
|
||||
liveDataNoteId.value = noteId
|
||||
if (tag == TAG) liveDataNoteId.value = noteId
|
||||
}
|
||||
|
||||
},
|
||||
@ -307,11 +311,9 @@ class MainViewModel @Inject constructor(
|
||||
*/
|
||||
object : OnNiLocationItemListener {
|
||||
override fun onNiLocation(tag: String, index: Int, it: NiLocation) {
|
||||
if (tag == TAG)
|
||||
liveDataNILocationList.value = it
|
||||
if (tag == TAG) liveDataNILocationList.value = it
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
getTaskBean()
|
||||
@ -335,43 +337,26 @@ class MainViewModel @Inject constructor(
|
||||
socketServer = SocketServer(mapController, traceDataBase, sharedPreferences)
|
||||
|
||||
// viewModelScope.launch(Dispatchers.Default) {
|
||||
// naviTestFlow().collect {
|
||||
// naviMutex.lock()
|
||||
// if (naviEngine.geometry != null) {
|
||||
// //定义垂线
|
||||
// val pointPairDistance = PointPairDistance()
|
||||
// val coordinate = Coordinate(it.longitude, it.latitude)
|
||||
// DistanceToPoint.computeDistance(
|
||||
// naviEngine.geometry,
|
||||
// coordinate,
|
||||
// pointPairDistance
|
||||
// )
|
||||
// if (pointPairDistance.getCoordinate(0) !== null) {
|
||||
// val line = GeometryTools.createLineString(
|
||||
// mutableListOf(
|
||||
// it,
|
||||
// GeoPoint(
|
||||
// pointPairDistance.getCoordinate(0).y,
|
||||
// pointPairDistance.getCoordinate(0).x
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// mapController.lineHandler.showLine(line.toText())
|
||||
// naviTestFlow().collect { point ->
|
||||
// if (naviEngineStatus == 1) {
|
||||
// naviEngine?.let {
|
||||
// naviMutex.lock()
|
||||
// it.bindingRoute(null, point)
|
||||
// naviMutex.unlock()
|
||||
// }
|
||||
// }
|
||||
// naviMutex.unlock()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
fun naviTestFlow(): Flow<GeoPoint> = flow {
|
||||
|
||||
while (true) {
|
||||
emit(mapController.mMapView.vtmMap.mapPosition.geoPoint)
|
||||
delay(1000)
|
||||
}
|
||||
}
|
||||
// fun naviTestFlow(): Flow<GeoPoint> = flow {
|
||||
//
|
||||
// while (true) {
|
||||
// emit(mapController.mMapView.vtmMap.mapPosition.geoPoint)
|
||||
// delay(1000)
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 获取当前任务
|
||||
@ -382,147 +367,70 @@ class MainViewModel @Inject constructor(
|
||||
val res = realm.where(TaskBean::class.java).equalTo("id", id).findFirst()
|
||||
if (res != null) {
|
||||
currentTaskBean = realm.copyFromRealm(res)
|
||||
//planningPath(currentTaskBean!!)
|
||||
}
|
||||
realm.close()
|
||||
}
|
||||
|
||||
/**
|
||||
* 规划路径
|
||||
*/
|
||||
fun planningPath() {
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
naviMutex.lock()
|
||||
getTaskBean()
|
||||
if (currentTaskBean != null && currentTaskBean!!.status == FileManager.Companion.FileDownloadStatus.DONE) {
|
||||
naviEngine = NaviEngine(niMapController = mapController,
|
||||
realmOperateHelper = realmOperateHelper,
|
||||
callback = object : OnNaviEngineCallbackListener {
|
||||
|
||||
private fun planningPath(taskBean: TaskBean) {
|
||||
if (taskBean.status == FileManager.Companion.FileDownloadStatus.DONE) {
|
||||
// Toast.makeText(context, "正在计算导航路径", Toast.LENGTH_SHORT).show()
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
naviMutex.lock()
|
||||
naviEngine = NaviEngine()
|
||||
val pathList = mutableListOf<Route>()
|
||||
val realm = realmOperateHelper.getSelectTaskRealmInstance()
|
||||
for (link in taskBean.hadLinkDvoList) {
|
||||
//测线不参与导航
|
||||
if (link.linkStatus == 3) {
|
||||
continue
|
||||
}
|
||||
val route = Route(
|
||||
linkId = link.linkPid,
|
||||
)
|
||||
route.pointList = GeometryTools.getGeoPoints(link.geometry)
|
||||
//查询每条link的snode,enode
|
||||
val res1 = realm.where(RenderEntity::class.java)
|
||||
.equalTo("table", DataCodeEnum.OMDB_RD_LINK_KIND.name).and()
|
||||
.equalTo("properties['linkPid']", link.linkPid).findFirst()
|
||||
res1?.let {
|
||||
override fun planningPathStatus(status: NaviStatus) {
|
||||
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)
|
||||
}
|
||||
|
||||
val snodePid = it.properties["snodePid"]
|
||||
if (snodePid != null) {
|
||||
route.sNode = snodePid
|
||||
}
|
||||
val enodePid = it.properties["enodePid"]
|
||||
if (enodePid != null) {
|
||||
route.eNode = enodePid
|
||||
}
|
||||
}
|
||||
//查询每条link的方向
|
||||
val res2 = realm.where(RenderEntity::class.java)
|
||||
.equalTo("table", DataCodeEnum.OMDB_LINK_DIRECT.name).and()
|
||||
.equalTo("properties['linkPid']", link.linkPid).findFirst()
|
||||
res2?.let {
|
||||
val direct = it.properties["direct"]
|
||||
if (direct != null) {
|
||||
route.direct = direct.toInt()
|
||||
}
|
||||
}
|
||||
//查询每条link的名称
|
||||
val res3 = realm.where(RenderEntity::class.java)
|
||||
.equalTo("table", DataCodeEnum.OMDB_LINK_NAME.name).and()
|
||||
.equalTo("properties['linkPid']", link.linkPid).findFirst()
|
||||
res3?.let {
|
||||
route.name = "${it.properties["name"]}"
|
||||
}
|
||||
pathList.add(route)
|
||||
}
|
||||
realm.close()
|
||||
//用来存储最终的导航路径
|
||||
val newRouteList = mutableListOf<Route>()
|
||||
//比对路径排序用的
|
||||
val tempRouteList = pathList.toMutableList()
|
||||
//先找到一根有方向的link,确定起终点
|
||||
var routeStart: Route? = null
|
||||
for (i in tempRouteList.indices) {
|
||||
val route = pathList[i]
|
||||
//只要时单方向的就行
|
||||
if (route.direct == 2 || route.direct == 3) {
|
||||
routeStart = route
|
||||
tempRouteList.removeAt(i)
|
||||
break
|
||||
}
|
||||
}
|
||||
if (routeStart != null) {
|
||||
var sNode = ""
|
||||
var eNode = ""
|
||||
//如果snode,enode是顺方向,geometry 不动,否则反转
|
||||
if (routeStart.direct == 3) {
|
||||
routeStart.pointList.reverse()
|
||||
sNode = routeStart.eNode
|
||||
eNode = routeStart.sNode
|
||||
} else {
|
||||
sNode = routeStart.sNode
|
||||
eNode = routeStart.eNode
|
||||
}
|
||||
newRouteList.add(routeStart)
|
||||
var bBreak = true
|
||||
while (bBreak) {
|
||||
//先找其实link的后续link
|
||||
var bHasNext = false
|
||||
for (route in tempRouteList) {
|
||||
//如果是link 的e 对下个link的s,方向不用动,否则下个link的geometry反转
|
||||
if (route.sNode != "" && eNode == route.sNode) {
|
||||
newRouteList.add(route)
|
||||
tempRouteList.remove(route)
|
||||
eNode = route.eNode
|
||||
bHasNext = true
|
||||
break
|
||||
} else if (route.eNode != "" && eNode == route.eNode) {
|
||||
route.pointList.reverse()
|
||||
newRouteList.add(route)
|
||||
tempRouteList.remove(route)
|
||||
eNode = route.sNode
|
||||
bHasNext = true
|
||||
break
|
||||
override suspend fun bindingResults(
|
||||
route: NaviRoute?,
|
||||
list: List<NaviRouteItem>
|
||||
) {
|
||||
val signList = mutableListOf<SignBean>()
|
||||
for (naviRouteItem in list) {
|
||||
|
||||
val signBean = SignBean(
|
||||
iconId = SignUtil.getSignIcon(naviRouteItem.data),
|
||||
iconText = SignUtil.getSignIconText(naviRouteItem.data),
|
||||
linkId = naviRouteItem.linkId,
|
||||
distance = naviRouteItem.distance,
|
||||
name = SignUtil.getSignNameText(naviRouteItem.data),
|
||||
bottomRightText = SignUtil.getSignBottomRightText(
|
||||
naviRouteItem.data
|
||||
),
|
||||
renderEntity = naviRouteItem.data,
|
||||
isMoreInfo = SignUtil.isMoreInfo(naviRouteItem.data),
|
||||
index = SignUtil.getRoadInfoIndex(naviRouteItem.data)
|
||||
)
|
||||
signList.add(signBean)
|
||||
}
|
||||
}
|
||||
//先找其实link的起始link
|
||||
var bHasLast = false
|
||||
for (route in tempRouteList) {
|
||||
//如果是link 的s 对上个link的e,方向不用动,否则下个link的geometry反转
|
||||
if (route.eNode != "" && sNode == route.eNode) {
|
||||
newRouteList.add(0, route)
|
||||
tempRouteList.remove(route)
|
||||
sNode = route.sNode
|
||||
bHasLast = true
|
||||
break
|
||||
} else if (route.sNode != "" && sNode == route.sNode) {
|
||||
route.pointList.reverse()
|
||||
newRouteList.add(0, route)
|
||||
tempRouteList.remove(route)
|
||||
sNode = route.eNode
|
||||
bHasLast = true
|
||||
break
|
||||
if (route != null) {
|
||||
liveDataRoadName.postValue(route.name)
|
||||
captureTopSign(route)
|
||||
}
|
||||
liveDataSignList.postValue(signList)
|
||||
}
|
||||
if (tempRouteList.size == 0) {
|
||||
bBreak = false
|
||||
} else {
|
||||
if (!bHasLast && !bHasNext) {
|
||||
bBreak = false
|
||||
//TODO 处理错误,路径不完整
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
naviEngine.routeList = newRouteList
|
||||
naviMutex.unlock()
|
||||
})
|
||||
naviEngine!!.planningPath(currentTaskBean!!)
|
||||
} else {
|
||||
liveDataMessage.postValue("请先安装任务数据")
|
||||
}
|
||||
} else {
|
||||
// Toast.makeText(context, "数据未安装,无法计算导航路径", Toast.LENGTH_SHORT).show()
|
||||
naviMutex.unlock()
|
||||
}
|
||||
}
|
||||
|
||||
@ -530,8 +438,11 @@ class MainViewModel @Inject constructor(
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
||||
if (key == Constant.SELECT_TASK_ID) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
naviMutex.lock()
|
||||
naviEngineStatus = 0
|
||||
getTaskBean()
|
||||
initQsRecordData()
|
||||
naviMutex.unlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -544,8 +455,7 @@ class MainViewModel @Inject constructor(
|
||||
var list = mutableListOf<QsRecordBean>()
|
||||
val realm = realmOperateHelper.getRealmDefaultInstance()
|
||||
realm.executeTransaction {
|
||||
val objects =
|
||||
realmOperateHelper.getRealmTools(QsRecordBean::class.java).findAll()
|
||||
val objects = realmOperateHelper.getRealmTools(QsRecordBean::class.java).findAll()
|
||||
list = realm.copyFromRealm(objects)
|
||||
}
|
||||
realm.close()
|
||||
@ -634,8 +544,10 @@ class MainViewModel @Inject constructor(
|
||||
//增加间距判断
|
||||
if (lastNiLocaion != null) {
|
||||
disance = GeometryTools.getDistance(
|
||||
location.latitude, location.longitude,
|
||||
lastNiLocaion!!.latitude, lastNiLocaion!!.longitude
|
||||
location.latitude,
|
||||
location.longitude,
|
||||
lastNiLocaion!!.latitude,
|
||||
lastNiLocaion!!.longitude
|
||||
)
|
||||
}
|
||||
//室内整理工具时不能进行轨迹存储,判断轨迹间隔要超过2.5并小于60米
|
||||
@ -649,18 +561,30 @@ class MainViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 导航预警信息
|
||||
*/
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
//用于定位点捕捉道路
|
||||
mapController.locationLayerHandler.niLocationFlow.collectLatest { location ->
|
||||
|
||||
if (!isSelectRoad() && !GeometryTools.isCheckError(
|
||||
location.longitude, location.latitude
|
||||
)
|
||||
) {
|
||||
captureLink(
|
||||
GeoPoint(
|
||||
location.latitude, location.longitude
|
||||
if (naviEngine != null && naviEngineStatus == 1) {
|
||||
naviMutex.lock()
|
||||
val point = GeoPoint(location.latitude, location.longitude)
|
||||
naviEngine!!.bindingRoute(location, point)
|
||||
naviMutex.unlock()
|
||||
} else {
|
||||
captureLink(
|
||||
GeoPoint(
|
||||
location.latitude, location.longitude
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -675,18 +599,17 @@ class MainViewModel @Inject constructor(
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
val itemList = realmOperateHelper.queryElement(
|
||||
GeometryTools.createPoint(
|
||||
point.longitude,
|
||||
point.latitude
|
||||
point.longitude, point.latitude
|
||||
),
|
||||
buffer = 3.2, catchAll = false,
|
||||
)
|
||||
//增加道路线过滤原则
|
||||
val filterResult = itemList.filter {
|
||||
if(isHighRoad()){
|
||||
mapController.mMapView.mapLevel>=it.zoomMin&&mapController.mMapView.mapLevel<=it.zoomMax
|
||||
}else{
|
||||
if (isHighRoad()) {
|
||||
mapController.mMapView.mapLevel >= it.zoomMin && mapController.mMapView.mapLevel <= it.zoomMax
|
||||
} else {
|
||||
//关闭时过滤道路线捕捉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()
|
||||
if (filterResult.size == 1) {
|
||||
@ -697,10 +620,114 @@ 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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 捕获道路和面板
|
||||
*/
|
||||
private suspend fun captureLink(point: GeoPoint) {
|
||||
|
||||
if (captureLinkState) {
|
||||
return
|
||||
}
|
||||
@ -715,44 +742,52 @@ class MainViewModel @Inject constructor(
|
||||
var hisRoadName = false
|
||||
|
||||
if (linkList.isNotEmpty()) {
|
||||
val link = linkList[0]
|
||||
val linkId = link.properties[RenderEntity.Companion.LinkTable.linkPid]
|
||||
//看板数据
|
||||
val signList = mutableListOf<SignBean>()
|
||||
val topSignList = mutableListOf<SignBean>()
|
||||
mapController.lineHandler.linksLayer.clear()
|
||||
|
||||
val link = linkList[0]
|
||||
|
||||
val linkId = link.properties[RenderEntity.Companion.LinkTable.linkPid]
|
||||
|
||||
if (linkIdCache != linkId) {
|
||||
|
||||
if (bSelectRoad)
|
||||
mapController.markerHandle.addMarker(point, "selectLink")
|
||||
mapController.lineHandler.showLine(link.geometry)
|
||||
val lineString: Geometry = GeometryTools.createGeometry(link.geometry)
|
||||
val footAndDistance = GeometryTools.pointToLineDistance(point, lineString)
|
||||
val linePoints = GeometryTools.getGeoPoints(link.geometry)
|
||||
linePoints.add(
|
||||
footAndDistance.footIndex + 1,
|
||||
GeoPoint(
|
||||
footAndDistance.getCoordinate(0).y,
|
||||
footAndDistance.getCoordinate(0).x
|
||||
)
|
||||
)
|
||||
val newLineString = GeometryTools.createLineString(linePoints)
|
||||
linkId?.let {
|
||||
var elementList = realmOperateHelper.queryLinkByLinkPid(it)
|
||||
for (element in elementList) {
|
||||
|
||||
if (element.code == DataCodeEnum.OMDB_LINK_NAME.code) {
|
||||
hisRoadName = true
|
||||
liveDataRoadName.postValue(element)
|
||||
continue
|
||||
}
|
||||
|
||||
val distance = GeometryTools.distanceToDouble(
|
||||
point, GeometryTools.createGeoPoint(element.geometry)
|
||||
)
|
||||
|
||||
val signBean = SignBean(
|
||||
iconId = SignUtil.getSignIcon(element),
|
||||
iconText = SignUtil.getSignIconText(element),
|
||||
distance = distance.toInt(),
|
||||
linkId = linkId,
|
||||
name = SignUtil.getSignNameText(element),
|
||||
bottomRightText = SignUtil.getSignBottomRightText(element),
|
||||
renderEntity = element,
|
||||
isMoreInfo = SignUtil.isMoreInfo(element),
|
||||
index = SignUtil.getRoadInfoIndex(element)
|
||||
index = SignUtil.getRoadInfoIndex(element),
|
||||
distance = SignUtil.getDistance(
|
||||
footAndDistance,
|
||||
newLineString,
|
||||
element
|
||||
)
|
||||
)
|
||||
Log.e("jingo", "捕捉到的数据code ${element.code}")
|
||||
// Log.e("jingo", "捕捉到的数据code ${element.code}")
|
||||
when (element.code) {
|
||||
DataCodeEnum.OMDB_MULTI_DIGITIZED.code,//上下线分离
|
||||
DataCodeEnum.OMDB_CON_ACCESS.code,//全封闭
|
||||
@ -797,7 +832,6 @@ class MainViewModel @Inject constructor(
|
||||
-> topSignList.add(
|
||||
signBean
|
||||
)
|
||||
|
||||
DataCodeEnum.OMDB_SPEEDLIMIT.code,//常规点限速
|
||||
DataCodeEnum.OMDB_SPEEDLIMIT_COND.code,//条件点限速
|
||||
DataCodeEnum.OMDB_SPEEDLIMIT_VAR.code,//可变点限速
|
||||
@ -806,26 +840,23 @@ class MainViewModel @Inject constructor(
|
||||
DataCodeEnum.OMDB_LANEINFO.code,//车信
|
||||
DataCodeEnum.OMDB_WARNINGSIGN.code,//危险信息
|
||||
DataCodeEnum.OMDB_TOLLGATE.code,//收费站
|
||||
-> signList.add(
|
||||
signBean
|
||||
)
|
||||
-> {
|
||||
signList.add(
|
||||
signBean
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
val realm = realmOperateHelper.getSelectTaskRealmInstance()
|
||||
|
||||
val entityList =
|
||||
realmOperateHelper.getSelectTaskRealmTools(
|
||||
RenderEntity::class.java,
|
||||
true
|
||||
)
|
||||
.and()
|
||||
.equalTo("table", DataCodeEnum.OMDB_RESTRICTION.name)
|
||||
.and()
|
||||
.equalTo(
|
||||
"properties['linkIn']", it
|
||||
).findAll()
|
||||
val entityList = realmOperateHelper.getSelectTaskRealmTools(
|
||||
RenderEntity::class.java, true
|
||||
).and().equalTo("table", DataCodeEnum.OMDB_RESTRICTION.name).and()
|
||||
.equalTo(
|
||||
"properties['linkIn']", it
|
||||
).findAll()
|
||||
if (entityList.isNotEmpty()) {
|
||||
val outList = entityList.distinct()
|
||||
for (i in outList.indices) {
|
||||
@ -835,7 +866,8 @@ class MainViewModel @Inject constructor(
|
||||
RenderEntity::class.java,
|
||||
true
|
||||
)
|
||||
.equalTo("table", DataCodeEnum.OMDB_RD_LINK_KIND.name).and()
|
||||
.equalTo("table", DataCodeEnum.OMDB_RD_LINK_KIND.name)
|
||||
.and()
|
||||
.equalTo(
|
||||
"properties['${RenderEntity.Companion.LinkTable.linkPid}']",
|
||||
outLink
|
||||
@ -847,8 +879,7 @@ class MainViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
mapController.lineHandler.linksLayer.addLine(
|
||||
link.geometry,
|
||||
Color.BLUE
|
||||
link.geometry, Color.BLUE
|
||||
)
|
||||
realm.close()
|
||||
}
|
||||
@ -1029,7 +1060,7 @@ class MainViewModel @Inject constructor(
|
||||
* */
|
||||
fun refreshOMDBLayer(layerConfigList: List<ImportConfig>) {
|
||||
// 根据获取到的配置信息,筛选未勾选的图层名称
|
||||
if (layerConfigList != null && !layerConfigList.isEmpty()) {
|
||||
if (layerConfigList != null && layerConfigList.isNotEmpty()) {
|
||||
val omdbVisibleList = mutableListOf<String>()
|
||||
layerConfigList.forEach {
|
||||
omdbVisibleList.addAll(it.tableMap.filter { entry ->
|
||||
@ -1057,6 +1088,12 @@ class MainViewModel @Inject constructor(
|
||||
linkIdCache = ""
|
||||
mapController.lineHandler.removeLine()
|
||||
liveDataSignList.value = mutableListOf()
|
||||
mapController.markerHandle.removeMarker("selectLink")
|
||||
if (bSelectRoad && naviEngineStatus == 1) {
|
||||
naviEngineStatus = 2
|
||||
} else if (naviEngineStatus == 2) {
|
||||
naviEngineStatus = 1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1146,9 +1183,7 @@ class MainViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
fun sendServerCommand(
|
||||
context: Context,
|
||||
traceVideoBean: TraceVideoBean,
|
||||
indoorToolsCommand: IndoorToolsCommand
|
||||
context: Context, traceVideoBean: TraceVideoBean, indoorToolsCommand: IndoorToolsCommand
|
||||
) {
|
||||
|
||||
if (TextUtils.isEmpty(Constant.INDOOR_IP)) {
|
||||
@ -1162,8 +1197,7 @@ class MainViewModel @Inject constructor(
|
||||
val url = "http://${Constant.INDOOR_IP}:8080/sensor/service/${traceVideoBean.command}?"
|
||||
|
||||
when (val result = networkService.sendServerCommand(
|
||||
url = url,
|
||||
traceVideoBean = traceVideoBean
|
||||
url = url, traceVideoBean = traceVideoBean
|
||||
)) {
|
||||
is NetResult.Success<*> -> {
|
||||
|
||||
@ -1176,9 +1210,7 @@ class MainViewModel @Inject constructor(
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
"命令成功。",
|
||||
Toast.LENGTH_LONG
|
||||
context, "命令成功。", Toast.LENGTH_LONG
|
||||
).show()
|
||||
|
||||
liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_SUCCESS)
|
||||
@ -1188,8 +1220,7 @@ class MainViewModel @Inject constructor(
|
||||
//启动双向控制服务
|
||||
if (socketServer != null && socketServer!!.isServerClose) {
|
||||
socketServer!!.connect(
|
||||
Constant.INDOOR_IP,
|
||||
this@MainViewModel
|
||||
Constant.INDOOR_IP, this@MainViewModel
|
||||
)
|
||||
}
|
||||
|
||||
@ -1200,8 +1231,7 @@ class MainViewModel @Inject constructor(
|
||||
context,
|
||||
"命令无效${defaultUserResponse.errmsg}",
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
.show()
|
||||
).show()
|
||||
}
|
||||
liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_FAILURE)
|
||||
}
|
||||
@ -1209,9 +1239,7 @@ class MainViewModel @Inject constructor(
|
||||
} catch (e: IOException) {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
"${e.message}",
|
||||
Toast.LENGTH_SHORT
|
||||
context, "${e.message}", Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
@ -1221,11 +1249,8 @@ class MainViewModel @Inject constructor(
|
||||
is NetResult.Error<*> -> {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
"${result.exception.message}",
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
.show()
|
||||
context, "${result.exception.message}", Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_FAILURE)
|
||||
}
|
||||
@ -1233,11 +1258,8 @@ class MainViewModel @Inject constructor(
|
||||
is NetResult.Failure<*> -> {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
"${result.code}:${result.msg}",
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
.show()
|
||||
context, "${result.code}:${result.msg}", Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_FAILURE)
|
||||
}
|
||||
@ -1260,8 +1282,7 @@ class MainViewModel @Inject constructor(
|
||||
if (niLocation != null) {
|
||||
mapController.markerHandle.addMarker(
|
||||
GeoPoint(
|
||||
niLocation.latitude,
|
||||
niLocation.longitude
|
||||
niLocation.latitude, niLocation.longitude
|
||||
), traceTag, "", niLocation as java.lang.Object
|
||||
)
|
||||
}
|
||||
@ -1299,9 +1320,7 @@ class MainViewModel @Inject constructor(
|
||||
override fun onConnect(success: Boolean) {
|
||||
if (!success && socketServer != null) {
|
||||
BaseToast.makeText(
|
||||
mapController.mMapView.context,
|
||||
"轨迹反向控制服务失败,请确认连接是否正常!",
|
||||
Toast.LENGTH_SHORT
|
||||
mapController.mMapView.context, "轨迹反向控制服务失败,请确认连接是否正常!", Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
@ -1330,9 +1349,7 @@ class MainViewModel @Inject constructor(
|
||||
Log.e("qj", "反向控制$currentIndexNiLocation")
|
||||
} else {
|
||||
BaseToast.makeText(
|
||||
mapController.mMapView.context,
|
||||
"没有找到对应轨迹点!",
|
||||
Toast.LENGTH_SHORT
|
||||
mapController.mMapView.context, "没有找到对应轨迹点!", Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
@ -1376,8 +1393,7 @@ class MainViewModel @Inject constructor(
|
||||
startTimer()
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(mapController.mMapView.context, "无数据了!", Toast.LENGTH_LONG)
|
||||
.show()
|
||||
Toast.makeText(mapController.mMapView.context, "无数据了!", Toast.LENGTH_LONG).show()
|
||||
cancelTrace()
|
||||
}
|
||||
}
|
||||
@ -1394,13 +1410,13 @@ class MainViewModel @Inject constructor(
|
||||
/**
|
||||
* 开启自动定位
|
||||
*/
|
||||
fun startAutoLocationTimer(){
|
||||
fun startAutoLocationTimer() {
|
||||
if (autoLocationTimer != null) {
|
||||
cancelAutoLocation()
|
||||
}
|
||||
autoLocationTimer = fixedRateTimer("", false, disAutoLocationTime, disAutoLocationTime) {
|
||||
liveDataAutoLocation.postValue(true)
|
||||
Log.e("qj","自动定位开始执行")
|
||||
Log.e("qj", "自动定位开始执行")
|
||||
startAutoLocationTimer()
|
||||
}
|
||||
}
|
||||
@ -1473,9 +1489,7 @@ class MainViewModel @Inject constructor(
|
||||
} else {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
mapController.mMapView.context,
|
||||
"未查询到数据",
|
||||
Toast.LENGTH_SHORT
|
||||
mapController.mMapView.context, "未查询到数据", Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
@ -1498,9 +1512,7 @@ class MainViewModel @Inject constructor(
|
||||
} else {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
mapController.mMapView.context,
|
||||
"未查询到数据",
|
||||
Toast.LENGTH_SHORT
|
||||
mapController.mMapView.context, "未查询到数据", Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
@ -1517,9 +1529,7 @@ class MainViewModel @Inject constructor(
|
||||
dialog.dismiss()
|
||||
} else {
|
||||
Toast.makeText(
|
||||
mapController.mMapView.context,
|
||||
"输入格式不正确",
|
||||
Toast.LENGTH_SHORT
|
||||
mapController.mMapView.context, "输入格式不正确", Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
@ -79,6 +79,7 @@ class SignAdapter(private var listener: OnSignAdapterClickListener?) :
|
||||
val bd = holder.viewBinding
|
||||
|
||||
if (item.iconId != 0) {
|
||||
bd.signMainIconBg.visibility = View.VISIBLE
|
||||
if (item.renderEntity.code == DataCodeEnum.OMDB_WARNINGSIGN.code) {
|
||||
try {
|
||||
var typeCode = "${item.iconId}"
|
||||
@ -110,6 +111,8 @@ class SignAdapter(private var listener: OnSignAdapterClickListener?) :
|
||||
} else {
|
||||
bd.signMainIconBg.setImageResource(item.iconId)
|
||||
}
|
||||
}else{
|
||||
bd.signMainIconBg.visibility = View.INVISIBLE
|
||||
}
|
||||
|
||||
bd.signMainIcon.text = item.iconText
|
||||
@ -128,6 +131,7 @@ class SignAdapter(private var listener: OnSignAdapterClickListener?) :
|
||||
} else {
|
||||
bd.signMainInfo.visibility = View.GONE
|
||||
}
|
||||
bd.signDistanceText.text = "${item.distance}米"
|
||||
bd.signSecondIcon.text = ""
|
||||
if (item.renderEntity.code == DataCodeEnum.OMDB_SPEEDLIMIT.code) {
|
||||
val minSpeed = SignUtil.getSpeedLimitMinText(item.renderEntity)
|
||||
@ -143,7 +147,7 @@ class SignAdapter(private var listener: OnSignAdapterClickListener?) :
|
||||
val bd = holder.viewBinding
|
||||
bd.signMoreIconsLayout.removeAllViews()
|
||||
bd.signBottomText.text = item.name
|
||||
bd.signBottomRightText.text = item.distance.toString()
|
||||
bd.signBottomRightText.text = "${item.distance}米"
|
||||
val list = SignUtil.getLineInfoIcons(item.renderEntity)
|
||||
val lineViewS = View(context)
|
||||
lineViewS.layoutParams = ViewGroup.LayoutParams(24, 80)
|
||||
@ -215,13 +219,13 @@ class SignAdapter(private var listener: OnSignAdapterClickListener?) :
|
||||
holder.tag = item.name + position
|
||||
}
|
||||
|
||||
override fun refreshData(newData: List<SignBean>) {
|
||||
super.refreshData(newData)
|
||||
for (i in newData.indices) {
|
||||
if (selectMoreInfoTag == newData[i].name + i) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
// override fun refreshData(newData: List<SignBean>) {
|
||||
// super.refreshData(newData)
|
||||
//// ?这是要干嘛 for (i in newData.indices) {
|
||||
//// if (selectMoreInfoTag == newData[i].name + i) {
|
||||
//// return
|
||||
//// }
|
||||
//// }
|
||||
// }
|
||||
|
||||
}
|
@ -166,7 +166,7 @@ class PersonalCenterFragment(private var indoorDataListener: ((Boolean) -> Unit?
|
||||
// 定位到指定位置
|
||||
niMapController.mMapView.vtmMap.animator()
|
||||
// .animateTo(GeoPoint( 40.05108004733645, 116.29187746293708 ))
|
||||
.animateTo(GeoPoint(40.09848700000006, 116.53088699999999))
|
||||
.animateTo(GeoPoint(40.09819324139729,116.53123207733361 ))
|
||||
}
|
||||
|
||||
R.id.personal_center_menu_open_all_layer -> {
|
||||
|
@ -152,6 +152,7 @@ class TaskListAdapter(
|
||||
if (taskBean.status == FileDownloadStatus.DONE) {
|
||||
binding.taskDownloadBtn.visibility = View.INVISIBLE
|
||||
binding.taskUploadBtn.visibility = View.VISIBLE
|
||||
|
||||
} else {
|
||||
binding.taskDownloadBtn.visibility = View.VISIBLE
|
||||
binding.taskUploadBtn.visibility = View.INVISIBLE
|
||||
|
@ -7,6 +7,7 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
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.taskupload.TaskUploadManager
|
||||
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.other.shareViewModels
|
||||
import com.yanzhenjie.recyclerview.SwipeMenuCreator
|
||||
@ -58,9 +61,6 @@ class TaskListFragment : BaseFragment() {
|
||||
Toast.makeText(context, "正在校验", Toast.LENGTH_SHORT).show()
|
||||
viewModel.checkUploadTask(binding.root.context, taskBean)
|
||||
}
|
||||
else -> {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,18 +12,15 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.navinfo.collect.library.data.dao.impl.TraceDataBase
|
||||
import com.navinfo.collect.library.data.entity.*
|
||||
import com.navinfo.collect.library.enums.DataCodeEnum
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import com.navinfo.collect.library.map.OnGeoPointClickListener
|
||||
import com.navinfo.collect.library.utils.GeometryTools
|
||||
import com.navinfo.collect.library.utils.MapParamUtils
|
||||
import com.navinfo.omqs.Constant
|
||||
import com.navinfo.omqs.bean.Route
|
||||
import com.navinfo.omqs.db.RealmOperateHelper
|
||||
import com.navinfo.omqs.http.NetResult
|
||||
import com.navinfo.omqs.http.NetworkService
|
||||
import com.navinfo.omqs.tools.FileManager
|
||||
import com.navinfo.omqs.ui.activity.login.LoginStatus
|
||||
import com.navinfo.omqs.ui.dialog.FirstDialog
|
||||
import com.navinfo.omqs.util.DateTimeUtil
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
|
@ -1,25 +1,623 @@
|
||||
package com.navinfo.omqs.util
|
||||
|
||||
import android.util.Log
|
||||
import com.navinfo.collect.library.data.entity.NiLocation
|
||||
import com.navinfo.collect.library.data.entity.RenderEntity
|
||||
import com.navinfo.collect.library.data.entity.TaskBean
|
||||
import com.navinfo.collect.library.enums.DataCodeEnum
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import com.navinfo.collect.library.utils.GeometryTools
|
||||
import com.navinfo.omqs.bean.Route
|
||||
import com.navinfo.omqs.bean.NaviRoute
|
||||
import com.navinfo.omqs.bean.NaviRouteItem
|
||||
import com.navinfo.omqs.db.RealmOperateHelper
|
||||
import io.realm.Realm
|
||||
import org.locationtech.jts.geom.LineString
|
||||
import org.locationtech.jts.geom.Point
|
||||
import org.oscim.core.GeoPoint
|
||||
|
||||
class NaviEngine {
|
||||
public interface OnNaviEngineCallbackListener {
|
||||
fun planningPathStatus(code: NaviStatus)
|
||||
|
||||
// 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(
|
||||
private val niMapController: NIMapController,
|
||||
private val realmOperateHelper: RealmOperateHelper,
|
||||
val callback: OnNaviEngineCallbackListener
|
||||
) {
|
||||
|
||||
/**
|
||||
* 要查询的要素列表
|
||||
*/
|
||||
private val QUERY_KEY_ITEM_LIST = arrayOf(
|
||||
DataCodeEnum.OMDB_ELECTRONICEYE.name,
|
||||
DataCodeEnum.OMDB_SPEEDLIMIT.name,
|
||||
DataCodeEnum.OMDB_SPEEDLIMIT_COND.name,
|
||||
DataCodeEnum.OMDB_SPEEDLIMIT_VAR.name,
|
||||
DataCodeEnum.OMDB_TRAFFICLIGHT.name,
|
||||
// DataCodeEnum.OMDB_RESTRICTION.name,
|
||||
DataCodeEnum.OMDB_LANEINFO.name,
|
||||
DataCodeEnum.OMDB_TRAFFIC_SIGN.name,
|
||||
DataCodeEnum.OMDB_WARNINGSIGN.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 = 15
|
||||
|
||||
/**
|
||||
* 偏离次数上限
|
||||
*/
|
||||
private val DEVIATION_COUNT = 5
|
||||
|
||||
/**
|
||||
* 局部匹配时,走过的路段还记录100米
|
||||
*/
|
||||
private val PASSED_ROUTE_DISTANCE = 100
|
||||
|
||||
/**
|
||||
* 局部匹配时,没走过的路段还记录1000米
|
||||
*/
|
||||
private val NEXT_ROUTE_DISTANCE = 1000
|
||||
|
||||
/**
|
||||
* 最远显示距离 米
|
||||
*/
|
||||
private val FARTHEST_DISPLAY_DISTANCE = 550
|
||||
|
||||
/**
|
||||
* 绑定失败次数
|
||||
*/
|
||||
private var errorCount = 0
|
||||
|
||||
/**
|
||||
* 当前邦定的那段route
|
||||
*/
|
||||
private var routeIndex = -1
|
||||
|
||||
/**
|
||||
* 当前绑定的link上哪个point
|
||||
*/
|
||||
private var footIndex = -1
|
||||
|
||||
/**
|
||||
* 绑定的垂足坐标
|
||||
*/
|
||||
private var footPoint: GeoPoint? = null
|
||||
|
||||
/**
|
||||
* 上一次定位绑到路线的距离
|
||||
*/
|
||||
private var lastDistance = -1
|
||||
|
||||
/**
|
||||
* 整条路的几何
|
||||
*/
|
||||
var geometry: LineString? = null
|
||||
var routeList = mutableListOf<Route>()
|
||||
|
||||
/**
|
||||
* 临时路径
|
||||
*/
|
||||
var tempGeometry: LineString? = null
|
||||
|
||||
/**
|
||||
* 定位点集合
|
||||
*/
|
||||
private var locationList: MutableList<NiLocation> = mutableListOf()
|
||||
|
||||
/**
|
||||
* 局部匹配时的路段
|
||||
*/
|
||||
var tempRoutList = mutableListOf<NaviRoute>()
|
||||
|
||||
|
||||
/**
|
||||
* 所有路段集合
|
||||
*/
|
||||
var routeList = mutableListOf<NaviRoute>()
|
||||
get() {
|
||||
return field
|
||||
}
|
||||
set(value) {
|
||||
val list = mutableListOf<GeoPoint>()
|
||||
list.addAll(value[0].pointList)
|
||||
val fRoute = value[0]
|
||||
//第一个路段加入
|
||||
list.addAll(fRoute.pointList)
|
||||
//起始点位置
|
||||
fRoute.startIndexInPath = 0
|
||||
var startPoint = fRoute.pointList.size - 1
|
||||
//终点位置
|
||||
fRoute.endIndexIntPath = startPoint
|
||||
fRoute.indexInPath = 0
|
||||
|
||||
for (i in 1 until value.size) {
|
||||
val list2 = value[i].pointList
|
||||
val route = value[i]
|
||||
route.startIndexInPath = startPoint
|
||||
if (route.itemList != null) {
|
||||
for (naviItem in route.itemList!!) {
|
||||
naviItem.index += startPoint
|
||||
}
|
||||
}
|
||||
startPoint += route.pointList.size - 1
|
||||
route.endIndexIntPath = startPoint
|
||||
route.indexInPath = i
|
||||
val list2 = ArrayList(route.pointList.toList())
|
||||
list2.removeAt(0)
|
||||
list.addAll(list2)
|
||||
}
|
||||
geometry = GeometryTools.createLineString(list)
|
||||
field = value
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算路径
|
||||
*/
|
||||
suspend fun planningPath(taskBean: TaskBean) {
|
||||
callback.planningPathStatus(NaviStatus.NAVI_STATUS_PATH_PLANNING)
|
||||
val pathList = mutableListOf<NaviRoute>()
|
||||
val realm = realmOperateHelper.getSelectTaskRealmInstance()
|
||||
for (link in taskBean.hadLinkDvoList) {
|
||||
//测线不参与导航
|
||||
if (link.linkStatus == 3) {
|
||||
continue
|
||||
}
|
||||
val route = NaviRoute(
|
||||
linkId = link.linkPid,
|
||||
)
|
||||
|
||||
route.pointList = GeometryTools.getGeoPoints(link.geometry)
|
||||
|
||||
val res = realm.where(RenderEntity::class.java).`in`("table", QUERY_KEY_LINK_INFO_LIST)
|
||||
.equalTo("properties['linkPid']", link.linkPid).findAll()
|
||||
var bHasNode = false
|
||||
var bHasDir = false
|
||||
var bHasName = false
|
||||
if (res != null) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!bHasNode) {
|
||||
callback.planningPathStatus(
|
||||
NaviStatus.NAVI_STATUS_PATH_ERROR_NODE
|
||||
)
|
||||
return
|
||||
}
|
||||
if (!bHasDir) {
|
||||
callback.planningPathStatus(
|
||||
NaviStatus.NAVI_STATUS_PATH_ERROR_DIRECTION
|
||||
)
|
||||
return
|
||||
}
|
||||
pathList.add(route)
|
||||
}
|
||||
//用来存储最终的导航路径
|
||||
val newRouteList = mutableListOf<NaviRoute>()
|
||||
//比对路径排序用的
|
||||
val tempRouteList = pathList.toMutableList()
|
||||
//先找到一根有方向的link,确定起终点
|
||||
var routeStart: NaviRoute? = null
|
||||
for (i in tempRouteList.indices) {
|
||||
val route = pathList[i]
|
||||
//只要时单方向的就行
|
||||
if (route.direct == 2 || route.direct == 3) {
|
||||
routeStart = route
|
||||
tempRouteList.removeAt(i)
|
||||
break
|
||||
}
|
||||
}
|
||||
if (routeStart != null) {
|
||||
var sNode = ""
|
||||
var eNode = ""
|
||||
//如果sNode,eNode是顺方向,geometry 不动,否则反转
|
||||
if (routeStart.direct == 3) {
|
||||
routeStart.pointList.reverse()
|
||||
sNode = routeStart.eNode
|
||||
eNode = routeStart.sNode
|
||||
} else {
|
||||
sNode = routeStart.sNode
|
||||
eNode = routeStart.eNode
|
||||
}
|
||||
newRouteList.add(routeStart)
|
||||
var bBreak = true
|
||||
while (bBreak) {
|
||||
//先找其实link的后续link
|
||||
var bHasNext = false
|
||||
for (route in tempRouteList) {
|
||||
//如果是link 的e 对下个link的s,方向不用动,否则下个link的geometry反转
|
||||
if (route.sNode != "" && eNode == route.sNode) {
|
||||
newRouteList.add(route)
|
||||
tempRouteList.remove(route)
|
||||
eNode = route.eNode
|
||||
bHasNext = true
|
||||
break
|
||||
} else if (route.eNode != "" && eNode == route.eNode) {
|
||||
route.pointList.reverse()
|
||||
newRouteList.add(route)
|
||||
tempRouteList.remove(route)
|
||||
eNode = route.sNode
|
||||
bHasNext = true
|
||||
break
|
||||
}
|
||||
}
|
||||
//先找其实link的起始link
|
||||
var bHasLast = false
|
||||
for (route in tempRouteList) {
|
||||
//如果是link 的s 对上个link的e,方向不用动,否则下个link的geometry反转
|
||||
if (route.eNode != "" && sNode == route.eNode) {
|
||||
newRouteList.add(0, route)
|
||||
tempRouteList.remove(route)
|
||||
sNode = route.sNode
|
||||
bHasLast = true
|
||||
break
|
||||
} else if (route.sNode != "" && sNode == route.sNode) {
|
||||
route.pointList.reverse()
|
||||
newRouteList.add(0, route)
|
||||
tempRouteList.remove(route)
|
||||
sNode = route.eNode
|
||||
bHasLast = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (tempRouteList.size == 0) {
|
||||
bBreak = false
|
||||
} else {
|
||||
if (!bHasLast && !bHasNext) {
|
||||
bBreak = false
|
||||
callback.planningPathStatus(
|
||||
NaviStatus.NAVI_STATUS_PATH_ERROR_BLOCKED
|
||||
)
|
||||
realm.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val itemMap: MutableMap<GeoPoint, MutableList<RenderEntity>> = mutableMapOf()
|
||||
//查询每根link上的关联要素
|
||||
for (route in newRouteList) {
|
||||
itemMap.clear()
|
||||
//常规点限速
|
||||
val res = realm.where(RenderEntity::class.java)
|
||||
.equalTo("properties['linkPid']", route.linkId).and().`in`(
|
||||
"table",
|
||||
QUERY_KEY_ITEM_LIST
|
||||
).findAll()
|
||||
if (res.isNotEmpty()) {
|
||||
// Log.e("jingo", "道路查询预警要素 ${route.linkId} ${res.size}条数据")
|
||||
for (r in res) {
|
||||
// Log.e("jingo", "道路查询预警要素 ${r.name}")
|
||||
insertItemToRoute(realm, route, r, itemMap)
|
||||
}
|
||||
}
|
||||
//对路径上的要素进行排序
|
||||
if (itemMap.isNotEmpty()) {
|
||||
route.itemList = mutableListOf()
|
||||
for (i in route.pointList.indices) {
|
||||
val point = route.pointList[i]
|
||||
if (itemMap.containsKey(point)) {
|
||||
val rEList = itemMap[point]
|
||||
for (item in rEList!!) {
|
||||
val naviRouteItem = NaviRouteItem(i, item, route.linkId)
|
||||
route.itemList!!.add(naviRouteItem)
|
||||
}
|
||||
itemMap.remove(point)
|
||||
}
|
||||
}
|
||||
route.itemList!!.sortBy { it.index }
|
||||
}
|
||||
}
|
||||
realm.close()
|
||||
routeList = newRouteList
|
||||
callback.planningPathStatus(NaviStatus.NAVI_STATUS_PATH_SUCCESS)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 将要素绑定到路径上
|
||||
*/
|
||||
private fun insertItemToRoute(
|
||||
realm: Realm,
|
||||
route: NaviRoute,
|
||||
res: RenderEntity?,
|
||||
itemMap: MutableMap<GeoPoint, MutableList<RenderEntity>>
|
||||
) {
|
||||
if (res != null) {
|
||||
val geometry = GeometryTools.createGeometry(res.geometry)
|
||||
if (geometry is Point) {
|
||||
//获取一个垂足点
|
||||
val footAndDistance = GeometryTools.pointToLineDistance(
|
||||
GeoPoint(
|
||||
geometry.coordinate.y, geometry.coordinate.x
|
||||
), GeometryTools.createLineString(route.pointList)
|
||||
)
|
||||
val point = GeoPoint(
|
||||
footAndDistance.getCoordinate(0).y, footAndDistance.getCoordinate(0).x
|
||||
)
|
||||
//测试marker
|
||||
// niMapController.markerHandle.addMarker(point, res.id, res.name)
|
||||
route.pointList.add(footAndDistance.footIndex + 1, point)
|
||||
if (itemMap.containsKey(point)) {
|
||||
itemMap[point]!!.add(realm.copyFromRealm(res))
|
||||
} else {
|
||||
itemMap[point] = mutableListOf(realm.copyFromRealm(res))
|
||||
}
|
||||
} else if (geometry is LineString) {
|
||||
//如果是线型数据,取路径的最后一个点
|
||||
val endPoint = route.pointList.last()
|
||||
if (itemMap.containsKey(endPoint)) {
|
||||
itemMap[endPoint]!!.add(realm.copyFromRealm(res))
|
||||
} else {
|
||||
itemMap[endPoint] = mutableListOf(realm.copyFromRealm(res))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定道路
|
||||
*/
|
||||
suspend fun bindingRoute(location: NiLocation?, point: GeoPoint) {
|
||||
if (geometry != null) {
|
||||
//还没有绑定到路径的时候
|
||||
if (routeIndex < 0) {
|
||||
val pointPairDistance = GeometryTools.pointToLineDistance(point, geometry)
|
||||
//定义垂线
|
||||
//定位点到垂足距离不超过30米
|
||||
if (pointPairDistance.getMeterDistance() < DEVIATION_DISTANCE) {
|
||||
footIndex = pointPairDistance.footIndex
|
||||
// Log.e(
|
||||
// "jingo",
|
||||
// "当前绑定到了整条路线的第 ${footIndex} 点 ${pointPairDistance.getMeterDistance()} "
|
||||
// )
|
||||
val lastRouteIndex = routeIndex
|
||||
for (i in routeList.indices) {
|
||||
val route = routeList[i]
|
||||
if (route.startIndexInPath <= footIndex && route.endIndexIntPath >= footIndex) {
|
||||
routeIndex = route.indexInPath
|
||||
// Log.e(
|
||||
// "jingo",
|
||||
// "当前绑定到了整条路线id ${route.linkId} "
|
||||
// )
|
||||
// niMapController.lineHandler.showLine(route.pointList)
|
||||
footPoint = GeoPoint(
|
||||
pointPairDistance.getCoordinate(0).y,
|
||||
pointPairDistance.getCoordinate(0).x
|
||||
)
|
||||
// val listPoint = mutableListOf(point, footPoint!!)
|
||||
// niMapController.lineHandler.showLine(
|
||||
// listPoint
|
||||
// )
|
||||
if (lastRouteIndex != routeIndex) {
|
||||
createTempPath()
|
||||
}
|
||||
errorCount = 0
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
deviationUp()
|
||||
}
|
||||
} else if (tempGeometry != null && tempRoutList.isNotEmpty()) {
|
||||
val pointPairDistance = GeometryTools.pointToLineDistance(point, tempGeometry)
|
||||
//定义垂线
|
||||
//定位点到垂足距离不超过30米
|
||||
if (pointPairDistance.getMeterDistance() < DEVIATION_DISTANCE) {
|
||||
footIndex = pointPairDistance.footIndex + tempRoutList[0].startIndexInPath
|
||||
// Log.e("jingo", "局部 当前绑定到了整条路线的第 $footIndex 点")
|
||||
val lastRouteIndex = routeIndex
|
||||
for (i in tempRoutList.indices) {
|
||||
val route = tempRoutList[i]
|
||||
if (route.startIndexInPath <= footIndex && route.endIndexIntPath >= footIndex) {
|
||||
routeIndex = route.indexInPath
|
||||
// Log.e(
|
||||
// "jingo",
|
||||
// "局部 当前绑定到了整条路线id ${route.linkId} "
|
||||
// )
|
||||
// niMapController.lineHandler.showLine(route.pointList)
|
||||
footPoint = GeoPoint(
|
||||
pointPairDistance.getCoordinate(0).y,
|
||||
pointPairDistance.getCoordinate(0).x
|
||||
)
|
||||
|
||||
// val listPoint = mutableListOf(point, footPoint!!)
|
||||
// niMapController.lineHandler.showLine(
|
||||
// listPoint
|
||||
// )
|
||||
matchingItem()
|
||||
if (lastRouteIndex != routeIndex) {
|
||||
createTempPath()
|
||||
}
|
||||
errorCount = 0
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
deviationUp()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 匹配要素
|
||||
* @point:定位点
|
||||
*/
|
||||
private suspend fun matchingItem() {
|
||||
|
||||
if (routeIndex > -1 && tempRoutList.isNotEmpty() && tempGeometry != null) {
|
||||
Log.e("jingo", "当前${routeIndex} ${tempRoutList[0].startIndexInPath} $footIndex")
|
||||
//道路前方一定距离范围内的要素信息
|
||||
val bindingItemList = mutableListOf<NaviRouteItem>()
|
||||
//定位点到要素的路径距离
|
||||
var distance = 0.0
|
||||
//计算要素路径距离的点集合
|
||||
val disPoints = mutableListOf(footPoint!!)
|
||||
//下一个要素的起点游标
|
||||
var tempIndex = footIndex - tempRoutList[0].startIndexInPath + 1
|
||||
var currentRoute: NaviRoute? = null
|
||||
for (route in tempRoutList) {
|
||||
// if (route.itemList != null) {
|
||||
// Log.e("jingo", "${route.linkId}我有${route.itemList!!.size}个要素 ")
|
||||
// }
|
||||
if (route.indexInPath < routeIndex)
|
||||
continue
|
||||
if (route.indexInPath == routeIndex) {
|
||||
currentRoute = route
|
||||
}
|
||||
if (route.itemList != null && route.itemList!!.isNotEmpty()) {
|
||||
for (naviItem in route.itemList!!) {
|
||||
// Log.e(
|
||||
// "jingo",
|
||||
// "我是:${naviItem.data.name} 我的点位 ${naviItem.index} 垂足点位 $footIndex"
|
||||
// )
|
||||
if (naviItem.index > footIndex) {
|
||||
val rightI = naviItem.index - tempRoutList[0].startIndexInPath + 1
|
||||
for (i in tempIndex until rightI) {
|
||||
val geo = tempGeometry!!.coordinates[i]
|
||||
disPoints.add(GeoPoint(geo.y, geo.x))
|
||||
}
|
||||
tempIndex = rightI + 1
|
||||
distance = GeometryTools.getDistance(disPoints)
|
||||
// Log.e("jingo", "我的距离${distance} 下一个${tempIndex} 位置${rightI}")
|
||||
if (distance < FARTHEST_DISPLAY_DISTANCE && distance > -1) {
|
||||
naviItem.distance = distance.toInt()
|
||||
bindingItemList.add(naviItem)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (distance >= FARTHEST_DISPLAY_DISTANCE) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
callback.bindingResults(currentRoute, bindingItemList)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建临时局部路径
|
||||
*/
|
||||
private fun createTempPath() {
|
||||
tempRoutList.clear()
|
||||
tempGeometry = null
|
||||
if (routeIndex > -1 && routeIndex < routeList.size && footPoint != null) {
|
||||
val route = routeList[routeIndex]
|
||||
//当前垂足点在这个路段中是第几个坐标
|
||||
tempRoutList.add(route)
|
||||
var distance = 0.0
|
||||
//已经走过的路是否有100米
|
||||
var i = routeIndex - 1
|
||||
while (i >= 0 && distance < PASSED_ROUTE_DISTANCE) {
|
||||
val routeT = routeList[i]
|
||||
tempRoutList.add(0, routeT)
|
||||
distance += routeT.length
|
||||
i--
|
||||
}
|
||||
distance = 0.0
|
||||
//没走过的路是否有1000米
|
||||
var j = routeIndex + 1
|
||||
while (j < routeList.size && distance < NEXT_ROUTE_DISTANCE) {
|
||||
val routeT = routeList[j]
|
||||
tempRoutList.add(routeT)
|
||||
distance += routeT.length
|
||||
j++
|
||||
}
|
||||
}
|
||||
val list = mutableListOf<GeoPoint>()
|
||||
val fRoute = tempRoutList[0]
|
||||
//第一个路段加入
|
||||
list.addAll(fRoute.pointList)
|
||||
|
||||
for (i in 1 until tempRoutList.size) {
|
||||
val route = tempRoutList[i]
|
||||
val list2 = ArrayList(route.pointList.toList())
|
||||
list2.removeAt(0)
|
||||
list.addAll(list2)
|
||||
}
|
||||
tempGeometry = GeometryTools.createLineString(list)
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否完全偏离
|
||||
*/
|
||||
private fun deviationUp() {
|
||||
errorCount++
|
||||
if (errorCount >= DEVIATION_COUNT) {
|
||||
callback.planningPathStatus(NaviStatus.NAVI_STATUS_DISTANCE_OFF)
|
||||
bindingReset()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定重置
|
||||
*/
|
||||
private fun bindingReset() {
|
||||
//绑定失败次数
|
||||
errorCount = 0
|
||||
//当前邦定的那段route
|
||||
routeIndex = -1
|
||||
//当前绑定的link上哪个point
|
||||
footIndex = -1
|
||||
//上一次定位绑到路线的距离
|
||||
lastDistance = -1
|
||||
//垂足坐标
|
||||
footPoint = null
|
||||
//定位点集合
|
||||
locationList.clear()
|
||||
}
|
||||
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
package com.navinfo.omqs.util
|
||||
|
||||
import android.provider.ContactsContract.Data
|
||||
import android.util.Log
|
||||
import com.navinfo.collect.library.data.entity.RenderEntity
|
||||
import com.navinfo.collect.library.enums.DataCodeEnum
|
||||
import com.navinfo.collect.library.utils.FootAndDistance
|
||||
import com.navinfo.collect.library.utils.GeometryTools
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.bean.RoadNameBean
|
||||
import com.navinfo.omqs.bean.SignBean
|
||||
@ -13,6 +14,10 @@ import com.navinfo.omqs.ui.fragment.signMoreInfo.TwoItemAdapter
|
||||
import com.navinfo.omqs.ui.fragment.signMoreInfo.TwoItemAdapterItem
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import org.locationtech.jts.geom.Geometry
|
||||
import org.locationtech.jts.geom.LineString
|
||||
import org.locationtech.jts.geom.Point
|
||||
import org.oscim.core.GeoPoint
|
||||
import java.lang.reflect.Field
|
||||
|
||||
class SignUtil {
|
||||
@ -808,32 +813,32 @@ class SignUtil {
|
||||
DataCodeEnum.OMDB_TRAFFIC_SIGN.code -> {
|
||||
var color = data.properties["color"]
|
||||
if (color != null) {
|
||||
when(color){
|
||||
"0"->{
|
||||
return "颜色:未验证"
|
||||
when (color) {
|
||||
"0" -> {
|
||||
return "颜色:未验证"
|
||||
}
|
||||
"1"->{
|
||||
"1" -> {
|
||||
return "颜色:白色"
|
||||
}
|
||||
"2"->{
|
||||
"2" -> {
|
||||
return "颜色:黄色"
|
||||
}
|
||||
"3"->{
|
||||
"3" -> {
|
||||
return "颜色:红色"
|
||||
}
|
||||
"5"->{
|
||||
"5" -> {
|
||||
return "颜色:棕色"
|
||||
}
|
||||
"6"->{
|
||||
"6" -> {
|
||||
return "颜色:蓝色"
|
||||
}
|
||||
"7"->{
|
||||
"7" -> {
|
||||
return "颜色:绿色"
|
||||
}
|
||||
"8"->{
|
||||
"8" -> {
|
||||
return "颜色:黑色"
|
||||
}
|
||||
"9"->{
|
||||
"9" -> {
|
||||
return "颜色:其他"
|
||||
}
|
||||
}
|
||||
@ -1065,7 +1070,8 @@ class SignUtil {
|
||||
DataCodeEnum.OMDB_TRAFFIC_SIGN.code -> {
|
||||
var trafsignShape = data.properties["trafsignShape"]
|
||||
if (trafsignShape != null) {
|
||||
trafsignShape = "icon_${DataCodeEnum.OMDB_TRAFFIC_SIGN.code}_${trafsignShape.lowercase()}"
|
||||
trafsignShape =
|
||||
"icon_${DataCodeEnum.OMDB_TRAFFIC_SIGN.code}_${trafsignShape.lowercase()}"
|
||||
return getResId(trafsignShape, R.drawable::class.java)
|
||||
}
|
||||
return 0
|
||||
@ -1645,5 +1651,54 @@ class SignUtil {
|
||||
return list
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算捕捉点到
|
||||
*/
|
||||
fun getDistance(
|
||||
footAndDistance: FootAndDistance,
|
||||
lineString: Geometry,
|
||||
element: RenderEntity
|
||||
): Int {
|
||||
|
||||
val itemGeometry = GeometryTools.createGeometry(element.geometry)
|
||||
if (itemGeometry is Point) {
|
||||
val itemFoot = GeometryTools.pointToLineDistance(
|
||||
GeoPoint(itemGeometry.y, itemGeometry.x),
|
||||
lineString
|
||||
)
|
||||
var dis = GeometryTools.getDistance(
|
||||
footAndDistance.getCoordinate(0).getY(),
|
||||
footAndDistance.getCoordinate(0).getX(),
|
||||
itemFoot.getCoordinate(0).getY(),
|
||||
itemFoot.getCoordinate(0).getX(),
|
||||
)
|
||||
return if (footAndDistance.footIndex < itemFoot.footIndex) {
|
||||
dis.toInt()
|
||||
} else {
|
||||
-dis.toInt()
|
||||
}
|
||||
} else if (itemGeometry is LineString) {
|
||||
val itemFoot = GeometryTools.pointToLineDistance(
|
||||
GeoPoint(
|
||||
lineString.coordinates[0].y,
|
||||
lineString.coordinates[0].x
|
||||
), lineString
|
||||
)
|
||||
var dis = GeometryTools.getDistance(
|
||||
footAndDistance.getCoordinate(0).getY(),
|
||||
footAndDistance.getCoordinate(0).getX(),
|
||||
itemFoot.getCoordinate(0).getY(),
|
||||
itemFoot.getCoordinate(0).getX(),
|
||||
)
|
||||
return if (footAndDistance.footIndex < itemFoot.footIndex) {
|
||||
dis.toInt()
|
||||
} else {
|
||||
-dis.toInt()
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
BIN
app/src/main/res/drawable-xxhdpi/t0201000.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/t0201000.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
@ -29,16 +29,29 @@
|
||||
android:textColor="#2F2F2F"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sign_distance_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="40dp"
|
||||
android:layout_alignRight="@id/sign_main_bg"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginRight="19dp"
|
||||
android:gravity="center"
|
||||
android:text="范围外"
|
||||
android:textColor="#3736DB"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sign_second_icon"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_toRightOf="@id/sign_main_icon"
|
||||
android:gravity="center"
|
||||
android:text=""
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sign_bottom_text"
|
||||
android:layout_width="wrap_content"
|
||||
@ -69,8 +82,8 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@id/sign_main_bg"
|
||||
android:layout_marginLeft="2dp"
|
||||
android:padding="4dp"
|
||||
android:layout_toRightOf="@id/sign_main_bg"
|
||||
android:padding="4dp"
|
||||
android:src="@drawable/icon_sign_info"
|
||||
android:visibility="gone" />
|
||||
|
||||
@ -81,7 +94,7 @@
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginLeft="172dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:visibility="gone"
|
||||
android:background="@drawable/icon_evaluation" />
|
||||
android:background="@drawable/icon_evaluation"
|
||||
android:visibility="gone" />
|
||||
|
||||
</RelativeLayout>
|
@ -260,6 +260,8 @@
|
||||
<xs:attribute name="gland" default="true" type="xs:boolean" use="optional"/>
|
||||
<!-- 原图标旋转角度,默认情况下应该使用以X轴为正方向的图标,此处可设置原图标的旋转角度,在渲染时自动对图标进行旋转,仅支持线要素 -->
|
||||
<xs:attribute name="degree" default="0" type="xs:float" use="optional"/>
|
||||
<!-- 图标在y轴方向上的偏移量 -->
|
||||
<xs:attribute name="dy" default="0" type="xs:float" use="optional"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="extrusion">
|
||||
|
@ -1568,7 +1568,7 @@
|
||||
<!-- 交通标牌 -->
|
||||
<m v="OMDB_TRAFFIC_SIGN">
|
||||
<symbol repeat="false" repeat-gap="2000" repeat-start="0" rotate="true"
|
||||
src="@src" symbol-height="24" symbol-width="24" degree="-90"></symbol>
|
||||
src="@src" symbol-height="24" symbol-width="24" degree="-90" dy="-30"></symbol>
|
||||
</m>
|
||||
|
||||
<m v="OMDB_AREA">
|
||||
|
@ -10,7 +10,7 @@ abstract class BaseHandler(context: AppCompatActivity, mapView: NIMapView) {
|
||||
protected val mMapView: NIMapView = mapView
|
||||
|
||||
fun addLayer(layer: Layer, groupType: NIMapView.LAYER_GROUPS) {
|
||||
Log.e("jingo", "增加了图层 ${layer.toString()}")
|
||||
// Log.e("jingo", "增加了图层 ${layer.toString()}")
|
||||
mMapView.vtmMap.layers().add(
|
||||
layer,
|
||||
groupType.groupIndex
|
||||
|
@ -10,6 +10,7 @@ import com.navinfo.collect.library.map.layers.MultiLinesLayer
|
||||
import com.navinfo.collect.library.map.layers.OmdbTaskLinkLayer
|
||||
import com.navinfo.collect.library.utils.GeometryTools
|
||||
import org.oscim.android.canvas.AndroidBitmap
|
||||
import org.oscim.core.GeoPoint
|
||||
import org.oscim.layers.marker.ItemizedLayer
|
||||
import org.oscim.layers.marker.ItemizedLayer.OnItemGestureListener
|
||||
import org.oscim.layers.marker.MarkerInterface
|
||||
@ -112,6 +113,18 @@ class LineHandler(context: AppCompatActivity, mapView: NIMapView) : BaseHandler(
|
||||
layer
|
||||
}
|
||||
|
||||
/**
|
||||
* 高亮一条线
|
||||
*/
|
||||
fun showLine(list:List<GeoPoint>) {
|
||||
try {
|
||||
mDefaultPathLayer.clearPath()
|
||||
mDefaultPathLayer.setPoints(list)
|
||||
mDefaultPathLayer.isEnabled = true
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(mContext, "高亮路线失败 ${e.message}", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 高亮一条线
|
||||
@ -126,6 +139,7 @@ class LineHandler(context: AppCompatActivity, mapView: NIMapView) : BaseHandler(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 取消高亮线
|
||||
*/
|
||||
|
@ -77,7 +77,7 @@ public class OMDBDataDecoder extends TileDecoder {
|
||||
properties.putAll(renderEntity.getProperties());
|
||||
parseGeometry(renderEntity.getTable(), renderEntity.getWkt(), properties);
|
||||
}else{
|
||||
Log.e("qj","render"+renderEntity.name+"=="+renderEntity.getZoomMin()+"==="+renderEntity.getZoomMax()+"==="+renderEntity.getEnable());
|
||||
// Log.e("qj","render"+renderEntity.name+"=="+renderEntity.getZoomMin()+"==="+renderEntity.getZoomMax()+"==="+renderEntity.getEnable());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -0,0 +1,145 @@
|
||||
package com.navinfo.collect.library.utils
|
||||
|
||||
import org.locationtech.jts.geom.*
|
||||
import org.locationtech.jts.io.WKTWriter
|
||||
import org.oscim.core.GeoPoint
|
||||
|
||||
class FootAndDistance(private val point: GeoPoint) {
|
||||
|
||||
private val pt = arrayOf(Coordinate(), Coordinate())
|
||||
private var distance = Double.NaN
|
||||
private var isNull = true
|
||||
var footIndex = 0
|
||||
|
||||
/**
|
||||
* Initializes this instance.
|
||||
*/
|
||||
fun initialize() {
|
||||
isNull = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the points, computing the distance between them.
|
||||
* @param p0 the 1st point
|
||||
* @param p1 the 2nd point
|
||||
*/
|
||||
fun initialize(p0: Coordinate, p1: Coordinate) {
|
||||
initialize(p0, p1, p0.distance(p1))
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the points, avoiding recomputing the distance.
|
||||
* @param p0 the 1st point
|
||||
* @param p1 the 2nd point
|
||||
* @param distance the distance between p0 and p1
|
||||
*/
|
||||
fun initialize(p0: Coordinate, p1: Coordinate, distance: Double) {
|
||||
pt[0].setCoordinate(p0)
|
||||
pt[1].setCoordinate(p1)
|
||||
this.distance = distance
|
||||
isNull = false
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the distance between the paired points
|
||||
* @return the distance between the paired points
|
||||
*/
|
||||
fun getDistance(): Double {
|
||||
return distance
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the paired points
|
||||
* @return the paired points
|
||||
*/
|
||||
fun getCoordinates(): Array<Coordinate> {
|
||||
return pt
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets one of the paired points
|
||||
* @param i the index of the paired point (0 or 1)
|
||||
* @return A point
|
||||
*/
|
||||
fun getCoordinate(i: Int): Coordinate {
|
||||
return pt[i]
|
||||
}
|
||||
|
||||
|
||||
fun setMinimum(p0: Coordinate, p1: Coordinate): Boolean {
|
||||
if (isNull) {
|
||||
initialize(p0, p1)
|
||||
return true
|
||||
}
|
||||
val dist = p0.distance(p1)
|
||||
if (dist < distance) {
|
||||
initialize(p0, p1, dist)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return WKTWriter.toLineString(pt[0], pt[1])
|
||||
}
|
||||
|
||||
|
||||
fun getMeterDistance(): Double {
|
||||
return if (!distance.isNaN() && pt.isNotEmpty())
|
||||
GeometryTools.getDistance(
|
||||
point.latitude,
|
||||
point.longitude,
|
||||
pt[0].y,
|
||||
pt[0].x
|
||||
)
|
||||
else {
|
||||
Double.NaN
|
||||
}
|
||||
}
|
||||
|
||||
fun computeDistance(geom: Geometry, pt: Coordinate) {
|
||||
when (geom) {
|
||||
is LineString -> {
|
||||
computeDistance(geom, pt)
|
||||
}
|
||||
is Polygon -> {
|
||||
computeDistance(geom, pt)
|
||||
}
|
||||
is GeometryCollection -> {
|
||||
for (i in 0 until geom.numGeometries) {
|
||||
val g = geom.getGeometryN(i)
|
||||
computeDistance(g, pt)
|
||||
}
|
||||
}
|
||||
else -> { // assume geom is Point
|
||||
setMinimum(geom.coordinate, pt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun computeDistance(line: LineString, pt: Coordinate) {
|
||||
val tempSegment = LineSegment()
|
||||
val coords = line.coordinates
|
||||
for (i in 0 until (coords.size - 1)) {
|
||||
tempSegment.setCoordinates(coords[i], coords[i + 1])
|
||||
// this is somewhat inefficient - could do better
|
||||
val closestPt = tempSegment.closestPoint(pt)
|
||||
if (setMinimum(closestPt, pt)) {
|
||||
footIndex = i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun computeDistance(segment: LineSegment, pt: Coordinate) {
|
||||
val closestPt = segment.closestPoint(pt)
|
||||
setMinimum(closestPt, pt)
|
||||
}
|
||||
|
||||
fun computeDistance(poly: Polygon, pt: Coordinate) {
|
||||
computeDistance(poly.exteriorRing, pt)
|
||||
for (i in 0 until poly.numInteriorRing) {
|
||||
computeDistance(poly.getInteriorRingN(i), pt)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -4,9 +4,6 @@ import android.graphics.Point;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.locationtech.jts.algorithm.distance.DistanceToPoint;
|
||||
import org.locationtech.jts.algorithm.distance.PointPairDistance;
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
import org.locationtech.jts.geom.GeometryFactory;
|
||||
@ -446,148 +443,15 @@ public class GeometryTools {
|
||||
|
||||
}
|
||||
|
||||
public static GeoPoint getLineStringCenter(String lineString) {
|
||||
List<GeoPoint> points = getGeoPoints(lineString);
|
||||
return getLineStringCenter(points);
|
||||
public static double distanceToDouble(Geometry startGeoPoint, Geometry endGeoPoint) {
|
||||
if (startGeoPoint != null && endGeoPoint != null) {
|
||||
double d = startGeoPoint.distance(endGeoPoint);
|
||||
return convertDistanceToDegree(d, startGeoPoint.getCoordinate().y);
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
public static GeoPoint getLineStringCenter(List<GeoPoint> points) {
|
||||
if (points != null && points.size() > 1) {
|
||||
if (points.size() == 2) {
|
||||
double x1 = points.get(0).getLongitude();
|
||||
double y1 = points.get(0).getLatitude();
|
||||
double x2 = points.get(1).getLongitude();
|
||||
double y2 = points.get(1).getLatitude();
|
||||
GeoPoint newPoint = new GeoPoint((y1 + y2) / 2, (x1 + x2) / 2);
|
||||
return newPoint;
|
||||
} else {
|
||||
double total = 0;
|
||||
ArrayList<Double> dList = new ArrayList<Double>();
|
||||
for (int i = 0; i < points.size() - 1; i++) {
|
||||
double lt = total;
|
||||
double dis = distanceToDouble(points.get(i), points.get(i + 1));
|
||||
dList.add(lt + dis);
|
||||
total += dis;
|
||||
}
|
||||
total = total / 2;
|
||||
for (int i = 0; i < dList.size(); i++) {
|
||||
double a = dList.get(i);
|
||||
double b = 0;
|
||||
if (i > 0) {
|
||||
b = dList.get(i - 1);
|
||||
}
|
||||
if (a > total) {
|
||||
if (a - total < 4) {
|
||||
return points.get(i);
|
||||
}
|
||||
double dx = (a - total) * 0.5 / (a - b);
|
||||
GeoPoint point1 = points.get(i);
|
||||
GeoPoint point2 = points.get(i + 1);
|
||||
double x;
|
||||
if (point1.getLongitude() < point2.getLongitude()) {
|
||||
x = (point2.getLongitude() - point1.getLongitude()) * dx;
|
||||
x = point2.getLongitude() - x;
|
||||
} else {
|
||||
x = (point1.getLongitude() - point2.getLongitude()) * dx;
|
||||
x = point2.getLongitude() + x;
|
||||
}
|
||||
double y;
|
||||
if (point1.getLatitude() > point2.getLatitude()) {
|
||||
y = (point1.getLatitude() - point2.getLatitude()) * dx;
|
||||
y = point2.getLatitude() + y;
|
||||
} else {
|
||||
y = (point2.getLatitude() - point1.getLatitude()) * dx;
|
||||
y = point2.getLatitude() - y;
|
||||
}
|
||||
GeoPoint geoPoint = new GeoPoint(y, x);
|
||||
return geoPoint;
|
||||
} else {
|
||||
if (total - a < 4) {
|
||||
return points.get(i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static GeoPoint getLineStringCenter(List<GeoPoint> points, int[] index) {
|
||||
if (points != null && points.size() > 1) {
|
||||
if (points.size() == 2) {
|
||||
double x1 = points.get(0).getLongitude();
|
||||
double y1 = points.get(0).getLatitude();
|
||||
double x2 = points.get(1).getLongitude();
|
||||
double y2 = points.get(1).getLatitude();
|
||||
GeoPoint newPoint = new GeoPoint((y1 + y2) / 2, (x1 + x2) / 2);
|
||||
if (index != null && index.length > 1) {
|
||||
index[0] = 0;
|
||||
index[1] = 1;
|
||||
}
|
||||
return newPoint;
|
||||
} else {
|
||||
double total = 0;
|
||||
ArrayList<Double> dList = new ArrayList<Double>();
|
||||
for (int i = 0; i < points.size() - 1; i++) {
|
||||
double lt = total;
|
||||
double dis = distance(points.get(i).toString(), points.get(i + 1).toString());
|
||||
dList.add(lt + dis);
|
||||
total += dis;
|
||||
}
|
||||
total = total / 2;
|
||||
for (int i = 0; i < dList.size(); i++) {
|
||||
double a = dList.get(i);
|
||||
double b = 0;
|
||||
if (i > 0) {
|
||||
b = dList.get(i - 1);
|
||||
}
|
||||
if (a > total) {
|
||||
if (a - total < 4) {
|
||||
if (index != null && index.length > 1) {
|
||||
index[0] = i;
|
||||
index[1] = i + 1;
|
||||
}
|
||||
return points.get(i);
|
||||
}
|
||||
double dx = (a - total) * 0.5 / (a - b);
|
||||
GeoPoint point1 = points.get(i);
|
||||
GeoPoint point2 = points.get(i + 1);
|
||||
double x;
|
||||
if (point1.getLongitude() < point2.getLongitude()) {
|
||||
x = (point2.getLongitude() - point1.getLongitude()) * dx;
|
||||
x = point2.getLongitude() - x;
|
||||
} else {
|
||||
x = (point1.getLongitude() - point2.getLongitude()) * dx;
|
||||
x = point2.getLongitude() + x;
|
||||
}
|
||||
double y;
|
||||
if (point1.getLatitude() > point2.getLatitude()) {
|
||||
y = (point1.getLatitude() - point2.getLatitude()) * dx;
|
||||
y = point2.getLatitude() + y;
|
||||
} else {
|
||||
y = (point2.getLatitude() - point1.getLatitude()) * dx;
|
||||
y = point2.getLatitude() - y;
|
||||
}
|
||||
GeoPoint geoPoint = new GeoPoint(y, x);
|
||||
if (index != null && index.length > 1) {
|
||||
index[0] = i;
|
||||
index[1] = i + 1;
|
||||
}
|
||||
return geoPoint;
|
||||
} else {
|
||||
if (total - a < 4) {
|
||||
if (index != null && index.length > 1) {
|
||||
index[0] = i;
|
||||
index[1] = i + 1;
|
||||
}
|
||||
return points.get(i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* LINESTRING (116.4206899999999933 39.9620999999999995,
|
||||
@ -1160,39 +1024,6 @@ public class GeometryTools {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 点与几何最近点位置
|
||||
*
|
||||
* @param list
|
||||
* @param geoPoint
|
||||
* @return geopoint
|
||||
* @author qiji
|
||||
*/
|
||||
public static GeoPoint getZuijinGeoPoint(List<GeoPoint> list, GeoPoint geoPoint) {//MapManager.getInstance().getMap().getMapCenterGeoLocation()屏幕中心点
|
||||
|
||||
if (list == null || list.size() == 0 || geoPoint == null)
|
||||
return null;
|
||||
|
||||
double dis = 0;
|
||||
|
||||
GeoPoint geo = null;
|
||||
|
||||
for (GeoPoint geopoint : list) {
|
||||
|
||||
double disTemp = distanceToDouble(geoPoint, geopoint);
|
||||
|
||||
if (dis == 0 || dis < disTemp) {
|
||||
|
||||
dis = disTemp;
|
||||
|
||||
geo = geopoint;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return geo;
|
||||
}
|
||||
|
||||
public static String GeometryFormatDouble5(String geometry) {
|
||||
try {
|
||||
@ -1333,8 +1164,6 @@ public class GeometryTools {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public enum SNAP_TYPE {
|
||||
/**
|
||||
* 像素
|
||||
@ -1570,7 +1399,7 @@ public class GeometryTools {
|
||||
*/
|
||||
public static double getDistance(List<GeoPoint> list) {
|
||||
if (list.size() < 2) {
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
double dis = 0;
|
||||
for (int i = 0; i < list.size() - 1; i++) {
|
||||
@ -1618,6 +1447,12 @@ public class GeometryTools {
|
||||
*/
|
||||
private static final double EARTH_RADIUS = 6371000.0;
|
||||
|
||||
/**
|
||||
* 距离转米
|
||||
* @param distance
|
||||
* @param latitude
|
||||
* @return
|
||||
*/
|
||||
public static double convertDistanceToDegree(double distance, double latitude) {
|
||||
double radianDistance = distance / EARTH_RADIUS;
|
||||
double radianLatitude = Math.toRadians(latitude);
|
||||
@ -1669,28 +1504,13 @@ public class GeometryTools {
|
||||
return point;
|
||||
}
|
||||
|
||||
public static List<GeoPoint> pointToLineDistance(GeoPoint point, List<GeoPoint> pointList) {
|
||||
|
||||
Coordinate coordinate = geoPointToMercator(point);
|
||||
Coordinate[] cs = new Coordinate[pointList.size()];
|
||||
public static FootAndDistance pointToLineDistance(GeoPoint point, Geometry geometry) {
|
||||
//定义垂线
|
||||
FootAndDistance pointPairDistance = new FootAndDistance(point);
|
||||
Coordinate coordinate = new Coordinate(point.getLongitude(), point.getLatitude());
|
||||
pointPairDistance.computeDistance(geometry,coordinate);
|
||||
|
||||
for (int i = 0; i < pointList.size(); i++) {
|
||||
Coordinate c = geoPointToMercator(pointList.get(i));
|
||||
cs[i] = c;
|
||||
}
|
||||
GeometryFactory factory = new GeometryFactory();
|
||||
LineString lineString = factory.createLineString(cs);
|
||||
PointPairDistance pointPairDistance = new PointPairDistance();
|
||||
DistanceToPoint.computeDistance(
|
||||
lineString,
|
||||
coordinate,
|
||||
pointPairDistance
|
||||
);
|
||||
|
||||
List newPoints = new ArrayList<GeoPoint>();
|
||||
for (int i = 0; i < pointPairDistance.getCoordinates().length; i++) {
|
||||
newPoints.add(mercatorToGeoPoint(pointPairDistance.getCoordinate(i)));
|
||||
}
|
||||
return newPoints;
|
||||
return pointPairDistance;
|
||||
}
|
||||
}
|
||||
|
2
vtm
2
vtm
@ -1 +1 @@
|
||||
Subproject commit 3d9400fb6aa671ff05dceb616e412f024b2e4440
|
||||
Subproject commit 719c44b65d3ed26d725b24b3a5366b281c9e4fad
|
Loading…
x
Reference in New Issue
Block a user