增加道路名显示和详细信息功能

This commit is contained in:
squallzhjch 2023-06-21 10:10:21 +08:00
parent 1fe90ccf26
commit 7b4229d756
16 changed files with 413 additions and 33 deletions

View File

@ -20,6 +20,11 @@
"code": 2010,
"name": "道路方向"
},
"2011": {
"table": "OMDB_LINK_NAME",
"code": 2011,
"name": "道路名"
},
"2013": {
"table": "OMDB_LANE_MARK_BOUNDARYTYPE",
"code": 2013,

View File

@ -0,0 +1,49 @@
package com.navinfo.omqs.bean
data class RoadNameBean(
/**
* 道路名称
*/
val name: String = "",
/**
* 0 普通
* 1 立交桥名连接路
* 2 立交桥名 主路
* 3 风景线路
* 5 隧道
* 6 虚拟名称
*/
val type: Int = 0,
/**
* 1 不论名称分类是官方名别名还是曾用名都统一从1开始递增
* 2 若取第一官方名时需判断名称分类 [nameClass]=="官方名"[seqNum] 最小的
*/
val seqNum: Int = 1,
/**
* 1 官方名
* 2 别名
* 3 曾用名
*/
val nameClass: Int = 1,
) {
fun getNameClassStr(): String {
when (nameClass) {
1 -> return "官方名"
2 -> return "别名"
3 -> return "曾用名"
}
return ""
}
fun getTypeStr(): String {
when (type) {
0 -> return "普通"
1 -> return "立交桥名(连接路)"
2 -> return "立交桥名(主路)"
3 -> return "风景线路"
5 -> return "隧道"
6 -> return "虚拟名称"
}
return ""
}
}

View File

@ -44,7 +44,7 @@ class RealmOperateHelper() {
)
// 根据polygon查询相交的tile号
val tileXSet = mutableSetOf<Int>()
tileXSet.toString()
GeometryToolsKt.getTileXByGeometry(polygon.toString(), tileXSet)
val tileYSet = mutableSetOf<Int>()
GeometryToolsKt.getTileYByGeometry(polygon.toString(), tileYSet)

View File

@ -31,6 +31,7 @@ import com.navinfo.omqs.ui.activity.BaseActivity
import com.navinfo.omqs.ui.fragment.console.ConsoleFragment
import com.navinfo.omqs.ui.fragment.offlinemap.OfflineMapFragment
import com.navinfo.omqs.ui.fragment.qsrecordlist.QsRecordListFragment
import com.navinfo.omqs.ui.fragment.sign.RoadNameInfoFragment
import com.navinfo.omqs.ui.fragment.tasklist.TaskManagerFragment
import com.navinfo.omqs.ui.widget.RecyclerViewSpacesItemDecoration
import com.navinfo.omqs.util.FlowEventBus
@ -56,6 +57,7 @@ class MainActivity : BaseActivity() {
*/
private var leftFragment: Fragment? = null
/**
* 是否开启右侧面板
*/
@ -150,8 +152,6 @@ class MainActivity : BaseActivity() {
checkIntent.action = TextToSpeech.Engine.ACTION_CHECK_TTS_DATA
someActivityResultLauncher.launch(checkIntent)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
//初始化地图
@ -184,12 +184,12 @@ class MainActivity : BaseActivity() {
}
v?.onTouchEvent(event) ?: true
}
//捕捉列表变化回调
viewModel.liveDataQsRecordIdList.observe(this) {
//处理页面跳转
viewModel.navigationRightFragment(this, it)
}
//右上角菜单是否被点击
viewModel.liveDataMenuState.observe(this) {
binding.mainActivityMenu.isSelected = it
if (it == true) {
@ -198,6 +198,17 @@ class MainActivity : BaseActivity() {
binding.mainActivityMenuGroup.visibility = View.INVISIBLE
}
}
//道路绑定,名称变化
viewModel.liveDataRoadName.observe(this) {
if (it != null && it.isNotEmpty()) {
binding.mainActivityRoadName.text = it[0].name
if (binding.mainActivityRoadName.visibility != View.VISIBLE)
binding.mainActivityRoadName.visibility = View.VISIBLE
} else {
if (binding.mainActivityRoadName.visibility != View.GONE)
binding.mainActivityRoadName.visibility = View.GONE
}
}
//道路属性面板
binding.mainActivityTopSignRecyclerview.layoutManager = LinearLayoutManager(
@ -228,6 +239,7 @@ class MainActivity : BaseActivity() {
viewModel.liveDataTopSignList.observe(this) {
topSignAdapter.refreshData(it)
}
//监听地图中点变化
viewModel.liveDataCenterPoint.observe(this) {
Log.e("qj", "${it.longitude}")
@ -533,4 +545,17 @@ class MainActivity : BaseActivity() {
.replace(R.id.main_activity_left_fragment, leftFragment!!).commit()
}
}
/**
* 打开道路名称属性看板
*/
fun openRoadNameFragment() {
val fragment =
supportFragmentManager.findFragmentById(R.id.main_activity_sign_more_info_fragment)
if (fragment !is RoadNameInfoFragment) {
supportFragmentManager.beginTransaction()
.replace(R.id.main_activity_sign_more_info_fragment, RoadNameInfoFragment())
.commit()
}
}
}

View File

@ -31,6 +31,7 @@ import com.navinfo.collect.library.utils.GeometryToolsKt
import com.navinfo.omqs.Constant
import com.navinfo.omqs.R
import com.navinfo.omqs.bean.ImportConfig
import com.navinfo.omqs.bean.RoadNameBean
import com.navinfo.omqs.bean.SignBean
import com.navinfo.omqs.db.RealmOperateHelper
import com.navinfo.omqs.ui.dialog.CommonDialog
@ -76,6 +77,8 @@ class MainViewModel @Inject constructor(
//顶部看板数据
val liveDataTopSignList = MutableLiveData<List<SignBean>>()
//道路名
val liveDataRoadName = MutableLiveData<List<RoadNameBean>?>()
// var testPoint = GeoPoint(0, 0)
//uuid标识用于记录轨迹组
@ -107,8 +110,8 @@ class MainViewModel @Inject constructor(
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.SCALE_EVENT, Map.MOVE_EVENT, Map.ROTATE_EVENT -> liveDataCenterPoint.value =
mapPosition
}
})
@ -213,6 +216,7 @@ class MainViewModel @Inject constructor(
val linkList = realmOperateHelper.queryLink(
point = point,
)
var hisRoadName = false
if (linkList.isNotEmpty()) {
//看板数据
val signList = mutableListOf<SignBean>()
@ -225,11 +229,17 @@ class MainViewModel @Inject constructor(
if (linkIdCache != linkId) {
Log.e("jingo", "捕捉到的linkid $linkId ${link.geometry}")
mapController.lineHandler.showLine(link.geometry)
linkId?.let {
var elementList = realmOperateHelper.queryLinkByLinkPid(it)
for (element in elementList) {
if (element.code == 2011) {
hisRoadName = true
liveDataRoadName.postValue(SignUtil.getRoadNameList(element))
continue
}
val distance = GeometryTools.distanceToDouble(
point, GeometryTools.createGeoPoint(element.geometry)
)
@ -246,7 +256,7 @@ class MainViewModel @Inject constructor(
elementCode = element.code,
moreText = SignUtil.getMoreInfoText(element)
)
Log.e("jingo", "捕捉到的数据code ${element.code}")
when (element.code) {
2002, 2008, 2010, 2041 -> topSignList.add(
signBean
@ -260,27 +270,20 @@ class MainViewModel @Inject constructor(
val realm = Realm.getDefaultInstance()
val entity = realm.where(RenderEntity::class.java)
.equalTo("table", "OMDB_RESTRICTION")
.and()
.equalTo(
"properties['linkIn']",
it
.equalTo("table", "OMDB_RESTRICTION").and().equalTo(
"properties['linkIn']", it
).findFirst()
if (entity != null) {
val outLink = entity.properties["linkOut"]
val linkOutEntity = realm.where(RenderEntity::class.java)
.equalTo("table", "OMDB_RD_LINK")
.and()
.equalTo(
.equalTo("table", "OMDB_RD_LINK").and().equalTo(
"properties['${RenderEntity.Companion.LinkTable.linkPid}']",
outLink
).findFirst()
if (linkOutEntity != null) {
mapController.lineHandler.linksLayer.addLine(
linkOutEntity.geometry,
0x7DFF0000
linkOutEntity.geometry, 0x7DFF0000
)
Log.e("jingo", "捕捉到的linkid $outLink ${linkOutEntity.geometry}")
}
}
}
@ -297,6 +300,10 @@ class MainViewModel @Inject constructor(
mapController.lineHandler.removeLine()
linkIdCache = ""
}
//如果没有捕捉到道路名
if (!hisRoadName) {
liveDataRoadName.postValue(null)
}
}
}

View File

@ -50,7 +50,7 @@ abstract class BaseFragment : Fragment() {
// ): View
fun onBackPressed(): Boolean{
findNavController().navigateUp()
// findNavController().navigateUp()
return true
}

View File

@ -0,0 +1,30 @@
package com.navinfo.omqs.ui.fragment.sign
import android.view.LayoutInflater
import android.view.ViewGroup
import com.navinfo.omqs.R
import com.navinfo.omqs.bean.RoadNameBean
import com.navinfo.omqs.databinding.AdapterRoadNameBinding
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
import com.navinfo.omqs.ui.other.BaseViewHolder
class RoadNameInfoAdapter : BaseRecyclerViewAdapter<RoadNameBean>() {
override fun getItemViewRes(position: Int): Int {
return R.layout.adapter_road_name
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
val viewBinding =
AdapterRoadNameBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return BaseViewHolder(viewBinding)
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
val binding: AdapterRoadNameBinding =
holder.viewBinding as AdapterRoadNameBinding
val bean = data[position]
binding.title.text = bean.getNameClassStr()
binding.name.text = bean.name
binding.type.text = bean.getTypeStr()
}
}

View File

@ -0,0 +1,57 @@
package com.navinfo.omqs.ui.fragment.sign
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.LinearLayoutManager
import com.navinfo.omqs.databinding.FragmentSignRoadnameBinding
import com.navinfo.omqs.ui.activity.map.MainViewModel
import com.navinfo.omqs.ui.fragment.BaseFragment
class RoadNameInfoFragment : BaseFragment() {
private var _binding: FragmentSignRoadnameBinding? = null
private val binding get() = _binding!!
private val viewModel by activityViewModels<MainViewModel>()
private val adapter by lazy { RoadNameInfoAdapter() }
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
_binding = FragmentSignRoadnameBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val layoutManager = LinearLayoutManager(context)
//// 设置 RecyclerView 的固定大小,避免在滚动时重新计算视图大小和布局,提高性能
binding.roadnameRecyclerview.setHasFixedSize(true)
binding.roadnameRecyclerview.layoutManager = layoutManager
binding.roadnameRecyclerview.adapter = adapter
viewModel.liveDataRoadName.observe(viewLifecycleOwner) {
if (it != null && it.isNotEmpty()) {
adapter.refreshData(it)
} else {
activity?.run {
supportFragmentManager.beginTransaction().remove(this@RoadNameInfoFragment)
.commit()
}
}
}
binding.roadnameCancel.setOnClickListener {
activity?.run {
supportFragmentManager.beginTransaction().remove(this@RoadNameInfoFragment)
.commit()
}
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@ -15,7 +15,8 @@ import dagger.hilt.android.AndroidEntryPoint
* 评测任务viewpager管理页面
*/
@AndroidEntryPoint
class TaskManagerFragment(private var backListener: ((TaskManagerFragment) -> Unit?)? = null) : BaseFragment() {
class TaskManagerFragment(private var backListener: ((TaskManagerFragment) -> Unit?)? = null) :
BaseFragment() {
private var _binding: FragmentTaskManagerBinding? = null
private val binding get() = _binding!!

View File

@ -0,0 +1,54 @@
//package com.navinfo.omqs.ui.other
//
//import androidx.lifecycle.*
//
//val vMStoreMap = HashMap<String, VMStoreClass>()
//
//inline fun <reified VM : ViewModel> LifecycleOwner.shareViewModels(
// scopeName: String,
// factory: ViewModelProvider.Factory? = null
//): Lazy<VM> {
// val store: VMStoreClass
// if (vMStoreMap.keys.contains(scopeName)) {
// store = vMStoreMap[scopeName]!!
// } else {
// store = VMStoreClass()
// vMStoreMap[scopeName] = store
// }
// store.register(this)
// return ViewModelLazy(VM::class,
// { store.viewModelStore },
// { factory ?: ViewModelProvider.NewInstanceFactory() })
//}
//
//class VMStoreClass : ViewModelStoreOwner {
//
// private val bindTargets = ArrayList<LifecycleOwner>()
// private var vmStore: ViewModelStore? = null
//
// fun register(host: LifecycleOwner) {
// if (!bindTargets.contains(host)) {
// bindTargets.add(host)
// host.lifecycle.addObserver(object : LifecycleEventObserver {
// override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
// if (event == Lifecycle.Event.ON_DESTROY) {
// host.lifecycle.removeObserver(this)
// bindTargets.remove(host)
// if (bindTargets.isEmpty()) {//如果当前商店没有关联对象,则释放资源
// vMStoreMap.entries.find { it.value == this@VMStoreClass }?.also {
// vmStore?.clear()
// vMStoreMap.remove(it.key)
// }
// }
// }
// }
// })
// }
// }
//
// override fun getViewModelStore(): ViewModelStore {
// if (vmStore == null)
// vmStore = ViewModelStore()
// return vmStore!!
// }
//}

View File

@ -1,9 +1,12 @@
package com.navinfo.omqs.ui.widget
import android.util.Log
import com.google.gson.Gson
import com.navinfo.collect.library.data.entity.RenderEntity
import com.navinfo.omqs.R
import com.navinfo.omqs.bean.RoadNameBean
import com.navinfo.omqs.bean.SignBean
import org.json.JSONArray
class SignUtil {
companion object {
@ -329,5 +332,43 @@ class SignUtil {
}
return stringBuffer.toString()
}
fun getRoadNameList(data: RenderEntity): MutableList<RoadNameBean> {
val list = mutableListOf<RoadNameBean>()
if (data.code == 2011) {
try {
val shapeStr = data.properties["shapeList"]
val array = JSONArray(shapeStr)
for (i in 0 until array.length()) {
val jsonObject = array.getJSONObject(0)
val name = jsonObject.optString("name", "")
val type = jsonObject.optInt("nameType", 0)
val seqNum = jsonObject.optInt("seqNum", 1)
val nameClass = jsonObject.optInt("nameClass", 1)
val bean = RoadNameBean(
name = name,
type = type,
seqNum = seqNum,
nameClass = nameClass
)
list.add(bean)
}
/**
* 排序
*/
list.sortWith { n1, n2 ->
if (n1.nameClass != n2.nameClass) {
n1.nameClass.compareTo(n2.nameClass)
} else {
n1.seqNum.compareTo(n2.seqNum)
}
}
} catch (e: Exception) {
}
}
return list
}
}
}

View File

@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#91909A"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M13,7zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z,M12,2zM17,15.59L15.59,17 12,13.41 8.41,17 7,15.59 10.59,12 7,8.41 8.41,7 12,10.59 15.59,7 17,8.41 13.41,12 17,15.59z" />
</vector>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#BA0C122B" />
<corners
android:bottomLeftRadius="6dp"
android:bottomRightRadius="6dp"
android:topLeftRadius="6dp"
android:topRightRadius="6dp" />
</shape>

View File

@ -44,25 +44,36 @@
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/main_activity_top_sign_recyclerview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/main_activity_sign_recyclerview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:layout_marginTop="2dp"
android:maxHeight="350dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/main_activity_top_sign_recyclerview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="280dp"
android:layout_marginTop="2dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout
android:id="@+id/main_activity_sign_more_info_fragment"
android:layout_width="240dp"
android:layout_height="wrap_content"
android:layout_marginTop="80dp"
android:minHeight="140dp"
app:layout_constraintLeft_toLeftOf="@id/main_activity_top_sign_recyclerview"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/main_activity_sign_more_info_bg"
android:layout_width="240dp"
@ -229,6 +240,23 @@
app:layout_constraintBottom_toTopOf="@id/main_activity_bottom_sheet_bg"
app:layout_constraintRight_toLeftOf="@id/main_activity_middle_fragment" />
<TextView
android:id="@+id/main_activity_road_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_road_name_bg"
android:onClick="@{()->mainActivity.openRoadNameFragment()}"
android:paddingLeft="10dp"
android:paddingTop="4dp"
android:paddingRight="10dp"
android:paddingBottom="4dp"
android:textColor="@color/white"
android:textSize="16sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/main_activity_geometry"
app:layout_constraintLeft_toLeftOf="@id/main_activity_top_sign_recyclerview" />
<ImageButton
android:id="@+id/main_activity_zoom_out"
android:layout_width="@dimen/zoom_btns_w"
@ -421,9 +449,9 @@
android:id="@+id/main_bottom_route"
style="@style/main_activity_bottom_sheet_icon"
android:background="@drawable/icon_main_bottom_route"
android:onClick="@{()->mainActivity.onClickRouteFragment()}"
app:layout_constraintBottom_toTopOf="@id/main_bottom_route_text"
app:layout_constraintLeft_toRightOf="@id/main_bottom_offline_map"
android:onClick="@{()->mainActivity.onClickRouteFragment()}"
app:layout_constraintRight_toRightOf="@id/main_activity_bottom_sheet_bg"
app:layout_constraintTop_toTopOf="@id/main_bottom_task"
app:layout_constraintVertical_chainStyle="packed" />
@ -432,10 +460,10 @@
android:id="@+id/main_bottom_route_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{()->mainActivity.onClickRouteFragment()}"
android:text="路径规划"
android:textColor="@color/blue"
android:textSize="10sp"
android:onClick="@{()->mainActivity.onClickRouteFragment()}"
app:layout_constraintBottom_toBottomOf="@id/main_activity_bottom_sheet_bg"
app:layout_constraintLeft_toLeftOf="@id/main_bottom_route"
app:layout_constraintRight_toRightOf="@id/main_bottom_route"

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@id/title"
android:textColor="@color/white" />
<TextView
android:id="@+id/type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:textColor="@color/white" />
</RelativeLayout>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:clickable="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/main_sign_moreinfo_bg"
android:padding="8dp"
tools:context=".ui.fragment.sign.RoadNameInfoFragment">
<TextView
android:id="@+id/roadname_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/icon_main_moreinfo_text_left"
android:drawablePadding="4dp"
android:text="条件点限速"
android:textColor="@color/orange" />
<ImageView
android:id="@+id/roadname_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/roadname_title"
android:layout_alignBottom="@id/roadname_title"
android:layout_alignParentRight="true"
android:src="@drawable/baseline_cancel_24" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/roadname_recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/roadname_title"
android:layout_marginTop="5dp" />
</RelativeLayout>