Conflicts:
	app/src/main/java/com/navinfo/omqs/db/ImportPreProcess.kt
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
	vtm
This commit is contained in:
qiji4215 2023-09-11 17:13:53 +08:00
commit c61599bcc8
12 changed files with 448 additions and 89 deletions

View File

@ -77,7 +77,6 @@ android {
} }
dependencies { dependencies {
api project(':collect-library') api project(':collect-library')
implementation project(path: ':vtm-android') implementation project(path: ':vtm-android')

View File

@ -0,0 +1,24 @@
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
}
}

View File

@ -279,11 +279,8 @@ class MainActivity : BaseActivity() {
viewModel.liveDataRoadName.observe(this) { viewModel.liveDataRoadName.observe(this) {
if (it != null) { if (it != null) {
binding.mainActivityRoadName.text = it.properties["name"] binding.mainActivityRoadName.text = it.properties["name"]
if (binding.mainActivityRoadName.visibility != View.VISIBLE) binding.mainActivityRoadName.visibility =
View.VISIBLE
} else { } else {
if (binding.mainActivityRoadName.visibility != View.GONE) binding.mainActivityRoadName.visibility = binding.mainActivityRoadName.text = " "
View.GONE
} }
} }

View File

@ -4,6 +4,7 @@ import android.app.Activity
import android.content.Context import android.content.Context
import android.content.DialogInterface import android.content.DialogInterface
import android.content.SharedPreferences import android.content.SharedPreferences
import android.graphics.Color
import android.graphics.drawable.AnimationDrawable import android.graphics.drawable.AnimationDrawable
import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.BitmapDrawable
import android.os.Build import android.os.Build
@ -29,34 +30,37 @@ import com.navinfo.collect.library.garminvirbxe.HostBean
import com.navinfo.collect.library.map.NIMapController import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.map.OnGeoPointClickListener import com.navinfo.collect.library.map.OnGeoPointClickListener
import com.navinfo.collect.library.map.handler.* import com.navinfo.collect.library.map.handler.*
import com.navinfo.collect.library.utils.DistanceUtil
import com.navinfo.collect.library.utils.GeometryTools import com.navinfo.collect.library.utils.GeometryTools
import com.navinfo.collect.library.utils.GeometryToolsKt import com.navinfo.collect.library.utils.GeometryToolsKt
import com.navinfo.collect.library.utils.MapParamUtils import com.navinfo.collect.library.utils.MapParamUtils
import com.navinfo.omqs.Constant import com.navinfo.omqs.Constant
import com.navinfo.omqs.R import com.navinfo.omqs.R
import com.navinfo.omqs.bean.ImportConfig import com.navinfo.omqs.bean.*
import com.navinfo.omqs.bean.QRCodeBean
import com.navinfo.omqs.bean.SignBean
import com.navinfo.omqs.bean.TraceVideoBean
import com.navinfo.omqs.db.RealmOperateHelper import com.navinfo.omqs.db.RealmOperateHelper
import com.navinfo.omqs.http.NetResult import com.navinfo.omqs.http.NetResult
import com.navinfo.omqs.http.NetworkService import com.navinfo.omqs.http.NetworkService
import com.navinfo.omqs.tools.FileManager
import com.navinfo.omqs.ui.dialog.CommonDialog import com.navinfo.omqs.ui.dialog.CommonDialog
import com.navinfo.omqs.ui.manager.TakePhotoManager import com.navinfo.omqs.ui.manager.TakePhotoManager
import com.navinfo.omqs.ui.other.BaseToast import com.navinfo.omqs.ui.other.BaseToast
import com.navinfo.omqs.util.SignUtil import com.navinfo.omqs.util.*
import com.navinfo.omqs.util.DateTimeUtil
import com.navinfo.omqs.util.ShareUtil
import com.navinfo.omqs.util.SoundMeter
import com.navinfo.omqs.util.SpeakMode
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import io.realm.Realm import io.realm.Realm
import io.realm.RealmConfiguration import io.realm.RealmConfiguration
import io.realm.RealmSet import io.realm.RealmSet
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
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.Geometry
import org.oscim.core.GeoPoint import org.oscim.core.GeoPoint
import org.oscim.core.MapPosition import org.oscim.core.MapPosition
@ -86,6 +90,9 @@ class MainViewModel @Inject constructor(
private var mCameraDialog: CommonDialog? = null private var mCameraDialog: CommonDialog? = null
//路径计算
val liveDataPlanningPathStatus = MutableLiveData<Int>()
//地图点击捕捉到的质检数据ID列表 //地图点击捕捉到的质检数据ID列表
val liveDataQsRecordIdList = MutableLiveData<List<String>>() val liveDataQsRecordIdList = MutableLiveData<List<String>>()
@ -210,16 +217,22 @@ class MainViewModel @Inject constructor(
private var currentMapZoomLevel: Int = 0 private var currentMapZoomLevel: Int = 0
//导航信息
private var naviEngine: NaviEngine = NaviEngine()
// 定义一个互斥锁
private val naviMutex = Mutex()
init { init {
mapController.mMapView.vtmMap.events.bind(Map.UpdateListener { e, mapPosition -> mapController.mMapView.vtmMap.events.bind(Map.UpdateListener { e, mapPosition ->
when (e) { when (e) {
Map.SCALE_EVENT, Map.MOVE_EVENT, Map.ROTATE_EVENT -> liveDataCenterPoint.value = Map.SCALE_EVENT, Map.MOVE_EVENT, Map.ROTATE_EVENT -> liveDataCenterPoint.value =
mapPosition mapPosition
} }
if (mapController.mMapView.vtmMap.mapPosition.zoomLevel >= 16) {
}
currentMapZoomLevel = mapController.mMapView.vtmMap.mapPosition.zoomLevel currentMapZoomLevel = mapController.mMapView.vtmMap.mapPosition.zoomLevel
}) })
@ -307,9 +320,46 @@ class MainViewModel @Inject constructor(
Constant.currentSelectTaskConfig = RealmConfiguration.Builder().directory(Constant.currentSelectTaskFolder).name("OMQS.realm").encryptionKey(Constant.PASSWORD).allowQueriesOnUiThread(true).schemaVersion(2).build() Constant.currentSelectTaskConfig = RealmConfiguration.Builder().directory(Constant.currentSelectTaskFolder).name("OMQS.realm").encryptionKey(Constant.PASSWORD).allowQueriesOnUiThread(true).schemaVersion(2).build()
MapParamUtils.setTaskConfig(Constant.currentSelectTaskConfig) MapParamUtils.setTaskConfig(Constant.currentSelectTaskConfig)
socketServer = SocketServer(mapController, traceDataBase, sharedPreferences) 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())
// }
// }
// naviMutex.unlock()
// }
// }
} }
fun naviTestFlow(): Flow<GeoPoint> = flow {
while (true) {
emit(mapController.mMapView.vtmMap.mapPosition.geoPoint)
delay(1000)
}
}
/** /**
* 获取当前任务 * 获取当前任务
*/ */
@ -319,6 +369,146 @@ 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()
}
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 = Realm.getDefaultInstance()
for (link in taskBean.hadLinkDvoList) {
//测线不参与导航
if (link.linkStatus == 3) {
continue
}
val route = Route(
linkId = link.linkPid,
)
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"]
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)
}
//用来存储最终的导航路径
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 = ""
//如果snodeenode是顺方向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
//TODO 处理错误,路径不完整
}
}
}
}
naviEngine.routeList = newRouteList
naviMutex.unlock()
}
} else {
// Toast.makeText(context, "数据未安装,无法计算导航路径", Toast.LENGTH_SHORT).show()
} }
realm.close() realm.close()
} }
@ -615,7 +805,7 @@ class MainViewModel @Inject constructor(
val realm = realmOperateHelper.getSelectTaskRealmInstance() val realm = realmOperateHelper.getSelectTaskRealmInstance()
val entity = val entityList =
realmOperateHelper.getSelectTaskRealmTools(RenderEntity::class.java, true) realmOperateHelper.getSelectTaskRealmTools(RenderEntity::class.java, true)
.and() .and()
.equalTo("table", DataCodeEnum.OMDB_RESTRICTION.name) .equalTo("table", DataCodeEnum.OMDB_RESTRICTION.name)
@ -623,23 +813,32 @@ class MainViewModel @Inject constructor(
.equalTo( .equalTo(
"properties['linkIn']", it "properties['linkIn']", it
).findFirst() ).findFirst()
if (entity != null) { if (entityList.isNotEmpty()) {
val outLink = entity.properties["linkOut"] val outList = entityList.distinct()
val linkOutEntity = for (i in outList.indices) {
realmOperateHelper.getSelectTaskRealmTools(RenderEntity::class.java, true) val outLink = outList[i].properties["linkOut"]
.and() val linkOutEntity =
.equalTo("table", DataCodeEnum.OMDB_RD_LINK.name).and() realmOperateHelper.getSelectTaskRealmTools(
.equalTo( RenderEntity::class.java,
"properties['${RenderEntity.Companion.LinkTable.linkPid}']", true
outLink )
).findFirst() .equalTo("table", DataCodeEnum.OMDB_RD_LINK.name).and()
if (linkOutEntity != null) { .equalTo(
mapController.lineHandler.linksLayer.addLine( "properties['${RenderEntity.Companion.LinkTable.linkPid}']",
linkOutEntity.geometry, 0x7DFF0000 outLink
) ).findFirst()
if (linkOutEntity != null) {
mapController.lineHandler.linksLayer.addLine(
linkOutEntity.geometry, 0x7DFF0000
)
}
} }
mapController.lineHandler.linksLayer.addLine(
link.geometry,
Color.BLUE
)
realm.close()
} }
realm.close()
} }
liveDataTopSignList.postValue(topSignList.distinctBy { it.name } liveDataTopSignList.postValue(topSignList.distinctBy { it.name }

View File

@ -37,6 +37,7 @@ class LaneBoundaryAdapter : RecyclerView.Adapter<ViewHolder>() {
fun bind(pos: Int, laneBoundaryItem: LaneBoundaryItem) { fun bind(pos: Int, laneBoundaryItem: LaneBoundaryItem) {
viewBinding.contactName.text = laneBoundaryItem.title viewBinding.contactName.text = laneBoundaryItem.title
if (laneBoundaryItem.itemList != null) { if (laneBoundaryItem.itemList != null) {
viewBinding.infos.removeAllViews()
for (item in laneBoundaryItem.itemList) { for (item in laneBoundaryItem.itemList) {
var view = LayoutInflater.from(viewBinding.root.context) var view = LayoutInflater.from(viewBinding.root.context)
.inflate(R.layout.adapter_two_item, null, false) .inflate(R.layout.adapter_two_item, null, false)

View File

@ -11,15 +11,14 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.navinfo.collect.library.data.dao.impl.TraceDataBase import com.navinfo.collect.library.data.dao.impl.TraceDataBase
import com.navinfo.collect.library.data.entity.HadLinkDvoBean import com.navinfo.collect.library.data.entity.*
import com.navinfo.collect.library.data.entity.NiLocation import com.navinfo.collect.library.enums.DataCodeEnum
import com.navinfo.collect.library.data.entity.QsRecordBean
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.OnGeoPointClickListener import com.navinfo.collect.library.map.OnGeoPointClickListener
import com.navinfo.collect.library.utils.GeometryTools import com.navinfo.collect.library.utils.GeometryTools
import com.navinfo.collect.library.utils.MapParamUtils import com.navinfo.collect.library.utils.MapParamUtils
import com.navinfo.omqs.Constant import com.navinfo.omqs.Constant
import com.navinfo.omqs.bean.Route
import com.navinfo.omqs.db.RealmOperateHelper import com.navinfo.omqs.db.RealmOperateHelper
import com.navinfo.omqs.http.NetResult import com.navinfo.omqs.http.NetResult
import com.navinfo.omqs.http.NetworkService import com.navinfo.omqs.http.NetworkService
@ -149,7 +148,7 @@ class TaskViewModel @Inject constructor(
} }
} }
} }
}else { } else {
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
val links = realmOperateHelper.queryLink( val links = realmOperateHelper.queryLink(
point = point, point = point,
@ -186,7 +185,7 @@ class TaskViewModel @Inject constructor(
/** /**
* 获取任务列表 * 获取任务列表
*/ */
fun loadNetTaskList(context: Context){ fun loadNetTaskList(context: Context) {
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
when (val result = networkService.getTaskList(Constant.USER_ID)) { when (val result = networkService.getTaskList(Constant.USER_ID)) {
is NetResult.Success -> { is NetResult.Success -> {
@ -243,12 +242,12 @@ class TaskViewModel @Inject constructor(
} }
is NetResult.Loading -> {} is NetResult.Loading -> {}
else -> {}
} }
} }
} }
/** /**
* 获取任务列表 * 获取任务列表
*/ */
@ -286,7 +285,7 @@ class TaskViewModel @Inject constructor(
* 设置当前选择的任务并高亮当前任务的所有link * 设置当前选择的任务并高亮当前任务的所有link
*/ */
fun setSelectTaskBean(taskBean: TaskBean) { fun setSelectTaskBean( taskBean: TaskBean) {
sharedPreferences.edit().putInt(Constant.SELECT_TASK_ID, taskBean.id).apply() sharedPreferences.edit().putInt(Constant.SELECT_TASK_ID, taskBean.id).apply()
@ -300,9 +299,10 @@ class TaskViewModel @Inject constructor(
MapParamUtils.setTaskConfig(Constant.currentSelectTaskConfig) MapParamUtils.setTaskConfig(Constant.currentSelectTaskConfig)
mapController.layerManagerHandler.updateOMDBVectorTileLayer() mapController.layerManagerHandler.updateOMDBVectorTileLayer()
mapController.mMapView.updateMap(true) mapController.mMapView.updateMap(true)
} }
private fun showTaskLinks(taskBean: TaskBean) { private fun showTaskLinks(taskBean: TaskBean) {
mapController.lineHandler.removeAllTaskLine() mapController.lineHandler.removeAllTaskLine()

View File

@ -0,0 +1,25 @@
package com.navinfo.omqs.util
import com.navinfo.collect.library.utils.GeometryTools
import com.navinfo.omqs.bean.Route
import org.locationtech.jts.geom.LineString
import org.oscim.core.GeoPoint
class NaviEngine {
var geometry: LineString? = null
var routeList = mutableListOf<Route>()
get() {
return field
}
set(value) {
val list = mutableListOf<GeoPoint>()
list.addAll(value[0].pointList)
for (i in 1 until value.size) {
val list2 = value[i].pointList
list2.removeAt(0)
list.addAll(list2)
}
geometry = GeometryTools.createLineString(list)
field = value
}
}

View File

@ -563,15 +563,57 @@ class SignUtil {
try { try {
val linkList = renderEntity.properties["tollinfoList"] val linkList = renderEntity.properties["tollinfoList"]
if (linkList != null && linkList != "" && linkList != "null") { if (linkList != null && linkList != "" && linkList != "null") {
val itemList = mutableListOf<TwoItemAdapterItem>()
val jsonArray = JSONArray(linkList) val jsonArray = JSONArray(linkList)
for (i in 0 until jsonArray.length()) { for (i in 0 until jsonArray.length()) {
val arrayObject: JSONObject = jsonArray[i] as JSONObject val arrayObject: JSONObject = jsonArray[i] as JSONObject
val itemList = mutableListOf<TwoItemAdapterItem>()
// itemList.add(TwoItemAdapterItem("方向", direct))
try { try {
itemList.add(
TwoItemAdapterItem("通道号码", "${arrayObject.optString("pid")}")
)
val stringBuffer = StringBuffer() val stringBuffer = StringBuffer()
stringBuffer.setLength(0)
val passageType = arrayObject.getInt("passageType")
for (i in 1 downTo 0) {
val bit = (passageType shr i) and 1
if (bit == 1) {
when (i) {
0 -> stringBuffer.append("称重车道 ")
1 -> stringBuffer.append("绿色通道 ")
}
}
}
itemList.add(
TwoItemAdapterItem("通道类型", stringBuffer.toString())
)
stringBuffer.setLength(0)
val payMethod = arrayObject.getInt("payMethod")
for (i in 8 downTo 0) {
val bit = (payMethod shr i) and 1
if (bit == 1) {
when (i) {
0 -> stringBuffer.append("ETC ")
1 -> stringBuffer.append("现金 ")
2 -> stringBuffer.append("银行卡(借记卡) ")
3 -> stringBuffer.append("信用卡 ")
4 -> stringBuffer.append("IC卡 ")
5 -> stringBuffer.append("预付卡 ")
6 -> stringBuffer.append("微信 ")
7 -> stringBuffer.append("支付宝 ")
8 -> stringBuffer.append("其他APP ")
}
}
}
itemList.add(
TwoItemAdapterItem("收费方式", stringBuffer.toString())
)
stringBuffer.setLength(0)
val cardType = arrayObject.getInt("cardType") val cardType = arrayObject.getInt("cardType")
for (i in 2 downTo 0) { for (i in 2 downTo 0) {
val bit = (cardType shr i) and 1 val bit = (cardType shr i) and 1
@ -586,34 +628,18 @@ class SignUtil {
itemList.add( itemList.add(
TwoItemAdapterItem("领卡方式", stringBuffer.toString()) TwoItemAdapterItem("领卡方式", stringBuffer.toString())
) )
} catch (e: Exception) {
Log.e("jingo", "领卡方式 报错 ${e.message}") val seqNum = arrayObject.getInt("seqNum")
} list.add(
try { LaneBoundaryItem(
val stringBuffer = StringBuffer() "车道$seqNum", null, itemList
val passageType = arrayObject.getInt("passageType") )
for (i in 2 downTo 0) {
val bit = (passageType shr i) and 1
if (bit == 1) {
when (i) {
0 -> stringBuffer.append("ETC ")
1 -> stringBuffer.append("人工 ")
2 -> stringBuffer.append("自助 ")
}
}
}
itemList.add(
TwoItemAdapterItem("领卡方式", stringBuffer.toString())
) )
} catch (e: Exception) { } catch (e: Exception) {
Log.e("jingo", "领卡方式 报错 ${e.message}") Log.e("jingo", "领卡方式 报错 ${e.message}")
} }
} }
list.add(
LaneBoundaryItem(
"车道信息", null, itemList
)
)
} }
} catch (e: Exception) { } catch (e: Exception) {
@ -642,9 +668,9 @@ class SignUtil {
try { try {
val linkList = renderEntity.properties["linkList"] val linkList = renderEntity.properties["linkList"]
if (linkList != null && linkList != "" && linkList != "null") { if (linkList != null && linkList != "" && linkList != "null") {
val itemList = mutableListOf<TwoItemAdapterItem>()
val jsonArray = JSONArray(linkList) val jsonArray = JSONArray(linkList)
for (i in 0 until jsonArray.length()) { for (i in 0 until jsonArray.length()) {
val itemList = mutableListOf<TwoItemAdapterItem>()
val arrayObject: JSONObject = jsonArray[i] as JSONObject val arrayObject: JSONObject = jsonArray[i] as JSONObject
val direct = when (arrayObject.getInt("direct")) { val direct = when (arrayObject.getInt("direct")) {
2 -> "顺方向" 2 -> "顺方向"
@ -652,6 +678,7 @@ class SignUtil {
else -> "" else -> ""
} }
itemList.add(TwoItemAdapterItem("方向", direct)) itemList.add(TwoItemAdapterItem("方向", direct))
val featureType = when (arrayObject.getInt("featureType")) { val featureType = when (arrayObject.getInt("featureType")) {
1 -> "LINK" 1 -> "LINK"
2 -> "LINK PA" 2 -> "LINK PA"

View File

@ -102,7 +102,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginRight="@dimen/top_right_drawer_btns_mr" android:layout_marginRight="@dimen/top_right_drawer_btns_mr"
app:constraint_referenced_ids="main_activity_note,main_activity_task_line,main_activity_serach,main_activity_2d_3d,main_activity_camera,main_activity_trace,main_activity_calc_distance,main_activity_menu" app:constraint_referenced_ids="main_activity_add_new,main_activity_task_line,main_activity_serach,main_activity_2d_3d,main_activity_camera,main_activity_trace,main_activity_calc_distance,main_activity_menu"
app:flow_horizontalGap="6dp" app:flow_horizontalGap="6dp"
app:flow_wrapMode="aligned" app:flow_wrapMode="aligned"
app:layout_constraintRight_toLeftOf="@id/main_activity_right_fragment" app:layout_constraintRight_toLeftOf="@id/main_activity_right_fragment"
@ -113,7 +113,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:visibility="invisible" android:visibility="invisible"
app:constraint_referenced_ids="main_activity_serach,main_activity_2d_3d,main_activity_camera,main_activity_trace,main_activity_note,main_activity_task_line,main_activity_calc_distance" /> app:constraint_referenced_ids="main_activity_serach,main_activity_2d_3d,main_activity_camera,main_activity_trace,main_activity_add_new,main_activity_task_line,main_activity_calc_distance" />
<ImageButton <ImageButton
android:id="@+id/main_activity_serach" android:id="@+id/main_activity_serach"
@ -146,10 +146,10 @@
android:src="@drawable/icon_calc_disance" /> android:src="@drawable/icon_calc_disance" />
<ImageButton <ImageButton
android:id="@+id/main_activity_note" android:id="@+id/main_activity_add_new"
style="@style/top_right_drawer_btns_style" style="@style/top_right_drawer_btns_style"
android:onClick="@{()->mainActivity.onClickNewNote()}" android:onClick="@{()->mainActivity.voiceOnclick()}"
android:src="@drawable/icon_menu_note" /> android:src="@drawable/icon_add_data" />
<ImageButton <ImageButton
android:id="@+id/main_activity_task_line" android:id="@+id/main_activity_task_line"
@ -243,7 +243,6 @@
android:paddingBottom="4dp" android:paddingBottom="4dp"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="16sp" android:textSize="16sp"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/main_activity_bottom_sheet" app:layout_constraintBottom_toTopOf="@id/main_activity_bottom_sheet"
app:layout_constraintLeft_toLeftOf="@id/main_activity_top_sign_recyclerview" /> app:layout_constraintLeft_toLeftOf="@id/main_activity_top_sign_recyclerview" />
@ -291,11 +290,11 @@
app:layout_constraintRight_toRightOf="@id/main_activity_map_update" /> app:layout_constraintRight_toRightOf="@id/main_activity_map_update" />
<ImageButton <ImageButton
android:id="@+id/main_activity_add_new" android:id="@+id/main_activity_note"
style="@style/zoom_btns_style" style="@style/zoom_btns_style"
android:layout_marginBottom="12dp" android:layout_marginBottom="12dp"
android:onClick="@{()->mainActivity.voiceOnclick()}" android:onClick="@{()->mainActivity.onClickNewNote()}"
android:src="@drawable/icon_add_data" android:src="@drawable/icon_menu_note"
app:layout_constraintBottom_toTopOf="@id/main_activity_location" app:layout_constraintBottom_toTopOf="@id/main_activity_location"
app:layout_constraintRight_toRightOf="@id/main_activity_location" /> app:layout_constraintRight_toRightOf="@id/main_activity_location" />
@ -305,8 +304,8 @@
android:layout_marginBottom="12dp" android:layout_marginBottom="12dp"
android:onClick="@{()->mainActivity.voiceOnclick()}" android:onClick="@{()->mainActivity.voiceOnclick()}"
android:src="@drawable/icon_add_voice" android:src="@drawable/icon_add_voice"
app:layout_constraintBottom_toTopOf="@id/main_activity_add_new" app:layout_constraintBottom_toTopOf="@id/main_activity_note"
app:layout_constraintRight_toRightOf="@id/main_activity_add_new" /> app:layout_constraintRight_toRightOf="@id/main_activity_note" />
<ImageButton <ImageButton
android:id="@+id/main_activity_select_line" android:id="@+id/main_activity_select_line"
@ -332,13 +331,13 @@
android:id="@+id/main_activity_right_visibility_buttons_group" android:id="@+id/main_activity_right_visibility_buttons_group"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:constraint_referenced_ids="main_activity_close_line,main_activity_select_line,main_activity_voice,main_activity_add_new" /> app:constraint_referenced_ids="main_activity_close_line,main_activity_select_line,main_activity_voice,main_activity_note" />
<androidx.constraintlayout.widget.Group <androidx.constraintlayout.widget.Group
android:id="@+id/main_activity_right_visibility_buttons_group2" android:id="@+id/main_activity_right_visibility_buttons_group2"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:constraint_referenced_ids="main_activity_close_line,main_activity_select_line,main_activity_voice,main_activity_add_new,main_activity_map_update,main_activity_zoom_in,main_activity_zoom_out,main_activity_geometry,main_activity_location" /> app:constraint_referenced_ids="main_activity_close_line,main_activity_select_line,main_activity_voice,main_activity_note,main_activity_map_update,main_activity_zoom_in,main_activity_zoom_out,main_activity_geometry,main_activity_location" />
<fragment <fragment
android:id="@+id/main_activity_middle_fragment" android:id="@+id/main_activity_middle_fragment"

View File

@ -67,7 +67,10 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) :
val errorCode = it.locType val errorCode = it.locType
mCurrentLocation = it mCurrentLocation = it
mLocationLayer.setPosition(it.latitude, it.longitude, it.radius) mLocationLayer.setPosition(it.latitude, it.longitude, it.radius)
Log.e("qj", "location==${it.longitude}==errorCode===$errorCode===${it.locTypeDescription}") Log.e(
"qj",
"location==${it.longitude}==errorCode===$errorCode===${it.locTypeDescription}"
)
getCurrentNiLocation()?.let { it1 -> getCurrentNiLocation()?.let { it1 ->
mContext.lifecycleScope.launch { mContext.lifecycleScope.launch {
@ -212,6 +215,7 @@ private class MyLocationListener(callback: (BDLocation) -> Unit) : BDAbstractLoc
val call = callback; val call = callback;
override fun onReceiveLocation(location: BDLocation) { override fun onReceiveLocation(location: BDLocation) {
call(location) call(location)
Log.e("jingo", "定位结果:速度=" + location.speed +" 方向=" + location.direction)
} }
} }

View File

@ -1,7 +1,12 @@
package com.navinfo.collect.library.utils; package com.navinfo.collect.library.utils;
import android.graphics.Point; import android.graphics.Point;
import android.os.Build;
import android.util.Log; 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.Coordinate;
import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory; import org.locationtech.jts.geom.GeometryFactory;
@ -14,6 +19,7 @@ import org.locationtech.jts.io.WKTReader;
import org.locationtech.jts.operation.linemerge.LineMerger; import org.locationtech.jts.operation.linemerge.LineMerger;
import org.oscim.core.GeoPoint; import org.oscim.core.GeoPoint;
import org.oscim.map.Map; import org.oscim.map.Map;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -416,7 +422,7 @@ public class GeometryTools {
Geometry startGeo = createGeometry(startGeoPoint); Geometry startGeo = createGeometry(startGeoPoint);
Geometry endGeo = createGeometry(endGeoPoint); Geometry endGeo = createGeometry(endGeoPoint);
double d = startGeo.distance(endGeo); double d = startGeo.distance(endGeo);
return convertDistanceToDegree(d,startGeoPoint.getLatitude()); return convertDistanceToDegree(d, startGeoPoint.getLatitude());
} }
return 0; return 0;
@ -589,6 +595,21 @@ public class GeometryTools {
return list; return list;
} }
public static List<GeoPoint> getGeoPoints(Geometry geometry) {
List<GeoPoint> list = null;
if (geometry != null) {
Coordinate[] coordinates = geometry.getCoordinates();
if (coordinates != null && coordinates.length > 0) {
list = new ArrayList<GeoPoint>();
for (Coordinate coor : coordinates) {
list.add(new GeoPoint(coor.y, coor.x));
}
}
}
return list;
}
public static Coordinate[] getCoordinates(String str) { public static Coordinate[] getCoordinates(String str) {
Coordinate[] coordinates = null; Coordinate[] coordinates = null;
if (Check.isEmpty(str)) if (Check.isEmpty(str))
@ -1294,6 +1315,8 @@ public class GeometryTools {
} }
public enum SNAP_TYPE { public enum SNAP_TYPE {
/** /**
* 像素 * 像素
@ -1327,7 +1350,7 @@ public class GeometryTools {
} }
public static boolean isCheckError(double lon, double lat) { public static boolean isCheckError(double lon, double lat) {
if(lon==0||lat==0){ if (lon == 0 || lat == 0) {
return true; return true;
} }
@ -1377,8 +1400,10 @@ public class GeometryTools {
static class Check { static class Check {
public static boolean isEmpty(String str) { public static boolean isEmpty(String str) {
if (str == null || str.isEmpty()) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
return true; if (str == null || str.isEmpty()) {
return true;
}
} }
return false; return false;
} }
@ -1446,7 +1471,7 @@ public class GeometryTools {
switch (unit) { switch (unit) {
case SNAP_PIXEL: case SNAP_PIXEL:
org.oscim.core.Point p = new org.oscim.core.Point(); org.oscim.core.Point p = new org.oscim.core.Point();
fMap.viewport().toScreenPoint(gp,false, p); fMap.viewport().toScreenPoint(gp, false, p);
GeoPoint gPLq = fMap.viewport().fromScreenPoint((float) p.x, (float) p.y); GeoPoint gPLq = fMap.viewport().fromScreenPoint((float) p.x, (float) p.y);
org.oscim.core.Point pL = new org.oscim.core.Point((p.x - distance), (p.y - distance)); org.oscim.core.Point pL = new org.oscim.core.Point((p.x - distance), (p.y - distance));
@ -1521,6 +1546,7 @@ public class GeometryTools {
/** /**
* 计算距离 * 计算距离
*
* @param list * @param list
* @return * @return
*/ */
@ -1573,10 +1599,68 @@ public class GeometryTools {
* @return 对应的地理坐标系中的距离单位 * @return 对应的地理坐标系中的距离单位
*/ */
private static final double EARTH_RADIUS = 6371000.0; private static final double EARTH_RADIUS = 6371000.0;
public static double convertDistanceToDegree(double distance, double latitude) { public static double convertDistanceToDegree(double distance, double latitude) {
double radianDistance = distance / EARTH_RADIUS; double radianDistance = distance / EARTH_RADIUS;
double radianLatitude = Math.toRadians(latitude); double radianLatitude = Math.toRadians(latitude);
double radianDegree = 2 * Math.asin(Math.sin(radianDistance / 2) / Math.cos(radianLatitude)); double radianDegree = 2 * Math.asin(Math.sin(radianDistance / 2) / Math.cos(radianLatitude));
return Math.toDegrees(radianDegree); return Math.toDegrees(radianDegree);
} }
/**
* 经纬度转墨卡托
*/
public static Coordinate geoPointToMercator(GeoPoint point) {
Coordinate coordinate = new Coordinate();
double x = point.getLongitude() * 20037508.34 / 180;
double y = Math.log(Math.tan((90 + point.getLatitude()) * Math.PI / 360)) / (Math.PI / 180);
y = y * 20037508.34 / 180;
coordinate.x = x;
coordinate.y = y;
return coordinate;
}
/**
* 墨卡托转经纬度
*/
public static GeoPoint mercatorToGeoPoint(Coordinate coordinate) {
GeoPoint point = null;
double x = coordinate.x / 20037508.34 * 180;
double y = coordinate.y / 20037508.34 * 180;
y = 180 / Math.PI * (2 * Math.atan(Math.exp(y * Math.PI / 180)) - Math.PI / 2);
point = new GeoPoint(y, x);
return point;
}
public static List<GeoPoint> pointToLineDistance(GeoPoint point, List<GeoPoint> pointList) {
Coordinate coordinate = geoPointToMercator(point);
Coordinate[] cs = new Coordinate[pointList.size()];
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;
}
} }

2
vtm

@ -1 +1 @@
Subproject commit 3031b70699d5d886834d75cc098466daa8cef118 Subproject commit 3ea6a7c90627e6e8ea10b3896004d9082167a7ff