From 7b4229d756374477acae79eba9030e47dc1ba1b5 Mon Sep 17 00:00:00 2001 From: squallzhjch Date: Wed, 21 Jun 2023 10:10:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=81=93=E8=B7=AF=E5=90=8D?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=92=8C=E8=AF=A6=E7=BB=86=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/omdb_config.json | 5 ++ .../com/navinfo/omqs/bean/RoadNameBean.kt | 49 ++++++++++++++++ .../com/navinfo/omqs/db/RealmOperateHelper.kt | 2 +- .../omqs/ui/activity/map/MainActivity.kt | 33 +++++++++-- .../omqs/ui/activity/map/MainViewModel.kt | 37 +++++++----- .../navinfo/omqs/ui/fragment/BaseFragment.kt | 2 +- .../ui/fragment/sign/RoadNameInfoAdapter.kt | 30 ++++++++++ .../ui/fragment/sign/RoadNameInfoFragment.kt | 57 +++++++++++++++++++ .../fragment/tasklist/TaskManagerFragment.kt | 3 +- .../navinfo/omqs/ui/other/ShareViewModel2.kt | 54 ++++++++++++++++++ .../com/navinfo/omqs/ui/widget/SignUtil.kt | 41 +++++++++++++ .../main/res/drawable/baseline_cancel_24.xml | 11 ++++ .../main/res/drawable/shape_road_name_bg.xml | 10 ++++ app/src/main/res/layout/activity_main.xml | 50 ++++++++++++---- app/src/main/res/layout/adapter_road_name.xml | 26 +++++++++ .../res/layout/fragment_sign_roadname.xml | 36 ++++++++++++ 16 files changed, 413 insertions(+), 33 deletions(-) create mode 100644 app/src/main/java/com/navinfo/omqs/bean/RoadNameBean.kt create mode 100644 app/src/main/java/com/navinfo/omqs/ui/fragment/sign/RoadNameInfoAdapter.kt create mode 100644 app/src/main/java/com/navinfo/omqs/ui/fragment/sign/RoadNameInfoFragment.kt create mode 100644 app/src/main/java/com/navinfo/omqs/ui/other/ShareViewModel2.kt create mode 100644 app/src/main/res/drawable/baseline_cancel_24.xml create mode 100644 app/src/main/res/drawable/shape_road_name_bg.xml create mode 100644 app/src/main/res/layout/adapter_road_name.xml create mode 100644 app/src/main/res/layout/fragment_sign_roadname.xml diff --git a/app/src/main/assets/omdb_config.json b/app/src/main/assets/omdb_config.json index 1060acc8..6d19017d 100644 --- a/app/src/main/assets/omdb_config.json +++ b/app/src/main/assets/omdb_config.json @@ -20,6 +20,11 @@ "code": 2010, "name": "道路方向" }, + "2011": { + "table": "OMDB_LINK_NAME", + "code": 2011, + "name": "道路名" + }, "2013": { "table": "OMDB_LANE_MARK_BOUNDARYTYPE", "code": 2013, diff --git a/app/src/main/java/com/navinfo/omqs/bean/RoadNameBean.kt b/app/src/main/java/com/navinfo/omqs/bean/RoadNameBean.kt new file mode 100644 index 00000000..db19a444 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/bean/RoadNameBean.kt @@ -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 "" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/db/RealmOperateHelper.kt b/app/src/main/java/com/navinfo/omqs/db/RealmOperateHelper.kt index 30aef395..8edb79c4 100644 --- a/app/src/main/java/com/navinfo/omqs/db/RealmOperateHelper.kt +++ b/app/src/main/java/com/navinfo/omqs/db/RealmOperateHelper.kt @@ -44,7 +44,7 @@ class RealmOperateHelper() { ) // 根据polygon查询相交的tile号 val tileXSet = mutableSetOf() - tileXSet.toString() + GeometryToolsKt.getTileXByGeometry(polygon.toString(), tileXSet) val tileYSet = mutableSetOf() GeometryToolsKt.getTileYByGeometry(polygon.toString(), tileYSet) diff --git a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt index c46932f7..96ef7c51 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt @@ -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() + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt index 78e29e3f..65b232d4 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt @@ -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>() + //道路名 + val liveDataRoadName = MutableLiveData?>() // 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() @@ -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) + } } } diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/BaseFragment.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/BaseFragment.kt index a0882082..1ecd8194 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/BaseFragment.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/BaseFragment.kt @@ -50,7 +50,7 @@ abstract class BaseFragment : Fragment() { // ): View fun onBackPressed(): Boolean{ - findNavController().navigateUp() +// findNavController().navigateUp() return true } diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/sign/RoadNameInfoAdapter.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/sign/RoadNameInfoAdapter.kt new file mode 100644 index 00000000..eb853924 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/sign/RoadNameInfoAdapter.kt @@ -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() { + 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() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/sign/RoadNameInfoFragment.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/sign/RoadNameInfoFragment.kt new file mode 100644 index 00000000..137fa3a5 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/sign/RoadNameInfoFragment.kt @@ -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() + 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 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskManagerFragment.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskManagerFragment.kt index ec11bd80..63285395 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskManagerFragment.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskManagerFragment.kt @@ -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!! diff --git a/app/src/main/java/com/navinfo/omqs/ui/other/ShareViewModel2.kt b/app/src/main/java/com/navinfo/omqs/ui/other/ShareViewModel2.kt new file mode 100644 index 00000000..dbcb22d9 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/ui/other/ShareViewModel2.kt @@ -0,0 +1,54 @@ +//package com.navinfo.omqs.ui.other +// +//import androidx.lifecycle.* +// +//val vMStoreMap = HashMap() +// +//inline fun LifecycleOwner.shareViewModels( +// scopeName: String, +// factory: ViewModelProvider.Factory? = null +//): Lazy { +// 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() +// 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!! +// } +//} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/widget/SignUtil.kt b/app/src/main/java/com/navinfo/omqs/ui/widget/SignUtil.kt index 773e55e0..f4260e94 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/widget/SignUtil.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/widget/SignUtil.kt @@ -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 { + val list = mutableListOf() + 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 + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/baseline_cancel_24.xml b/app/src/main/res/drawable/baseline_cancel_24.xml new file mode 100644 index 00000000..082ea0a2 --- /dev/null +++ b/app/src/main/res/drawable/baseline_cancel_24.xml @@ -0,0 +1,11 @@ + + + + diff --git a/app/src/main/res/drawable/shape_road_name_bg.xml b/app/src/main/res/drawable/shape_road_name_bg.xml new file mode 100644 index 00000000..7b1a14f6 --- /dev/null +++ b/app/src/main/res/drawable/shape_road_name_bg.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 77fc36a0..fc72fe88 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -44,25 +44,36 @@ app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> - + + + + + + + + @@ -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" diff --git a/app/src/main/res/layout/adapter_road_name.xml b/app/src/main/res/layout/adapter_road_name.xml new file mode 100644 index 00000000..4a4d65dd --- /dev/null +++ b/app/src/main/res/layout/adapter_road_name.xml @@ -0,0 +1,26 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_sign_roadname.xml b/app/src/main/res/layout/fragment_sign_roadname.xml new file mode 100644 index 00000000..b657f832 --- /dev/null +++ b/app/src/main/res/layout/fragment_sign_roadname.xml @@ -0,0 +1,36 @@ + + + + + + + + + \ No newline at end of file