diff --git a/app/build.gradle b/app/build.gradle index ca4fa52f..f6479027 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -133,6 +133,8 @@ dependencies { annotationProcessor 'com.github.bumptech.glide:compiler:4.15.1' // implementation "io.realm:realm-kotlin-extensions:6.1.0" + //带侧滑的自定义列表 + implementation 'com.yanzhenjie.recyclerview:x:1.3.2' } //允许引用生成的代码 kapt { 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 8edb79c4..a1a02fd4 100644 --- a/app/src/main/java/com/navinfo/omqs/db/RealmOperateHelper.kt +++ b/app/src/main/java/com/navinfo/omqs/db/RealmOperateHelper.kt @@ -3,6 +3,7 @@ package com.navinfo.omqs.db import android.os.Build import android.util.Log import androidx.annotation.RequiresApi +import com.navinfo.collect.library.data.entity.HadLinkDvoBean import com.navinfo.collect.library.data.entity.RenderEntity import com.navinfo.collect.library.data.entity.RenderEntity.Companion.LinkTable import com.navinfo.collect.library.map.NIMapController @@ -85,6 +86,39 @@ class RealmOperateHelper() { } + suspend fun captureTaskLink( + taskId: Int, + point: GeoPoint, + buffer: Double = DEFAULT_BUFFER, + bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE, + ): HadLinkDvoBean? { + + val polygon = getPolygonFromPoint( + GeometryTools.createPoint(point.longitude, point.latitude), + buffer, + bufferType + ) + + val realm = Realm.getDefaultInstance() + val realmList = realm.where(HadLinkDvoBean::class.java) + .equalTo("taskId", taskId) + .findAll() + var linkBean: HadLinkDvoBean? = null + var nearLast: Double = 99999.99 + for (link in realmList) { + if (polygon.intersects(GeometryTools.createGeometry(link.geometry))) { + val near = point.distance(GeometryTools.createGeoPoint(link.geometry)) + if (near < nearLast) { + nearLast = near + linkBean = link + } + } + } + if (linkBean != null) + return realm.copyFromRealm(linkBean) + return null + } + suspend fun queryLink(linkPid: String): RenderEntity? { var link: RenderEntity? = null withContext(Dispatchers.IO) { @@ -237,6 +271,8 @@ class RealmOperateHelper() { Log.d("queryLink", wkt.toString()) return wkt } + + } enum class BUFFER_TYPE(val index: Int) { diff --git a/app/src/main/java/com/navinfo/omqs/http/taskupload/TaskUploadScope.kt b/app/src/main/java/com/navinfo/omqs/http/taskupload/TaskUploadScope.kt index 19e28738..41b948ef 100644 --- a/app/src/main/java/com/navinfo/omqs/http/taskupload/TaskUploadScope.kt +++ b/app/src/main/java/com/navinfo/omqs/http/taskupload/TaskUploadScope.kt @@ -163,7 +163,8 @@ class TaskUploadScope( var s: String = "%.3f".format(hadLinkDvoBean.length)//保留一位小数(且支持四舍五入) val objects = realm.where(QsRecordBean::class.java) - .equalTo("linkId", /*"84207223282277331"*/hadLinkDvoBean.linkPid).findAll() + .equalTo("linkId", /*"84207223282277331"*/hadLinkDvoBean.linkPid).and() + .equalTo("taskId", hadLinkDvoBean.taskId).findAll() if (objects != null && objects.size > 0) { val copyList = realm.copyFromRealm(objects) @@ -183,7 +184,7 @@ class TaskUploadScope( var dataLevel = 0 - if(hadLinkDvoBean.linkInfo!=null){ + if (hadLinkDvoBean.linkInfo != null) { roadClassfcation = hadLinkDvoBean.linkInfo!!.kind roadFunctionGrade = hadLinkDvoBean.linkInfo!!.functionLevel dataLevel = hadLinkDvoBean.linkInfo!!.dataLevel 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 db09aa62..d4747786 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 @@ -106,7 +106,6 @@ class MainActivity : BaseActivity() { } //点击详细信息 - @RequiresApi(Build.VERSION_CODES.N) override fun onMoreInfoClick(selectTag: String, tag: String, signBean: SignBean) { viewModel.showSignMoreInfo(signBean.renderEntity) val fragment = @@ -147,7 +146,6 @@ class MainActivity : BaseActivity() { } - @RequiresApi(Build.VERSION_CODES.N) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -226,8 +224,7 @@ class MainActivity : BaseActivity() { val bundle = Bundle() bundle.putString("TaskLinkId", it) findNavController(R.id.main_activity_right_fragment).navigate( - R.id.TaskLinkFragment, - bundle + R.id.TaskLinkFragment, bundle ) } @@ -382,7 +379,6 @@ class MainActivity : BaseActivity() { mapController.mMapView.onPause() } - @RequiresApi(Build.VERSION_CODES.N) override fun onDestroy() { super.onDestroy() viewModel.speakMode?.shutdown() @@ -413,7 +409,6 @@ class MainActivity : BaseActivity() { /** * 打开相机预览 */ - @RequiresApi(Build.VERSION_CODES.N) fun openCamera() { //显示轨迹图层 viewModel.onClickCameraButton(this) @@ -422,7 +417,6 @@ class MainActivity : BaseActivity() { /** * 开关菜单 */ - @RequiresApi(Build.VERSION_CODES.N) fun onClickMenu() { //显示菜单图层 viewModel.onClickMenu() @@ -530,7 +524,6 @@ class MainActivity : BaseActivity() { /** * 点击线选择 */ - @RequiresApi(Build.VERSION_CODES.N) fun selectLineOnclick() { viewModel.setSelectRoad(!viewModel.isSelectRoad()) binding.mainActivitySelectLine.isSelected = viewModel.isSelectRoad() @@ -539,7 +532,6 @@ class MainActivity : BaseActivity() { /** * 点击线选择 */ - @RequiresApi(Build.VERSION_CODES.N) fun tracePointsOnclick() { viewModel.setSelectTrace(!viewModel.isSelectTrace()) if (viewModel.isSelectTrace()) { @@ -551,7 +543,6 @@ class MainActivity : BaseActivity() { /** * 点击结束轨迹操作 */ - @RequiresApi(Build.VERSION_CODES.N) fun finishTraceOnclick() { setIndoorGroupEnable(false) viewModel.setSelectTrace(false) @@ -565,7 +556,6 @@ class MainActivity : BaseActivity() { /** * 点击结束轨迹操作 */ - @RequiresApi(Build.VERSION_CODES.N) fun mediaFlagOnclick() { viewModel.setMediaFlag(!viewModel.isMediaFlag()) binding.mainActivitySnapshotMediaFlag.isSelected = viewModel.isMediaFlag() @@ -574,7 +564,6 @@ class MainActivity : BaseActivity() { /** * 点击上一个轨迹点播放操作 */ - @RequiresApi(Build.VERSION_CODES.N) fun rewindTraceOnclick() { pasePlayTrace() } @@ -582,7 +571,6 @@ class MainActivity : BaseActivity() { /** * 点击暂停播放轨迹操作 */ - @RequiresApi(Build.VERSION_CODES.N) fun pauseTraceOnclick() { viewModel.setSelectPauseTrace(!viewModel.isSelectPauseTrace()) binding.mainActivitySnapshotPause.isSelected = viewModel.isSelectPauseTrace() @@ -593,12 +581,10 @@ class MainActivity : BaseActivity() { /** * 点击下一个轨迹点 */ - @RequiresApi(Build.VERSION_CODES.N) fun nextTraceOnclick() { pasePlayTrace() } - @RequiresApi(Build.VERSION_CODES.N) fun pasePlayTrace() { viewModel.setSelectTrace(false) binding.mainActivityTraceSnapshotPoints.isSelected = viewModel.isSelectTrace() @@ -625,8 +611,7 @@ class MainActivity : BaseActivity() { binding.mainActivityBottomSheetGroup.visibility = View.VISIBLE mapController.mMapView.setScaleBarLayer(GLViewport.Position.BOTTOM_CENTER, 128, 65) } - mapController.mMapView.vtmMap.animator() - .animateTo( + mapController.mMapView.vtmMap.animator().animateTo( GeoPoint( mapController.mMapView.vtmMap.mapPosition.geoPoint.latitude, mapController.mMapView.vtmMap.mapPosition.geoPoint.longitude @@ -634,7 +619,6 @@ class MainActivity : BaseActivity() { ) } - @RequiresApi(Build.VERSION_CODES.N) private fun voiceOnTouchStart() { viewModel.startSoundMetter(this, binding.mainActivityVoice) } @@ -738,7 +722,6 @@ class MainActivity : BaseActivity() { /** * 打开道路名称属性看板,选择的道路在viewmodel里记录,不用 */ - @RequiresApi(Build.VERSION_CODES.N) fun openRoadNameFragment() { if (viewModel.liveDataRoadName.value != null) { viewModel.showSignMoreInfo(viewModel.liveDataRoadName.value!!) 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 a8402389..e62cc5d0 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 @@ -18,13 +18,15 @@ import android.widget.PopupWindow import androidx.annotation.RequiresApi import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel -import androidx.lifecycle.lifecycleScope import androidx.lifecycle.viewModelScope import androidx.navigation.findNavController import com.blankj.utilcode.util.ToastUtils import com.navinfo.collect.library.data.dao.impl.TraceDataBase import com.navinfo.collect.library.data.entity.* import com.navinfo.collect.library.map.NIMapController +import com.navinfo.collect.library.map.OnGeoPointClickListener +import com.navinfo.collect.library.map.handler.ONNoteItemClickListener +import com.navinfo.collect.library.map.handler.OnNiLocationItemListener import com.navinfo.collect.library.map.handler.OnQsRecordItemClickListener import com.navinfo.collect.library.map.handler.OnTaskLinkItemClickListener import com.navinfo.collect.library.utils.GeometryTools @@ -60,14 +62,15 @@ import javax.inject.Inject * 创建Activity全局viewmode */ -@RequiresApi(Build.VERSION_CODES.N) @HiltViewModel class MainViewModel @Inject constructor( private val mapController: NIMapController, private val traceDataBase: TraceDataBase, private val realmOperateHelper: RealmOperateHelper, private val sharedPreferences: SharedPreferences -) : ViewModel() { +) : ViewModel(), SharedPreferences.OnSharedPreferenceChangeListener { + + private val TAG = "MainViewModel" private var mCameraDialog: CommonDialog? = null @@ -97,6 +100,16 @@ class MainViewModel @Inject constructor( */ val liveDataSignMoreInfo = MutableLiveData() + /** + * 右上角菜单状态 + */ + val liveDataMenuState = MutableLiveData() + + /** + * 地图中心坐标 + */ + val liveDataCenterPoint = MutableLiveData() + // var testPoint = GeoPoint(0, 0) //uuid标识,用于记录轨迹组 @@ -116,9 +129,7 @@ class MainViewModel @Inject constructor( var captureLinkState: Boolean = false - val liveDataMenuState = MutableLiveData() - - val liveDataCenterPoint = MutableLiveData() + var currentTaskBean: TaskBean? = null /** * 是不是线选择模式 @@ -145,6 +156,7 @@ class MainViewModel @Inject constructor( private var lastNiLocaion: NiLocation? = null init { + mapController.mMapView.vtmMap.events.bind(Map.UpdateListener { e, mapPosition -> when (e) { Map.SCALE_EVENT, Map.MOVE_EVENT, Map.ROTATE_EVENT -> liveDataCenterPoint.value = @@ -152,76 +164,114 @@ class MainViewModel @Inject constructor( } }) - //处理质检数据点击事件 - mapController.markerHandle.setOnQsRecordItemClickListener(object : - OnQsRecordItemClickListener { - override fun onQsRecordList(list: MutableList) { - liveDataQsRecordIdList.value = list - } - - override fun onNote(id: String) { - liveDataNoteId.value = id - } - - override fun onNiLocation(item: NiLocation) { - liveDataNILocationList.value = item - } - }) - mapController.lineHandler.setOnTaskLinkItemClickListener(object : - OnTaskLinkItemClickListener { - override fun onTaskLink(taskLinkId: String) { - liveDataTaskLink.value = taskLinkId - } - }) - initLocation() + /** + * 处理点击道路捕捉回调功能 + */ + mapController.mMapView.addOnNIMapClickListener( + TAG, + //处理地图点击操作 + object : OnGeoPointClickListener { + override fun onMapClick(tag: String, point: GeoPoint) { + if (tag == TAG) { + viewModelScope.launch(Dispatchers.Default) { + //线选择状态 + if (bSelectRoad) { + captureLink(point) + } + } + } + } + }, + /** + * 处理之间数据的点击 + */ + object : OnQsRecordItemClickListener { + override fun onQsRecordList(tag: String, list: MutableList) { + if (tag == TAG) + liveDataQsRecordIdList.value = list + } + }, + /** + * 处理新增link线点击编辑 + */ + object : OnTaskLinkItemClickListener { + override fun onTaskLink(tag: String, taskLinkId: String) { + if (tag == TAG) + liveDataTaskLink.value = taskLinkId + } + }, + /** + * 处理便签点击 + */ + object : ONNoteItemClickListener { + override fun onNote(tag: String, noteId: String) { + if (tag == TAG) + liveDataNoteId.value = noteId + } - //处理地图点击操作 - viewModelScope.launch(Dispatchers.Default) { - mapController.onMapClickFlow.collectLatest { -// testPoint = it - //线选择状态 - if (bSelectRoad) { - captureLink(it) - } else { - captureItem(it) + }, + /** + * 处理定位点的点击 + */ + object : OnNiLocationItemListener { + override fun onNiLocation(tag: String, it: NiLocation) { + if (tag == TAG) + liveDataNILocationList.value = it } } - } + ) + viewModelScope.launch(Dispatchers.IO) { - initTaskData() + getTaskBean() + //初始化选中的任务高亮高亮 + mapController.lineHandler.showTaskLines(currentTaskBean?.hadLinkDvoList!!) initQsRecordData() initNoteData() initNILocationData() } + sharedPreferences.registerOnSharedPreferenceChangeListener(this) } + /** - * 初始化选中的任务高亮高亮 + * 获取当前任务 */ - private suspend fun initTaskData() { + private suspend fun getTaskBean() { val id = sharedPreferences.getInt(Constant.SELECT_TASK_ID, -1) val realm = Realm.getDefaultInstance() val res = realm.where(TaskBean::class.java).equalTo("id", id).findFirst() if (res != null) { - val taskBean = realm.copyFromRealm(res) - mapController.lineHandler.showTaskLines(taskBean.hadLinkDvoList) + currentTaskBean = realm.copyFromRealm(res) } + } + + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { + if (key == Constant.SELECT_TASK_ID) { + viewModelScope.launch(Dispatchers.IO) { + getTaskBean() + initQsRecordData() + } + } } /** * 初始化渲染质检数据 */ private suspend fun initQsRecordData() { - var list = mutableListOf() - val realm = Realm.getDefaultInstance() - realm.executeTransaction { - val objects = realm.where().findAll() - list = realm.copyFromRealm(objects) - } - for (item in list) { - mapController.markerHandle.addOrUpdateQsRecordMark(item) + if (currentTaskBean != null) { + var list = mutableListOf() + val realm = Realm.getDefaultInstance() + realm.executeTransaction { + val objects = + realm.where().equalTo("taskId", currentTaskBean!!.id).findAll() + list = realm.copyFromRealm(objects) + } + mapController.markerHandle.removeAllQsMarker() + for (item in list) { + mapController.markerHandle.addOrUpdateQsRecordMark(item) + } } } @@ -259,7 +309,6 @@ class MainViewModel @Inject constructor( /** * 初始化定位信息 */ - @RequiresApi(Build.VERSION_CODES.N) private fun initLocation() { //用于定位点存储到数据库 viewModelScope.launch(Dispatchers.Default) { @@ -335,17 +384,10 @@ class MainViewModel @Inject constructor( } - /** - * 捕捉要素 - */ - private suspend fun captureItem(point: GeoPoint) { - - } /** * 捕获道路和面板 */ - @RequiresApi(Build.VERSION_CODES.N) private suspend fun captureLink(point: GeoPoint) { if (captureLinkState) { return @@ -354,101 +396,103 @@ class MainViewModel @Inject constructor( try { captureLinkState = true - val linkList = realmOperateHelper.queryLink( - point = point, - ) - var hisRoadName = false - if (linkList.isNotEmpty()) { - //看板数据 - val signList = mutableListOf() - val topSignList = mutableListOf() - mapController.lineHandler.linksLayer.clear() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + val linkList = realmOperateHelper.queryLink( + point = point, + ) - val link = linkList[0] + var hisRoadName = false + if (linkList.isNotEmpty()) { + //看板数据 + val signList = mutableListOf() + val topSignList = mutableListOf() + mapController.lineHandler.linksLayer.clear() - val linkId = link.properties[RenderEntity.Companion.LinkTable.linkPid] + val link = linkList[0] - if (linkIdCache != linkId) { + val linkId = link.properties[RenderEntity.Companion.LinkTable.linkPid] - mapController.lineHandler.showLine(link.geometry) - linkId?.let { - var elementList = realmOperateHelper.queryLinkByLinkPid(it) - for (element in elementList) { + if (linkIdCache != linkId) { - if (element.code == 2011) { - hisRoadName = true - liveDataRoadName.postValue(element) - continue - } + mapController.lineHandler.showLine(link.geometry) + linkId?.let { + var elementList = realmOperateHelper.queryLinkByLinkPid(it) + for (element in elementList) { - val distance = GeometryTools.distanceToDouble( - point, GeometryTools.createGeoPoint(element.geometry) - ) + if (element.code == 2011) { + hisRoadName = true + liveDataRoadName.postValue(element) + continue + } - 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) - ) - Log.e("jingo", "捕捉到的数据code ${element.code}") - when (element.code) { - //车道数,种别,功能等级,线限速,道路方向 - 2041, 2008, 2002, 2019, 2010 -> topSignList.add( - signBean + val distance = GeometryTools.distanceToDouble( + point, GeometryTools.createGeoPoint(element.geometry) ) - 4002, 4003, 4004, 4010, 4022, 4601 -> signList.add( - signBean + 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) ) + Log.e("jingo", "捕捉到的数据code ${element.code}") + when (element.code) { + //车道数,种别,功能等级,线限速,道路方向 + 2041, 2008, 2002, 2019, 2010 -> topSignList.add( + signBean + ) + + 4002, 4003, 4004, 4010, 4022, 4601 -> signList.add( + signBean + ) + } + } - } - - val realm = Realm.getDefaultInstance() - val entity = realm.where(RenderEntity::class.java) - .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( - "properties['${RenderEntity.Companion.LinkTable.linkPid}']", - outLink + val realm = Realm.getDefaultInstance() + val entity = realm.where(RenderEntity::class.java) + .equalTo("table", "OMDB_RESTRICTION").and().equalTo( + "properties['linkIn']", it ).findFirst() - if (linkOutEntity != null) { - mapController.lineHandler.linksLayer.addLine( - linkOutEntity.geometry, 0x7DFF0000 - ) + if (entity != null) { + val outLink = entity.properties["linkOut"] + val linkOutEntity = realm.where(RenderEntity::class.java) + .equalTo("table", "OMDB_RD_LINK").and().equalTo( + "properties['${RenderEntity.Companion.LinkTable.linkPid}']", + outLink + ).findFirst() + if (linkOutEntity != null) { + mapController.lineHandler.linksLayer.addLine( + linkOutEntity.geometry, 0x7DFF0000 + ) + } } } - } - liveDataTopSignList.postValue(topSignList.distinctBy { it.name } - .sortedBy { it.index }) + liveDataTopSignList.postValue(topSignList.distinctBy { it.name } + .sortedBy { it.index }) - liveDataSignList.postValue(signList.sortedBy { it.distance }) - val speechText = SignUtil.getRoadSpeechText(topSignList) - withContext(Dispatchers.Main) { - speakMode?.speakText(speechText) + liveDataSignList.postValue(signList.sortedBy { it.distance }) + val speechText = SignUtil.getRoadSpeechText(topSignList) + withContext(Dispatchers.Main) { + speakMode?.speakText(speechText) + } + linkIdCache = linkId ?: "" } - linkIdCache = linkId ?: "" + } else { + mapController.lineHandler.removeLine() + linkIdCache = "" + } + //如果没有捕捉到道路名 + if (!hisRoadName) { + liveDataRoadName.postValue(null) } - } else { - mapController.lineHandler.removeLine() - linkIdCache = "" } - //如果没有捕捉到道路名 - if (!hisRoadName) { - liveDataRoadName.postValue(null) - } - } catch (e: Exception) { } finally { @@ -474,9 +518,9 @@ class MainViewModel @Inject constructor( override fun onCleared() { super.onCleared() - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - mapController.lineHandler.removeLine() - } + sharedPreferences.unregisterOnSharedPreferenceChangeListener(this) + mapController.mMapView.removeOnNIMapClickListener(TAG) + mapController.lineHandler.removeLine() } //点击相机按钮 diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultFragment.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultFragment.kt index 270654cd..60a50bea 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultFragment.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultFragment.kt @@ -8,6 +8,7 @@ import android.os.Bundle import android.provider.MediaStore import android.util.Log import android.view.* +import android.widget.Toast import androidx.activity.result.ActivityResult import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts @@ -44,7 +45,7 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - mCameraLauncher = registerForActivityResult( + mCameraLauncher = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { result: ActivityResult -> if (result.resultCode == Activity.RESULT_OK) { @@ -65,37 +66,28 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener { binding = DataBindingUtil.inflate(inflater, R.layout.fragment_evaluation_result, container, false) binding.fragment = this - val layoutManager = LinearLayoutManager(context) binding.viewModel = viewModel binding.lifecycleOwner = this - //// 设置 RecyclerView 的固定大小,避免在滚动时重新计算视图大小和布局,提高性能 - binding.evaluationVoiceRecyclerview.setHasFixedSize(true) - binding.evaluationVoiceRecyclerview.layoutManager = layoutManager - /** - * 监听左侧栏的点击事件 - */ - val adapter = SoundtListAdapter { _, view -> - - } - - binding.evaluationVoiceRecyclerview.adapter = adapter - viewModel.listDataChatMsgEntityList.observe(viewLifecycleOwner) { - adapter.refreshData(it) - } - - - return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - //监听是否退出当前页面 - viewModel.liveDataFinish.observe(viewLifecycleOwner) { - onBackPressed() + //// 设置 RecyclerView 的固定大小,避免在滚动时重新计算视图大小和布局,提高性能 + binding.evaluationVoiceRecyclerview.setHasFixedSize(true) + val layoutManager = LinearLayoutManager(context) + binding.evaluationVoiceRecyclerview.layoutManager = layoutManager + /** + * 监听左侧栏的点击事件 + */ + val adapter = SoundtListAdapter { _, _ -> + } + + binding.evaluationVoiceRecyclerview.adapter = adapter + //返回按钮点击 - binding.evaluationBar.setOnClickListener() { + binding.evaluationBar.setOnClickListener { val mDialog = FirstDialog(context) mDialog.setTitle("提示?") mDialog.setMessage("是否退出,请确认!") @@ -110,15 +102,13 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener { } //保存事件 - binding.evaluationBarSave.setOnClickListener() { + binding.evaluationBarSave.setOnClickListener { viewModel.saveData() } //删除事件 - binding.evaluationBarDelete.setOnClickListener() { - + binding.evaluationBarDelete.setOnClickListener { viewModel.deleteData(requireContext()) - } /** * 照片view @@ -166,22 +156,21 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener { /** * 读取元数据 */ -// val id = args.qsId var id = "" var signBean: SignBean? = null - var autoSave: Boolean = false - var filePath: String = "" + var autoSave = false + var filePath = "" arguments?.let { id = it.getString("QsId", "") filePath = it.getString("filePath", "") try { signBean = it.getParcelable("SignBean") autoSave = it.getBoolean("AutoSave") - } catch (e: java.lang.Exception) { + } catch (_: java.lang.Exception) { } } - if (id == null || id.isEmpty()) { + if (id.isEmpty()) { viewModel.initNewData(signBean, filePath) //增加监听,联动列表自动保存 viewModel.liveDataRightTypeList.observe(viewLifecycleOwner) { @@ -192,102 +181,22 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener { } else { viewModel.initData(id) } -// //监听大分类数据变化 -// viewModel.liveDataClassTypeList.observe(viewLifecycleOwner) { -// if (it == null || it.isEmpty()) { -// Toast.makeText(requireContext(), "还没有导入元数据!", Toast.LENGTH_SHORT).show() -// } else { -// binding.evaluationClassType.adapter = -// ArrayAdapter(requireContext(), R.layout.text_item_select, it) -// } -// } -// -// viewModel.liveDataProblemTypeList.observe(viewLifecycleOwner){ -// if (it == null || it.isEmpty()) { -// Toast.makeText(requireContext(), "还没有导入元数据!", Toast.LENGTH_SHORT).show() -// }else{ -// binding.evaluationProblemType.adapter = -// ArrayAdapter(requireContext(), R.layout.text_item_select, it) -// } -// } -// //选择问题分类的回调 -// binding.evaluationClassType.onItemSelectedListener = -// object : AdapterView.OnItemSelectedListener { -// override fun onItemSelected( -// parent: AdapterView<*>?, view: View?, position: Int, id: Long -// ) { -// viewModel.getProblemTypeList(position) -// } -// -// override fun onNothingSelected(parent: AdapterView<*>?) {} -// } -// /** -// * 监听联动选择的内容 -// */ -// viewModel.problemTypeListLiveData.observe(viewLifecycleOwner) { -// binding.evaluationClassTabLayout.let { tabLayout -> -// tabLayout.removeAllTabs() -// val fragmentList = mutableListOf() -// for (item in it) { -// val tab = tabLayout.newTab() -// tab.text = item -// tabLayout.addTab(tab) -// fragmentList.add(PhenomenonFragment(viewModel.currentClassType, item)) -// } -// phenomenonFragmentAdapter = -// activity?.let { a -> EvaluationResultAdapter(a, fragmentList) } -// binding.evaluationViewpager.adapter = phenomenonFragmentAdapter -// -// TabLayoutMediator( -// binding.evaluationClassTabLayout, -// binding.evaluationViewpager -// ) { tab, position -> -// tab.text = it[position] -// }.attach() -// updateHeight(0) -// } -// -// } + viewModel.listDataChatMsgEntityList.observe(viewLifecycleOwner) { + adapter.refreshData(it) + } + + //监听是否退出当前页面 + viewModel.liveDataFinish.observe(viewLifecycleOwner) { + onBackPressed() + } + //监听要提示的信息 + viewModel.liveDataToastMessage.observe(viewLifecycleOwner) { + Toast.makeText(requireContext(), it, Toast.LENGTH_SHORT).show() + } -// binding.evaluationViewpager.registerOnPageChangeCallback(object : -// ViewPager2.OnPageChangeCallback() { -// override fun onPageSelected(position: Int) { -// super.onPageSelected(position) -// updateHeight(position) -// } -// }) } - -// private fun updateHeight(position: Int) { -// phenomenonFragmentAdapter?.let { -// if (it.fragmentList.size > position) { -// val fragment: Fragment = it.fragmentList[position] -// if (fragment.view != null) { -// val viewWidth = View.MeasureSpec.makeMeasureSpec( -// fragment.requireView().width, View.MeasureSpec.EXACTLY -// ) -// val viewHeight = -// View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED) -// fragment.requireView().measure(viewWidth, viewHeight) -// binding.evaluationViewpager.let { viewpager -> -// if (viewpager.layoutParams.height != fragment.requireView().measuredHeight) { -// //必须要用对象去接收,然后修改该对象再采用该对象,否则无法生效... -// val layoutParams: ViewGroup.LayoutParams = -// viewpager.layoutParams -// layoutParams.height = fragment.requireView().measuredHeight -// viewpager.layoutParams = layoutParams -// } -// } -// -// } -// } -// } -// -// } - - override fun onDestroyView() { activity?.run { findNavController(R.id.main_activity_middle_fragment).navigateUp() @@ -307,6 +216,7 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener { if (currentItem > 0) { binding.evaluationPictureViewpager.currentItem = currentItem - 1 } else { + return } } @@ -316,7 +226,7 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener { if (currentItem < pictureAdapter.data.size - 1) { binding.evaluationPictureViewpager.currentItem = currentItem + 1 } else { - + return } } //上三项,打开面板 @@ -369,7 +279,9 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener { R.id.evaluation_camera -> { takePhoto() } - else -> {} + else -> { + return + } } } } @@ -402,6 +314,4 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener { Log.d("TTTT", e.toString()) } } - - } \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultViewModel.kt index 468d56d6..509748a0 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultViewModel.kt @@ -3,6 +3,7 @@ package com.navinfo.omqs.ui.fragment.evaluationresult import android.app.Activity import android.app.Dialog import android.content.Context +import android.content.SharedPreferences import android.graphics.Bitmap import android.graphics.drawable.AnimationDrawable import android.graphics.drawable.BitmapDrawable @@ -20,9 +21,12 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.blankj.utilcode.util.ToastUtils import com.navinfo.collect.library.data.entity.AttachmentBean +import com.navinfo.collect.library.data.entity.HadLinkDvoBean import com.navinfo.collect.library.data.entity.QsRecordBean import com.navinfo.collect.library.data.entity.RenderEntity.Companion.LinkTable +import com.navinfo.collect.library.data.entity.TaskBean import com.navinfo.collect.library.map.NIMapController +import com.navinfo.collect.library.map.OnGeoPointClickListener import com.navinfo.collect.library.utils.GeometryTools import com.navinfo.omqs.Constant import com.navinfo.omqs.R @@ -39,8 +43,8 @@ import dagger.hilt.android.lifecycle.HiltViewModel import io.realm.Realm import io.realm.RealmList import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.oscim.core.GeoPoint import java.io.File import java.io.FileOutputStream @@ -52,9 +56,11 @@ class EvaluationResultViewModel @Inject constructor( private val roomAppDatabase: RoomAppDatabase, private val mapController: NIMapController, private val realmOperateHelper: RealmOperateHelper, -) : ViewModel() { + private val sharedPreferences: SharedPreferences +) : ViewModel(), SharedPreferences.OnSharedPreferenceChangeListener { - private val markerTitle = "点选marker" + + private val TAG = "点选marker" /** * 操作结束,销毁页面 @@ -66,10 +72,6 @@ class EvaluationResultViewModel @Inject constructor( */ val liveDataLeftTypeList = MutableLiveData>() - /** - * 问题类型 liveData 给[MiddleAdapter]展示的数据 - */ -// val liveDataMiddleTypeList = MutableLiveData>() /** * 问题现象 liveData 给[RightGroupHeaderAdapter]展示的数据 @@ -77,9 +79,9 @@ class EvaluationResultViewModel @Inject constructor( val liveDataRightTypeList = MutableLiveData>() /** - * + * 要保存的评测数据 */ - val liveDataQsRecordBean = MutableLiveData() + val liveDataQsRecordBean = MutableLiveData(QsRecordBean(id = UUID.randomUUID().toString())) /** * 语音列表 @@ -91,6 +93,19 @@ class EvaluationResultViewModel @Inject constructor( */ val liveDataPictureList = MutableLiveData>() + /** + * toast信息 + */ + val liveDataToastMessage = MutableLiveData() + + /** + * 当前选择的任务 + */ + val liveDataTaskBean = MutableLiveData() + + /** + * 编辑数据时用来差分数据 + */ var oldBean: QsRecordBean? = null //语音窗体 @@ -108,24 +123,27 @@ class EvaluationResultViewModel @Inject constructor( var classCodeTemp: String = "" init { - liveDataQsRecordBean.value = QsRecordBean(id = UUID.randomUUID().toString()) - viewModelScope.launch { - mapController.onMapClickFlow.collectLatest { - liveDataQsRecordBean.value!!.geometry = GeometryTools.createGeometry(it).toText() - mapController.markerHandle.addMarker(it, markerTitle) - viewModelScope.launch { - captureLink(it.longitude, it.latitude) + mapController.mMapView.addOnNIMapClickListener(TAG, object : OnGeoPointClickListener { + override fun onMapClick(tag: String, point: GeoPoint) { + if (tag == TAG) { + liveDataQsRecordBean.value!!.geometry = + GeometryTools.createGeometry(point).toText() + mapController.markerHandle.addMarker(point, TAG) + viewModelScope.launch { + captureLink(point) + } } + } - } + }) + sharedPreferences.registerOnSharedPreferenceChangeListener(this) } override fun onCleared() { super.onCleared() - mapController.markerHandle.removeMarker(markerTitle) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - mapController.lineHandler.removeLine() - } + mapController.mMapView.removeOnNIMapClickListener(TAG) + mapController.markerHandle.removeMarker(TAG) + mapController.lineHandler.removeLine() } @@ -133,40 +151,57 @@ class EvaluationResultViewModel @Inject constructor( * 查询数据库,获取问题分类 */ fun initNewData(bean: SignBean?, filePath: String) { - //获取当前定位点 - val geoPoint = mapController.locationLayerHandler.getCurrentGeoPoint() - //如果不是从面板进来的 - if (bean == null) { - geoPoint?.let { - liveDataQsRecordBean.value!!.geometry = GeometryTools.createGeometry(it).toText() - mapController.markerHandle.addMarker(geoPoint, markerTitle) - mapController.animationHandler.animationByLatLon( - geoPoint.latitude, geoPoint.longitude - ) - viewModelScope.launch { - captureLink(geoPoint.longitude, geoPoint.latitude) - } - } - } else { - liveDataQsRecordBean.value?.run { - elementId = bean.renderEntity.code.toString() - linkId = bean.linkId - if (linkId.isNotEmpty()) { - viewModelScope.launch { - val link = realmOperateHelper.queryLink(linkId) - link?.let { l -> - mapController.lineHandler.showLine(l.geometry) - } - } - } - val point = GeometryTools.createGeoPoint(bean.renderEntity.geometry) - this.geometry = GeometryTools.createGeometry(point).toText() - mapController.animationHandler.animationByLatLon(point.latitude, point.longitude) - mapController.markerHandle.addMarker(point, markerTitle) - } - } //查询元数据 viewModelScope.launch(Dispatchers.IO) { + /** + * 获取当前所选的任务 + */ + val taskId = sharedPreferences.getInt(Constant.SELECT_TASK_ID, -1) + val realm = Realm.getDefaultInstance() + val objects = realm.where(TaskBean::class.java).equalTo("id", taskId).findFirst() + if (objects != null) { + liveDataTaskBean.postValue(realm.copyFromRealm(objects)) + } + + //获取当前定位点 + val geoPoint = mapController.locationLayerHandler.getCurrentGeoPoint() + //如果不是从面板进来的 + if (bean == null) { + geoPoint?.let { + liveDataQsRecordBean.value!!.geometry = + GeometryTools.createGeometry(it).toText() + withContext(Dispatchers.Main) { + mapController.markerHandle.addMarker(geoPoint, TAG) + mapController.animationHandler.animationByLatLon( + geoPoint.latitude, geoPoint.longitude + ) + } + captureLink(geoPoint) + } + } else { + liveDataQsRecordBean.value?.run { + elementId = bean.renderEntity.code.toString() + linkId = bean.linkId + if (linkId.isNotEmpty()) { + viewModelScope.launch { + val link = realmOperateHelper.queryLink(linkId) + link?.let { l -> + mapController.lineHandler.showLine(l.geometry) + } + } + } + + val point = GeometryTools.createGeoPoint(bean.renderEntity.geometry) + this.geometry = GeometryTools.createGeometry(point).toText() + withContext(Dispatchers.Main) { + mapController.animationHandler.animationByLatLon( + point.latitude, point.longitude + ) + mapController.markerHandle.addMarker(point, TAG) + } + } + } + getClassTypeList(bean) getProblemLinkList() } @@ -174,23 +209,32 @@ class EvaluationResultViewModel @Inject constructor( } /** - * 捕捉道路 + * 捕捉道路或新增评测link */ - private suspend fun captureLink(longitude: Double, latitude: Double) { + private suspend fun captureLink(point: GeoPoint) { + if (liveDataTaskBean.value == null) { + liveDataToastMessage.postValue("请先选择所属任务!") + return + } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - val linkList = realmOperateHelper.queryLink( - point = GeoPoint(latitude, longitude), - ) - liveDataQsRecordBean.value?.let { - if (linkList.isNotEmpty()) { - it.linkId = linkList[0].properties[LinkTable.linkPid] ?: "" - mapController.lineHandler.showLine(linkList[0].geometry) - Log.e("jingo", "捕捉到的linkId = ${it.linkId}") + + val taskLink = + realmOperateHelper.captureTaskLink(liveDataTaskBean.value!!.id, point) + if (taskLink != null) { + it.linkId = taskLink.linkPid + mapController.lineHandler.showLine(taskLink.geometry) + return } else { - it.linkId = "" - mapController.lineHandler.removeLine() + val linkList = realmOperateHelper.queryLink(point = point) + if (linkList.isNotEmpty()) { + it.linkId = linkList[0].properties[LinkTable.linkPid] ?: "" + mapController.lineHandler.showLine(linkList[0].geometry) + return + } } + it.linkId = "" + mapController.lineHandler.removeLine() } } } @@ -323,19 +367,51 @@ class EvaluationResultViewModel @Inject constructor( liveDataQsRecordBean.postValue(liveDataQsRecordBean.value) } + /** + * 保存数据 + */ + fun saveData() { + viewModelScope.launch(Dispatchers.IO) { + val taskBean = liveDataQsRecordBean.value!! + if (liveDataTaskBean.value == null) { + liveDataToastMessage.postValue("请选择所属任务!") + return@launch + } else if (taskBean.classType.isEmpty()) { + liveDataToastMessage.postValue("请选择要素分类!") + return@launch + } else if (taskBean.problemType.isEmpty()) { + liveDataToastMessage.postValue("请选择问题类型!") + return@launch + } else if (taskBean.phenomenon.isEmpty()) { + liveDataToastMessage.postValue("请选择问题现象!") + return@launch + } else if (taskBean.problemLink.isEmpty()) { + liveDataToastMessage.postValue("请选择问题环节!") + return@launch + } else if (taskBean.classType.isEmpty()) { + liveDataToastMessage.postValue("请选择问题分类!") + return@launch + } else if (taskBean.cause.isEmpty()) { + liveDataToastMessage.postValue("请选择初步分析原因!") + return@launch + } + val realm = Realm.getDefaultInstance() + liveDataQsRecordBean.value!!.taskId = liveDataTaskBean.value!!.id liveDataQsRecordBean.value!!.checkTime = DateTimeUtil.getDataTime() realm.executeTransaction { it.copyToRealmOrUpdate(liveDataQsRecordBean.value) } -// realm.close() mapController.markerHandle.addOrUpdateQsRecordMark(liveDataQsRecordBean.value!!) liveDataFinish.postValue(true) } } + /** + * 删除数据 + */ fun deleteData(context: Context) { val mDialog = FirstDialog(context) mDialog.setTitle("提示?") @@ -368,39 +444,49 @@ class EvaluationResultViewModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { - Realm.getDefaultInstance().use { realm -> - realm.executeTransactionAsync { bgRealm -> - // find the item + val realm = Realm.getDefaultInstance() + val objects = realm.where(QsRecordBean::class.java).equalTo("id", id).findFirst() + Log.e("jingo", "查询数据 id= $id") + if (objects != null) { + oldBean = realm.copyFromRealm(objects) + oldBean?.let { + /** + * 获取当前所选的任务 + */ val objects = - bgRealm.where(QsRecordBean::class.java).equalTo("id", id).findFirst() + realm.where(TaskBean::class.java).equalTo("id", it.taskId).findFirst() if (objects != null) { - oldBean = bgRealm.copyFromRealm(objects) - oldBean?.let { - liveDataQsRecordBean.postValue(it.copy()) - val p = GeometryTools.createGeoPoint(it.geometry) - mapController.markerHandle.addMarker( - GeoPoint( - p.latitude, - p.longitude - ), markerTitle - ) + liveDataTaskBean.postValue(realm.copyFromRealm(objects)) + } - //获取linkid - if (it.linkId.isNotEmpty()) { - viewModelScope.launch(Dispatchers.IO) { - val link = realmOperateHelper.queryLink(it.linkId) - link?.let { l -> - mapController.lineHandler.showLine(l.geometry) - } - } + liveDataQsRecordBean.postValue(it.copy()) + val p = GeometryTools.createGeoPoint(it.geometry) + mapController.markerHandle.addMarker( + GeoPoint( + p.latitude, p.longitude + ), TAG + ) + + //获取linkid + if (it.linkId.isNotEmpty()) { + val link = realmOperateHelper.queryLink(it.linkId) + if (link != null) { + mapController.lineHandler.showLine(link.geometry) + } else { + val realmR = realm.where(HadLinkDvoBean::class.java) + .equalTo("linkPid", it.linkId).and().equalTo("taskId", it.taskId) + .findFirst() + if (realmR != null) { + mapController.lineHandler.showLine(realmR.geometry) } - liveDataQsRecordBean.value?.attachmentBeanList = - it.attachmentBeanList - // 显示语音数据到界面 - getChatMsgEntityList() } } + liveDataQsRecordBean.value?.attachmentBeanList = it.attachmentBeanList + // 显示语音数据到界面 + getChatMsgEntityList() } + } else { + liveDataToastMessage.postValue("数据读取失败") } } } @@ -408,7 +494,7 @@ class EvaluationResultViewModel @Inject constructor( /** * 查询问题类型列表 */ - fun getChatMsgEntityList() { + private suspend fun getChatMsgEntityList() { val chatMsgEntityList: MutableList = ArrayList() liveDataQsRecordBean.value?.attachmentBeanList?.forEach { //1 录音 @@ -535,8 +621,7 @@ class EvaluationResultViewModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { // 创建一个名为 "MyApp" 的文件夹 val myAppDir = File(Constant.USER_DATA_ATTACHEMNT_PATH) - if (!myAppDir.exists()) - myAppDir.mkdirs() // 确保文件夹已创建 + if (!myAppDir.exists()) myAppDir.mkdirs() // 确保文件夹已创建 // 创建一个名为 fileName 的文件 val file = File(myAppDir, "${UUID.randomUUID()}.png") @@ -558,4 +643,20 @@ class EvaluationResultViewModel @Inject constructor( } } + + /** + * 监听任务选择变化 + */ + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { + if (key == Constant.SELECT_TASK_ID && oldBean == null) { + viewModelScope.launch(Dispatchers.IO) { + val taskId = sharedPreferences.getInt(Constant.SELECT_TASK_ID, -1) + val realm = Realm.getDefaultInstance() + val objects = realm.where(TaskBean::class.java).equalTo("id", taskId).findFirst() + if (objects != null) { + liveDataTaskBean.postValue(realm.copyFromRealm(objects)) + } + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkViewModel.kt index 6945c9a9..a6e7d636 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkViewModel.kt @@ -246,7 +246,7 @@ class TaskLinkViewModel @Inject constructor( /** * 监听shared变化 */ - override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { if (key == Constant.SELECT_TASK_ID) { getTaskBean() } @@ -313,32 +313,47 @@ class TaskLinkViewModel @Inject constructor( * 删除数据 */ fun deleteData(context: Context) { - if(hadLinkDvoBean == null){ + if (hadLinkDvoBean == null) { liveDataFinish.value = true return } val mDialog = FirstDialog(context) mDialog.setTitle("提示?") mDialog.setMessage("是否删除Mark,请确认!") - mDialog.setPositiveButton("确定" + mDialog.setPositiveButton( + "确定" ) { _, _ -> mDialog.dismiss() viewModelScope.launch(Dispatchers.IO) { val realm = Realm.getDefaultInstance() realm.executeTransaction { - val task = it.where(TaskBean::class.java).equalTo("id",hadLinkDvoBean!!.taskId).findFirst() - if(task != null) { + //先找到对应的任务 + val task = it.where(TaskBean::class.java).equalTo("id", hadLinkDvoBean!!.taskId) + .findFirst() + //维护任务删除当前link + if (task != null) { for (h in task.hadLinkDvoList) { - if(h.linkPid == hadLinkDvoBean!!.linkPid) + if (h.linkPid == hadLinkDvoBean!!.linkPid) task.hadLinkDvoList.remove(h) break } realm.copyToRealmOrUpdate(task) } -// val objects = it.where(HadLinkDvoBean::class.java) -// .equalTo("linkPid", hadLinkDvoBean!!.linkPid).findFirst() -// objects?.deleteFromRealm() + //删除link + val objects = it.where(HadLinkDvoBean::class.java) + .equalTo("linkPid", hadLinkDvoBean!!.linkPid).findFirst() + objects?.deleteFromRealm() + //删除相关联的评测任务 + val qsRecordBeans = it.where(QsRecordBean::class.java) + .equalTo("linkId", hadLinkDvoBean!!.linkPid).and() + .equalTo("taskId", hadLinkDvoBean!!.taskId).findAll() + if (qsRecordBeans != null) { + for (b in qsRecordBeans) { + mapController.markerHandle.removeQsRecordMark(b) + } + qsRecordBeans.deleteAllFromRealm() + } } mapController.lineHandler.removeTaskLink(hadLinkDvoBean!!.linkPid) mapController.mMapView.vtmMap.updateMap(true) diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskFragment.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskFragment.kt index afe01176..9312378b 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskFragment.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskFragment.kt @@ -17,8 +17,12 @@ import com.navinfo.omqs.R import com.navinfo.omqs.databinding.FragmentTaskBinding import com.navinfo.omqs.ui.fragment.BaseFragment import com.navinfo.omqs.ui.other.shareViewModels +import com.yanzhenjie.recyclerview.SwipeMenuBridge +import com.yanzhenjie.recyclerview.SwipeMenuCreator +import com.yanzhenjie.recyclerview.SwipeMenuItem import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch +import org.videolan.vlc.Util /** * 当前任务的道路列表 @@ -36,12 +40,8 @@ class TaskFragment : BaseFragment() { private val adapter: TaskAdapter by lazy { TaskAdapter(object : TaskAdapterCallback { override fun itemOnClick(bean: HadLinkDvoBean) { - if(bean!=null){ - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - viewModel.showCurrentLink(bean) - } - }else{ - Toast.makeText(context, "数据错误,无法显示!", Toast.LENGTH_SHORT).show() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + viewModel.showCurrentLink(bean) } } @@ -63,11 +63,43 @@ class TaskFragment : BaseFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + binding.taskAddLink.setOnClickListener { + viewModel.setSelectLink(!binding.taskAddLink.isSelected) + } + + viewModel.liveDataSelectNewLink.observe(viewLifecycleOwner) { + binding.taskAddLink.isSelected = it + } + + //注意:使用滑动菜单不能开启滑动删除,否则只有滑动删除没有滑动菜单 + val mSwipeMenuCreator = SwipeMenuCreator { _, rightMenu, _ -> + //添加菜单自动添加至尾部 + val deleteItem = SwipeMenuItem(context) + deleteItem.height = Util.convertDpToPx(requireContext(), 60) + deleteItem.width = Util.convertDpToPx(requireContext(), 80) + deleteItem.text = "删除" + deleteItem.background = requireContext().getDrawable(R.color.red) + deleteItem.setTextColor(requireContext().resources.getColor(R.color.white)) + rightMenu.addMenuItem(deleteItem) + } + val layoutManager = LinearLayoutManager(context) //// 设置 RecyclerView 的固定大小,避免在滚动时重新计算视图大小和布局,提高性能 binding.taskRecyclerview.setHasFixedSize(true) binding.taskRecyclerview.layoutManager = layoutManager + + //增加侧滑按钮 + binding.taskRecyclerview.setSwipeMenuCreator(mSwipeMenuCreator) + + + //单项点击 + binding.taskRecyclerview.setOnItemMenuClickListener { menuBridge, position -> + menuBridge.closeMenu() + viewModel.deleteTaskLink(requireContext(), adapter.data[position]) + } + binding.taskRecyclerview.adapter = adapter + binding.taskSearchClear.setOnClickListener { binding.taskSearch.setText("") } @@ -90,6 +122,7 @@ class TaskFragment : BaseFragment() { }) } + override fun onDestroyView() { super.onDestroyView() _binding = null diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskListFragment.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskListFragment.kt index 7e114aaa..1d83b1e9 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskListFragment.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskListFragment.kt @@ -106,6 +106,8 @@ class TaskListFragment : BaseFragment() { }) } + + override fun onDestroyView() { super.onDestroyView() _binding = null 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 63285395..5d1634c7 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 @@ -4,7 +4,9 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.Toast import androidx.navigation.fragment.findNavController +import androidx.viewpager2.widget.ViewPager2 import com.google.android.material.tabs.TabLayoutMediator import com.navinfo.omqs.databinding.FragmentTaskManagerBinding import com.navinfo.omqs.ui.fragment.BaseFragment @@ -38,10 +40,20 @@ class TaskManagerFragment(private var backListener: ((TaskManagerFragment) -> Un override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + viewModel.liveDataToastMessage.observe(viewLifecycleOwner) { + Toast.makeText(requireContext(), it, Toast.LENGTH_SHORT).show() + } //禁止滑动,因为页面在抽屉里,和抽屉的滑动有冲突 binding.taskManagerViewpager.isUserInputEnabled = false //创建viewpager2的适配器 binding.taskManagerViewpager.adapter = activity?.let { TaskManagerAdapter(it) } + binding.taskManagerViewpager.registerOnPageChangeCallback(object : + ViewPager2.OnPageChangeCallback() { + override fun onPageSelected(position: Int) { + viewModel.setSelectLink(false) + } + }) + //绑定viewpager2与tabLayout TabLayoutMediator( binding.taskManagerTabLayout, diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskViewModel.kt index 4d0f8e8c..b6f25996 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskViewModel.kt @@ -1,12 +1,11 @@ package com.navinfo.omqs.ui.fragment.tasklist -import android.app.Dialog import android.content.Context import android.content.SharedPreferences import android.content.SharedPreferences.OnSharedPreferenceChangeListener import android.os.Build +import android.view.View import android.widget.Toast -import androidx.annotation.RequiresApi import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -16,8 +15,10 @@ import com.navinfo.collect.library.data.entity.NiLocation 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.OnGeoPointClickListener import com.navinfo.collect.library.utils.GeometryTools import com.navinfo.omqs.Constant +import com.navinfo.omqs.db.RealmOperateHelper import com.navinfo.omqs.http.NetResult import com.navinfo.omqs.http.NetworkService import com.navinfo.omqs.tools.FileManager @@ -26,6 +27,8 @@ import com.navinfo.omqs.util.DateTimeUtil import dagger.hilt.android.lifecycle.HiltViewModel import io.realm.Realm import kotlinx.coroutines.* +import kotlinx.coroutines.flow.collectLatest +import org.oscim.core.GeoPoint import javax.inject.Inject @@ -33,8 +36,10 @@ import javax.inject.Inject class TaskViewModel @Inject constructor( private val networkService: NetworkService, private val mapController: NIMapController, - private val sharedPreferences: SharedPreferences + private val sharedPreferences: SharedPreferences, + private val realmOperateHelper: RealmOperateHelper, ) : ViewModel(), OnSharedPreferenceChangeListener { + private val TAG = "TaskViewModel" /** * 用来更新任务列表 @@ -58,6 +63,11 @@ class TaskViewModel @Inject constructor( */ val liveDataCloseTask = MutableLiveData() + /** + * 提示信息 + */ + val liveDataToastMessage = MutableLiveData() + /** * 当前选中的任务 */ @@ -70,6 +80,10 @@ class TaskViewModel @Inject constructor( private var filterTaskJob: Job? = null + /** + * 是否开启了道路选择 + */ + var liveDataSelectNewLink = MutableLiveData(false) init { sharedPreferences.registerOnSharedPreferenceChangeListener(this) @@ -318,65 +332,13 @@ class TaskViewModel @Inject constructor( * 关闭任务 */ fun removeTask(context: Context, taskBean: TaskBean) { - if (taskBean != null) { - val mDialog = FirstDialog(context) - mDialog.setTitle("提示?") - mDialog.setMessage("是否关闭,请确认!") - mDialog.setPositiveButton("确定", object : FirstDialog.OnClickListener { - override fun onClick(dialog: Dialog?, which: Int) { - mDialog.dismiss() - viewModelScope.launch(Dispatchers.IO) { - val realm = Realm.getDefaultInstance() - realm.executeTransaction { - val objects = it.where(TaskBean::class.java) - .equalTo("id", taskBean.id).findFirst() - objects?.deleteFromRealm() - } - //遍历删除对应的数据 - taskBean.hadLinkDvoList.forEach { hadLinkDvoBean -> - val qsRecordList = realm.where(QsRecordBean::class.java) - .equalTo("linkId", hadLinkDvoBean.linkPid).findAll() - if (qsRecordList != null && qsRecordList.size > 0) { - val copyList = realm.copyFromRealm(qsRecordList) - copyList.forEach { - it.deleteFromRealm() - mapController.markerHandle.removeQsRecordMark(it) - mapController.mMapView.vtmMap.updateMap(true) - } - } - } - //过滤掉已上传的超过90天的数据 - var nowTime: Long = DateTimeUtil.getNowDate().time - var beginNowTime: Long = nowTime - 90 * 3600 * 24 * 1000L - var syncUpload: Int = FileManager.Companion.FileUploadStatus.DONE - val objects = realm.where(TaskBean::class.java) - .notEqualTo("syncStatus", syncUpload).or() - .between("operationTime", beginNowTime, nowTime) - .equalTo("syncStatus", syncUpload).findAll() - val taskList = realm.copyFromRealm(objects) - for (item in taskList) { - FileManager.checkOMDBFileInfo(item) - } - liveDataTaskList.postValue(taskList) - liveDataCloseTask.postValue(true) - } - } - }) - mDialog.setNegativeButton("取消", object : FirstDialog.OnClickListener { - override fun onClick(dialog: Dialog?, which: Int) { - liveDataCloseTask.postValue(false) - mDialog.dismiss() - } - }) - mDialog.show() - } val mDialog = FirstDialog(context) mDialog.setTitle("提示?") mDialog.setMessage("是否关闭,请确认!") mDialog.setPositiveButton( "确定" - ) { _, _ -> - mDialog.dismiss() + ) { dialog, _ -> + dialog.dismiss() viewModelScope.launch(Dispatchers.IO) { val realm = Realm.getDefaultInstance() realm.executeTransaction { @@ -387,7 +349,8 @@ class TaskViewModel @Inject constructor( //遍历删除对应的数据 taskBean.hadLinkDvoList.forEach { hadLinkDvoBean -> val qsRecordList = realm.where(QsRecordBean::class.java) - .equalTo("linkId", hadLinkDvoBean.linkPid).findAll() + .equalTo("linkId", hadLinkDvoBean.linkPid).and() + .equalTo("taskId", hadLinkDvoBean.taskId).findAll() if (qsRecordList != null && qsRecordList.size > 0) { val copyList = realm.copyFromRealm(qsRecordList) copyList.forEach { @@ -410,9 +373,15 @@ class TaskViewModel @Inject constructor( FileManager.checkOMDBFileInfo(item) } liveDataTaskList.postValue(taskList) + liveDataCloseTask.postValue(true) } } - mDialog.setNegativeButton("取消", null) + mDialog.setNegativeButton( + "取消" + ) { _, _ -> + liveDataCloseTask.postValue(false) + mDialog.dismiss() + } mDialog.show() } @@ -421,7 +390,8 @@ class TaskViewModel @Inject constructor( val realm = Realm.getDefaultInstance() taskBean.hadLinkDvoList.forEach { hadLinkDvoBean -> val objects = realm.where(QsRecordBean::class.java) - .equalTo("linkId", hadLinkDvoBean.linkPid).findAll() + .equalTo("linkId", hadLinkDvoBean.linkPid).and() + .equalTo("taskId", hadLinkDvoBean.taskId).findAll() val map: MutableMap = HashMap() if (objects.isEmpty() && hadLinkDvoBean.reason.isEmpty()) { withContext(Dispatchers.Main) { @@ -452,11 +422,127 @@ class TaskViewModel @Inject constructor( /** * 监听新增的评测link */ - override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { if (key == Constant.SHARED_SYNC_TASK_LINK_ID) { viewModelScope.launch(Dispatchers.IO) { getLocalTaskList() } } } + + /** + * 设置是否开启选择link + */ + fun setSelectLink(selected: Boolean) { + liveDataSelectNewLink.value = selected + //开始捕捉 + if (selected) { + mapController.mMapView.addOnNIMapClickListener(TAG, object : OnGeoPointClickListener { + override fun onMapClick(tag: String, point: GeoPoint) { + if (tag == TAG) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + viewModelScope.launch(Dispatchers.Default) { + if (currentSelectTaskBean == null) { + liveDataToastMessage.postValue("还没有开启任何任务") + } else { + val links = realmOperateHelper.queryLink( + point = point, + ) + if (links.isNotEmpty()) { + val l = links[0] + for (link in currentSelectTaskBean!!.hadLinkDvoList) { + if (link.linkPid == l.properties["linkPid"]) { + return@launch + } + } + val hadLinkDvoBean = HadLinkDvoBean( + taskId = currentSelectTaskBean!!.id, + linkPid = l.properties["linkPid"]!!, + geometry = l.geometry, + linkStatus = 2 + ) + currentSelectTaskBean!!.hadLinkDvoList.add( + hadLinkDvoBean + ) + val realm = Realm.getDefaultInstance() + realm.executeTransaction { r -> + r.copyToRealmOrUpdate(hadLinkDvoBean) + r.copyToRealmOrUpdate(currentSelectTaskBean!!) + } + liveDataTaskLinks.postValue(currentSelectTaskBean!!.hadLinkDvoList) + mapController.lineHandler.addTaskLink(hadLinkDvoBean) + } + } + } + } + } + } + + }) + } else { + mapController.mMapView.removeOnNIMapClickListener(TAG) + mapController.lineHandler.removeLine() + } + } + + /** + * 删除评测link + */ + fun deleteTaskLink(context: Context, hadLinkDvoBean: HadLinkDvoBean) { + if (hadLinkDvoBean.linkStatus == 1) { + val mDialog = FirstDialog(context) + mDialog.setTitle("提示") + mDialog.setMessage("当前要评测的link是任务原始规划的,不能删除,如果不进行作业请标记原因") + mDialog.setCancelVisibility(View.GONE) + mDialog.setPositiveButton( + "确定" + ) { _, _ -> + mDialog.dismiss() + } + mDialog.show() + } else { + val mDialog = FirstDialog(context) + mDialog.setTitle("提示") + mDialog.setMessage("是否删除当前link,与之相关联的评测任务会一起删除!!") + mDialog.setPositiveButton( + "确定" + ) { dialog, _ -> + dialog.dismiss() + viewModelScope.launch(Dispatchers.IO) { + val realm = Realm.getDefaultInstance() + realm.executeTransaction { + for (link in currentSelectTaskBean!!.hadLinkDvoList) { + if (link.linkPid == hadLinkDvoBean.linkPid) { + currentSelectTaskBean!!.hadLinkDvoList.remove(link) + break + } + } + realm.where(HadLinkDvoBean::class.java) + .equalTo("linkPid", hadLinkDvoBean.linkPid).findFirst() + ?.deleteFromRealm() + val markers = realm.where(QsRecordBean::class.java) + .equalTo("linkId", hadLinkDvoBean.linkPid) + .and().equalTo("taskId", hadLinkDvoBean.taskId) + .findAll() + if(markers != null){ + for(marker in markers){ + mapController.markerHandle.removeQsRecordMark(marker) + } + markers.deleteAllFromRealm() + } + + realm.copyToRealmOrUpdate(currentSelectTaskBean) + mapController.lineHandler.removeTaskLink(hadLinkDvoBean.linkPid) + liveDataTaskLinks.postValue(currentSelectTaskBean!!.hadLinkDvoList) + } + } + } + mDialog.setNegativeButton( + "取消" + ) { _, _ -> + mDialog.dismiss() + } + mDialog.show() + } + } } diff --git a/app/src/main/res/drawable-v24/baseline_add_24.xml b/app/src/main/res/drawable-v24/baseline_add_24.xml new file mode 100644 index 00000000..647e5ea9 --- /dev/null +++ b/app/src/main/res/drawable-v24/baseline_add_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable-v24/baseline_add_24_press.xml b/app/src/main/res/drawable-v24/baseline_add_24_press.xml new file mode 100644 index 00000000..c52171ce --- /dev/null +++ b/app/src/main/res/drawable-v24/baseline_add_24_press.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/selector_add_taskline.xml b/app/src/main/res/drawable/selector_add_taskline.xml new file mode 100644 index 00000000..45941ce4 --- /dev/null +++ b/app/src/main/res/drawable/selector_add_taskline.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/layout/fragment_evaluation_result.xml b/app/src/main/res/layout/fragment_evaluation_result.xml index 7d77f88b..d1186c70 100644 --- a/app/src/main/res/layout/fragment_evaluation_result.xml +++ b/app/src/main/res/layout/fragment_evaluation_result.xml @@ -87,6 +87,24 @@ android:layout_marginBottom="7dp" android:orientation="vertical"> + + + + + + + + + + - () +// val onMapClickFlow = MutableSharedFlow() fun init( context: AppCompatActivity, @@ -43,13 +39,26 @@ class NIMapController { measureLayerHandler = MeasureLayerHandler(context, mapView) mMapView = mapView mMapView.setOnMapClickListener { - context.lifecycleScope.launch { - onMapClickFlow.emit(it) + if (mapView.listenerTagList.isNotEmpty()) { + val tag = mapView.listenerTagList.last() + val listenerList = mapView.listenerList[tag] + if (listenerList != null) { + for (listener in listenerList) { + if (listener is OnGeoPointClickListener) { + listener.onMapClick(tag, it) + return@setOnMapClickListener + } + } + } } + +// context.lifecycleScope.launch { +// onMapClickFlow.emit(it) +// } + } mapView.setOptions(options) } - - } + diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/NIMapView.java b/collect-library/src/main/java/com/navinfo/collect/library/map/NIMapView.java index e10dd9a2..f07e6217 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/NIMapView.java +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/NIMapView.java @@ -3,8 +3,8 @@ package com.navinfo.collect.library.map; import android.content.Context; import android.os.Build; import android.os.Bundle; +import android.text.TextUtils; import android.util.AttributeSet; -import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; @@ -12,12 +12,12 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.RelativeLayout; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.navinfo.collect.library.R; import com.navinfo.collect.library.data.entity.NiLocation; import com.navinfo.collect.library.map.layers.NaviMapScaleBar; -import com.navinfo.collect.library.map.source.MapLifeNiLocationTileSource; import org.oscim.android.MapPreferences; import org.oscim.android.MapView; @@ -29,22 +29,14 @@ import org.oscim.event.Gesture; import org.oscim.event.GestureListener; import org.oscim.layers.GroupLayer; import org.oscim.layers.Layer; -import org.oscim.layers.tile.buildings.BuildingLayer; -import org.oscim.layers.tile.vector.OsmTileLayer; import org.oscim.layers.tile.vector.VectorTileLayer; -import org.oscim.layers.tile.vector.labeling.LabelLayer; -import org.oscim.layers.tile.vector.labeling.LabelTileLoaderHook; import org.oscim.map.Map; import org.oscim.renderer.GLViewport; import org.oscim.scalebar.MapScaleBarLayer; -import org.oscim.theme.IRenderTheme; -import org.oscim.theme.ThemeLoader; import org.oscim.theme.VtmThemes; -import org.oscim.tiling.source.mapfile.MapFileTileSource; -import org.oscim.tiling.source.mapfile.MultiMapFileTileSource; -import java.io.File; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; @@ -91,11 +83,6 @@ public final class NIMapView extends RelativeLayout { * 地图状态设置 */ private NIMapOptions options; - /** - * 地图图层管理器 - */ -// private NILayerManager mLayerManager; -// private Layer baseRasterLayer, defaultVectorTileLayer, defaultVectorLabelLayer, gridLayer; /** * 地图网格图层 */ @@ -109,6 +96,23 @@ public final class NIMapView extends RelativeLayout { protected String mapFilePath = "/map"; protected GroupLayer baseGroupLayer; // 用于盛放所有基础底图的图层组,便于统一管理 + + private HashMap listenerList = new HashMap(); + private List listenerTagList = new ArrayList(); + + public HashMap getListenerList() { + return listenerList; + } + + /** + * 获取所有tag + * + * @return + */ + public List getListenerTagList() { + return listenerTagList; + } + public void setOptions(NIMapOptions option) { this.options = option; initOptions(); @@ -812,8 +816,6 @@ public final class NIMapView extends RelativeLayout { /** * 设置logo显隐 - * - * @param position 按钮位置 */ public void setLogoVisable(int visable) { if (logoImage != null) { @@ -886,12 +888,13 @@ public final class NIMapView extends RelativeLayout { /** * 设置比例尺位置 + * * @param position * @param xOffset * @param yOffset */ - public void setScaleBarLayer(GLViewport.Position position, int xOffset, int yOffset){ - if(mapScaleBarLayer!=null&&mapView.map().layers().contains(mapScaleBarLayer)){ + public void setScaleBarLayer(GLViewport.Position position, int xOffset, int yOffset) { + if (mapScaleBarLayer != null && mapView.map().layers().contains(mapScaleBarLayer)) { mapView.map().layers().remove(mapScaleBarLayer); mapScaleBarLayer = null; } @@ -1029,4 +1032,39 @@ public final class NIMapView extends RelativeLayout { mapView.map().updateMap(redraw); } + + /** + * 增加地图点击监听 + */ + public boolean addOnNIMapClickListener(@NonNull String tag, @NonNull BaseClickListener... listeners) { + if (TextUtils.equals(tag, "")) { + return false; + } + for (Object s : listenerTagList) { + if (s == tag) { + return false; + } + } + listenerTagList.add(tag); + listenerList.put(tag, listeners); + return true; + } + + /** + * 移除点击监听 + * + * @param tag + */ + public void removeOnNIMapClickListener(@NonNull String tag) { + listenerList.remove(tag); + for (String t : listenerTagList) { + if (t.equals(tag)) { + listenerTagList.remove(t); + return; + } + } + } } + + + diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/OnGeoPointClickListener.kt b/collect-library/src/main/java/com/navinfo/collect/library/map/OnGeoPointClickListener.kt new file mode 100644 index 00000000..339ed625 --- /dev/null +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/OnGeoPointClickListener.kt @@ -0,0 +1,7 @@ +package com.navinfo.collect.library.map + +import org.oscim.core.GeoPoint + +interface OnGeoPointClickListener : BaseClickListener { + fun onMapClick(tag: String, point: GeoPoint) +} diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LineHandler.kt b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LineHandler.kt index c52bbd7e..3a38ab3c 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LineHandler.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LineHandler.kt @@ -4,6 +4,7 @@ import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import com.navinfo.collect.library.R import com.navinfo.collect.library.data.entity.HadLinkDvoBean +import com.navinfo.collect.library.map.BaseClickListener import com.navinfo.collect.library.map.NIMapView import com.navinfo.collect.library.map.layers.MultiLinesLayer import com.navinfo.collect.library.map.layers.OmdbTaskLinkLayer @@ -19,21 +20,23 @@ import org.oscim.layers.vector.geometries.Style class LineHandler(context: AppCompatActivity, mapView: NIMapView) : BaseHandler(context, mapView) { - //绘制线 样式 - private val lineStyle: Style - - //高亮线绘制线 样式 - private val defaultLineStyle: Style /** * 高亮线图层,同时只高亮一条线,如线选择 */ - private val mDefaultPathLayer: PathLayer + private val mDefaultPathLayer: PathLayer by lazy { + //高亮线绘制线 样式 + val defaultLineStyle = Style.builder() + .stippleColor(context.resources.getColor(R.color.draw_line_blue2_color)) + .strokeWidth(10f) + .fillColor(context.resources.getColor(R.color.teal_200)) + .fillAlpha(0.5f) + .strokeColor(context.resources.getColor(R.color.teal_200)) + .fixed(true).build() - private var onTaskLinkItemClickListener: OnTaskLinkItemClickListener? = null - - fun setOnTaskLinkItemClickListener(listener: OnTaskLinkItemClickListener) { - onTaskLinkItemClickListener = listener + val layer = PathLayer(mMapView.vtmMap, defaultLineStyle) + addLayer(layer, NIMapView.LAYER_GROUPS.OPERATE_LINE) + layer } @@ -84,12 +87,18 @@ class LineHandler(context: AppCompatActivity, mapView: NIMapView) : BaseHandler( markerSymbol, object : OnItemGestureListener { override fun onItemSingleTapUp(index: Int, item: MarkerInterface?): Boolean { - onTaskLinkItemClickListener?.let { - if (item is MarkerItem) { - it.onTaskLink(item.title) + val tag = mMapView.listenerTagList.last() + val listenerList = mMapView.listenerList[tag] + if (listenerList != null) { + for (listener in listenerList) { + if (listener is OnTaskLinkItemClickListener) { + if (item is MarkerItem) { + listener.onTaskLink(tag, item.title) + } + break + } } } - return false } @@ -103,30 +112,6 @@ class LineHandler(context: AppCompatActivity, mapView: NIMapView) : BaseHandler( layer } - init { - - //新增线数据图层和线样式 - lineStyle = Style.builder() - .stippleColor(context.resources.getColor(R.color.draw_line_blue1_color)) - .strokeWidth(4f) - .fillColor(context.resources.getColor(R.color.draw_line_blue2_color)) - .fillAlpha(0.5f) - .strokeColor(context.resources.getColor(R.color.draw_line_blue2_color)) - .fixed(true).build() - - - defaultLineStyle = Style.builder() - .stippleColor(context.resources.getColor(R.color.draw_line_blue2_color)) - .strokeWidth(10f) - .fillColor(context.resources.getColor(R.color.teal_200)) - .fillAlpha(0.5f) - .strokeColor(context.resources.getColor(R.color.teal_200)) - .fixed(true).build() - - mDefaultPathLayer = PathLayer(mMapView.vtmMap, defaultLineStyle) - addLayer(mDefaultPathLayer, NIMapView.LAYER_GROUPS.OPERATE_LINE) - - } /** * 高亮一条线 @@ -226,6 +211,6 @@ class LineHandler(context: AppCompatActivity, mapView: NIMapView) : BaseHandler( } } -interface OnTaskLinkItemClickListener { - fun onTaskLink(taskLinkId: String) +interface OnTaskLinkItemClickListener : BaseClickListener { + fun onTaskLink(tag: String, taskLinkId: String) } \ No newline at end of file diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/MarkHandler.kt b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/MarkHandler.kt index 4b1a65e0..c7aa09be 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/MarkHandler.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/MarkHandler.kt @@ -11,6 +11,7 @@ import com.navinfo.collect.library.R import com.navinfo.collect.library.data.entity.NiLocation import com.navinfo.collect.library.data.entity.NoteBean import com.navinfo.collect.library.data.entity.QsRecordBean +import com.navinfo.collect.library.map.BaseClickListener import com.navinfo.collect.library.map.NIMapView import com.navinfo.collect.library.map.cluster.ClusterMarkerItem import com.navinfo.collect.library.map.cluster.ClusterMarkerRenderer @@ -145,18 +146,22 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : list: MutableList, nearest: Int ): Boolean { - itemListener?.let { - val idList = mutableListOf() - if (list.size == 0) { - } else { - for (i in list) { - val markerInterface: MarkerInterface = - qsRecordItemizedLayer.itemList[i] - if (markerInterface is MarkerItem) { - idList.add(markerInterface.title) + val tag = mMapView.listenerTagList.last() + val listenerList = mMapView.listenerList[tag] + if (listenerList != null) { + for (listener in listenerList) { + if (listener is OnQsRecordItemClickListener) { + val idList = mutableListOf() + for (i in list) { + val markerInterface: MarkerInterface = + qsRecordItemizedLayer.itemList[i] + if (markerInterface is MarkerItem) { + idList.add(markerInterface.title) + } } + listener.onQsRecordList(tag, idList.distinct().toMutableList()) + break } - it.onQsRecordList(idList.distinct().toMutableList()) } } return true @@ -185,8 +190,18 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : ) layer.setOnItemGestureListener(object : OnItemGestureListener { override fun onItemSingleTapUp(index: Int, item: MarkerInterface?): Boolean { - itemListener?.let { - it.onNiLocation((niLocationItemizedLayer.itemList[index] as MarkerItem).uid as NiLocation) + val tag = mMapView.listenerTagList.last() + val listenerList = mMapView.listenerList[tag] + if (listenerList != null) { + for (listener in listenerList) { + if (listener is OnNiLocationItemListener) { + listener.onNiLocation( + tag, + (niLocationItemizedLayer.itemList[index] as MarkerItem).uid as NiLocation + ) + break + } + } } return true } @@ -222,10 +237,17 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : ) layer.setOnItemGestureListener(object : OnItemGestureListener { override fun onItemSingleTapUp(index: Int, item: MarkerInterface?): Boolean { - itemListener?.let { - val marker = layer.itemList[index] - if (marker is MarkerItem) - it.onNote(marker.title) + val tag = mMapView.listenerTagList.last() + val listenerList = mMapView.listenerList[tag] + if (listenerList != null) { + for (listener in listenerList) { + if (listener is ONNoteItemClickListener) { + val marker = layer.itemList[index] + if (marker is MarkerItem) + listener.onNote(tag, marker.title) + break + } + } } return true } @@ -241,7 +263,6 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : private val resId = R.mipmap.map_icon_report private val noteResId = R.drawable.icon_note_marker - private var itemListener: OnQsRecordItemClickListener? = null /** * 文字大小 @@ -259,17 +280,10 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : }) } - /** - * 设置marker 点击回调 - */ - fun setOnQsRecordItemClickListener(listener: OnQsRecordItemClickListener?) { - itemListener = listener - } /** * 增加marker */ - fun addMarker( geoPoint: GeoPoint, title: String?, @@ -753,10 +767,24 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : niLocationItemizedLayer.update() } + /** + * 移除所有质检数据 + */ + fun removeAllQsMarker() { + qsRecordItemizedLayer.removeAllItems() + mMapView.updateMap(true) + } + } -interface OnQsRecordItemClickListener { - fun onQsRecordList(list: MutableList) - fun onNote(noteId: String) - fun onNiLocation(it: NiLocation) +interface OnQsRecordItemClickListener : BaseClickListener { + fun onQsRecordList(tag: String, list: MutableList) } + +interface ONNoteItemClickListener : BaseClickListener { + fun onNote(tag: String, noteId: String) +} + +interface OnNiLocationItemListener : BaseClickListener { + fun onNiLocation(tag: String, it: NiLocation) +} \ No newline at end of file