diff --git a/app/src/main/assets/omdb_config.json b/app/src/main/assets/omdb_config.json index 7d532f4a..46d82ecc 100644 --- a/app/src/main/assets/omdb_config.json +++ b/app/src/main/assets/omdb_config.json @@ -452,7 +452,7 @@ "zoomMin": 15, "zoomMax": 17, "filterData": true, - "isDependOnOtherTable": false, + "isDependOnOtherTable": true, "catch": true, "transformer": [ { @@ -609,7 +609,7 @@ "table": "OMDB_LANE_LINK_LG", "code": 5001, "name": "车道中心线", - "catch": false, + "catch": true, "isDependOnOtherTable": false, "checkLinkId": false, "zoomMin": 18, diff --git a/app/src/main/java/com/navinfo/omqs/db/ImportOMDBHelper.kt b/app/src/main/java/com/navinfo/omqs/db/ImportOMDBHelper.kt index c2c556ab..dbe16498 100644 --- a/app/src/main/java/com/navinfo/omqs/db/ImportOMDBHelper.kt +++ b/app/src/main/java/com/navinfo/omqs/db/ImportOMDBHelper.kt @@ -10,7 +10,6 @@ import com.google.gson.reflect.TypeToken import com.navinfo.collect.library.data.entity.* import com.navinfo.collect.library.enums.DataCodeEnum import com.navinfo.collect.library.utils.DeflaterUtil -import com.navinfo.collect.library.utils.StrZipUtil import com.navinfo.omqs.Constant import com.navinfo.omqs.Constant.Companion.currentInstallTaskConfig import com.navinfo.omqs.Constant.Companion.currentInstallTaskFolder @@ -26,19 +25,34 @@ import io.realm.Realm import io.realm.RealmConfiguration import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.FlowCollector -import kotlinx.coroutines.flow.channelFlow -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.sync.Mutex -import org.spatialite.database.SQLiteDatabase -import sun.misc.BASE64Encoder +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.channels.trySendBlocking +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.conflate import java.io.BufferedReader import java.io.File import java.io.FileReader import java.util.* import javax.inject.Inject + +//定义一个接口 +sealed interface Event +class OnProgress(val value:Int):Event +class OnError(val t:Throwable):Event +class OnResult(val value:T):Event +object OnComplete:Event + +interface MultiPathsCallback{ + fun onProgress(value: Int) + + fun onResult(value: T) + + fun onError(t:Throwable) + + fun onComplete() +} + /** * 导入omdb数据的帮助类 * */ @@ -150,8 +164,9 @@ class ImportOMDBHelper @AssistedInject constructor( * @param configFile 对应的配置文件 * */ suspend fun importOmdbZipFile( - omdbZipFile: File, task: TaskBean, scope: CoroutineScope - ): Boolean { + omdbZipFile: File, task: TaskBean, scope: CoroutineScope,callback: MultiPathsCallback + ) { + val channel = Channel>(Channel.RENDEZVOUS) installTaskid = task.id.toString() @@ -193,9 +208,11 @@ class ImportOMDBHelper @AssistedInject constructor( mutableMapOf, ImportConfig>() //协程池 val listJob = mutableListOf() + try { CMLog.writeLogtoFile(ImportOMDBHelper::class.java.name, "数据安装", "开始安装数据") Constant.INSTALL_DATA = true + for (importConfig in importConfigList) { for ((index, currentEntry) in importConfig.tableMap.entries.withIndex()) { if (currentEntry.value.isDependOnOtherTable) { @@ -203,14 +220,64 @@ class ImportOMDBHelper @AssistedInject constructor( continue } val job = scope.launch(Dispatchers.IO) { - importData( + startTaskAsFlow( channel, unZipFiles, currentEntry, task, importConfig, - hashMap - ) + hashMap, + true).collect{ + when(it){ + OnComplete->{ + processIndex ++ + callback.onResult("$processIndex|$tableNum") + Log.e("jingo", "安装==$processIndex===$tableNum") + if(tableNum-processIndex==listDependOnEntry.size){ + for ((currentEntry, importConfig) in listDependOnEntry) { + processIndex++ + if(processIndex==tableNum){ + importData( + channel, + unZipFiles, + currentEntry, + task, + importConfig, + hashMap, + false, callback + ) + }else{ + callback.onResult("$processIndex|$tableNum") + importData( + channel, + unZipFiles, + currentEntry, + task, + importConfig, + hashMap, + false, null) + } + } + Log.e("jingo", "安装结束") + + CMLog.writeLogtoFile(ImportOMDBHelper::class.java.name, "数据安装", "安装结束") + + Constant.INSTALL_DATA = false + } + } + is OnProgress->{ + callback.onProgress(it.value) + Log.e("qj","progress==${it.value}") + } + is OnResult<*>->{ + callback.onResult(it.value.toString()) + } + is OnError->{ + callback.onError(it.t) + } + + } + } } listJob.add(job) } @@ -225,36 +292,49 @@ class ImportOMDBHelper @AssistedInject constructor( } realm.close() } - } - listJob.joinAll() channel.close() channelJob.join() - Log.e("jingo", "channel close 等待结束") - for ((currentEntry, importConfig) in listDependOnEntry) { - importData( - channel, - unZipFiles, - currentEntry, - task, - importConfig, - hashMap, - false - ) - } - Log.e("jingo", "安装结束") - - CMLog.writeLogtoFile(ImportOMDBHelper::class.java.name, "数据安装", "安装结束") - - Constant.INSTALL_DATA = false - } catch (e: Exception) { Log.e("jingo", "安装报错1 ${e.message}") - return false + + callback.onError(e) + + Constant.INSTALL_DATA = false } - return true } + private fun startTaskAsFlow( + f: Channel>, + unZipFiles: List, + currentEntry: MutableMap.MutableEntry, + task: TaskBean, + importConfig: ImportConfig, + hashMap: HashMap, + isEmit: Boolean = true) = callbackFlow { + val cancellable= importData(f,unZipFiles,currentEntry,task,importConfig,hashMap,isEmit,object :MultiPathsCallback{ + override fun onProgress(value: Int) { + trySendBlocking(OnProgress(value)) + Log.e("jingo","=====$value") + } + + override fun onError(t: Throwable) { + trySendBlocking(OnError(t)) + } + + override fun onComplete() { + trySendBlocking(OnComplete) + } + + override fun onResult(value: String) { + trySendBlocking(OnResult(value)) + } + }) + + awaitClose { + + } + }.conflate() private suspend fun importData( f: Channel>, @@ -263,15 +343,19 @@ class ImportOMDBHelper @AssistedInject constructor( task: TaskBean, importConfig: ImportConfig, hashMap: HashMap, - isEmit: Boolean = true - ) { + isEmit: Boolean = true, callback: MultiPathsCallback? + ):NonCancellable { val resHashMap: HashMap = HashMap() //define empty hashmap var listRenderEntity = mutableListOf() //单个表要素统计 var elementIndex = 0 val currentConfig = currentEntry.value - CMLog.writeLogtoFile(ImportOMDBHelper::class.java.name, "importOmdbZipFile", "${currentConfig.table}开始") + CMLog.writeLogtoFile( + ImportOMDBHelper::class.java.name, + "importOmdbZipFile", + "${currentConfig.table}开始" + ) try { var realm: Realm? = null @@ -295,8 +379,11 @@ class ImportOMDBHelper @AssistedInject constructor( } newTime = System.currentTimeMillis() - if(elementIndex%50==0){ - Log.e("jingo", "安装数据 ${currentConfig.table} $elementIndex ${listRenderEntity.size} ${newTime - time}") + if (elementIndex % 50 == 0) { + Log.e( + "jingo", + "安装数据 ${currentConfig.table} $elementIndex ${listRenderEntity.size} ${newTime - time}" + ) } time = newTime @@ -539,6 +626,7 @@ class ImportOMDBHelper @AssistedInject constructor( when (renderEntity.properties["bridgeType"]) { "1" -> renderEntity.code = DataCodeEnum.OMDB_BRIDGE_1.code + "2" -> renderEntity.code = DataCodeEnum.OMDB_BRIDGE_2.code // "3" -> renderEntity.code = DataCodeEnum.OMDB_BRIDGE_3.code @@ -682,6 +770,21 @@ class ImportOMDBHelper @AssistedInject constructor( renderEntity.properties.remove("linkPid") } + //去掉暂用控件较大的字段多余属性字段 + if (renderEntity.properties.containsKey("shapeList")) { + renderEntity.properties.remove("shapeList") + } + + //只保留link表相关的pid + if (currentConfig.code != DataCodeEnum.OMDB_RD_LINK.code.toInt() && currentConfig.code != DataCodeEnum.OMDB_RD_LINK_KIND.code.toInt() && renderEntity.properties.containsKey( + "linkPid" + ) + ) { + if (renderEntity.properties.containsKey("mesh")) { + renderEntity.properties.remove("mesh") + } + } + // 如果当前解析的是OMDB_RD_LINK数据,将其缓存在预处理类中,以便后续处理其他要素时使用 if (currentConfig.code == DataCodeEnum.OMDB_RD_LINK.code.toInt()) { if (renderEntity.linkRelation == null) { @@ -694,12 +797,8 @@ class ImportOMDBHelper @AssistedInject constructor( renderEntity.properties["enodePid"] } - //去掉暂用控件较大的字段多余属性字段 - if (renderEntity.properties.containsKey("shapeList")) { - renderEntity.properties.remove("shapeList") - } - - renderEntity.propertiesDb = DeflaterUtil.zipString(JSON.toJSONString(renderEntity.properties)) + renderEntity.propertiesDb = + DeflaterUtil.zipString(JSON.toJSONString(renderEntity.properties)) listRenderEntity.add(renderEntity) @@ -713,12 +812,14 @@ class ImportOMDBHelper @AssistedInject constructor( if (isEmit) { f.send(listRenderEntity) delay(20) + callback?.onProgress(elementIndex) } else { realm!!.copyToRealm(listRenderEntity) realm!!.commitTransaction() realm!!.close() realm = Realm.getInstance(currentInstallTaskConfig) realm.beginTransaction() + callback?.onProgress(elementIndex) } listRenderEntity = mutableListOf() // @@ -726,16 +827,21 @@ class ImportOMDBHelper @AssistedInject constructor( line = bufferedReader.readLine() } - CMLog.writeLogtoFile(ImportOMDBHelper::class.java.name, "importOmdbZipFile", "${currentConfig.table}结束===总量$elementIndex") + CMLog.writeLogtoFile( + ImportOMDBHelper::class.java.name, + "importOmdbZipFile", + "${currentConfig.table}结束===总量$elementIndex" + ) if (isEmit) { f.send(listRenderEntity) delay(20) - + callback?.onProgress(elementIndex) } else { bufferedReader.close() realm!!.copyToRealm(listRenderEntity) realm!!.commitTransaction() + callback?.onProgress(elementIndex) } } if (!isEmit) { @@ -745,7 +851,12 @@ class ImportOMDBHelper @AssistedInject constructor( Log.e("jingo", "安装报错 ${currentConfig.table} ${elementIndex} ${e.message}") throw e } + Log.e("jingo", "完成 ${currentConfig.table}") + + callback?.onComplete() + + return NonCancellable } diff --git a/app/src/main/java/com/navinfo/omqs/db/ImportPreProcess.kt b/app/src/main/java/com/navinfo/omqs/db/ImportPreProcess.kt index cb5b22c3..57ba6e93 100644 --- a/app/src/main/java/com/navinfo/omqs/db/ImportPreProcess.kt +++ b/app/src/main/java/com/navinfo/omqs/db/ImportPreProcess.kt @@ -231,6 +231,7 @@ class ImportPreProcess { // startEndReference.renderEntityId = renderEntity.id startEndReference.name = "${renderEntity.name}参考线" startEndReference.table = renderEntity.table + startEndReference.code = renderEntity.code startEndReference.zoomMin = renderEntity.zoomMin startEndReference.zoomMax = renderEntity.zoomMax startEndReference.taskId = renderEntity.taskId @@ -469,6 +470,7 @@ class ImportPreProcess { // angleReference.renderEntityId = renderEntity.id angleReference.name = "${renderEntity.name}参考方向" angleReference.table = renderEntity.table + angleReference.code = renderEntity.code angleReference.zoomMin = renderEntity.zoomMin angleReference.zoomMax = renderEntity.zoomMax angleReference.taskId = renderEntity.taskId @@ -736,9 +738,10 @@ class ImportPreProcess { // angleReference.renderEntityId = renderEntity.id angleReference.name = "${renderEntity.name}车道中线面" angleReference.table = renderEntity.table + angleReference.code = renderEntity.code Log.e("jingo", "几何转换开始") - angleReference.geometry = renderEntity.geometry - //GeometryTools.createGeometry(renderEntity.geometry).buffer(0.000035).toString()//GeometryTools.computeLine(0.000035,0.000035,renderEntity.geometry) + //angleReference.geometry = renderEntity.geometry + angleReference.geometry = GeometryTools.computeLine(0.000035,0.000035,renderEntity.geometry) Log.e("jingo", "几何转换结束") angleReference.properties["qi_table"] = renderEntity.table angleReference.properties["widthProperties"] = "3" @@ -938,6 +941,7 @@ class ImportPreProcess { // dynamicSrcReference.renderEntityId = renderEntity.id dynamicSrcReference.name = "${renderEntity.name}动态icon" dynamicSrcReference.table = renderEntity.table + dynamicSrcReference.code = renderEntity.code dynamicSrcReference.zoomMin = renderEntity.zoomMin dynamicSrcReference.zoomMax = renderEntity.zoomMax dynamicSrcReference.taskId = renderEntity.taskId diff --git a/app/src/main/java/com/navinfo/omqs/http/taskdownload/TaskDownloadScope.kt b/app/src/main/java/com/navinfo/omqs/http/taskdownload/TaskDownloadScope.kt index e93e47fa..8a30d42c 100644 --- a/app/src/main/java/com/navinfo/omqs/http/taskdownload/TaskDownloadScope.kt +++ b/app/src/main/java/com/navinfo/omqs/http/taskdownload/TaskDownloadScope.kt @@ -1,14 +1,18 @@ package com.navinfo.omqs.http.taskdownload +import android.os.Handler +import android.os.Message import android.util.Log import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Observer +import androidx.lifecycle.viewmodel.viewModelFactory import com.blankj.utilcode.util.MapUtils import com.navinfo.collect.library.data.entity.TaskBean import com.navinfo.collect.library.utils.MapParamUtils import com.navinfo.omqs.Constant import com.navinfo.omqs.db.ImportOMDBHelper +import com.navinfo.omqs.db.MultiPathsCallback import com.navinfo.omqs.db.RealmOperateHelper import com.navinfo.omqs.tools.FileManager import com.navinfo.omqs.tools.FileManager.Companion.FileDownloadStatus @@ -155,20 +159,50 @@ class TaskDownloadScope( fileNew ) if (task != null) { - if (importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile, task, this)) { -// if (it == "finish") { - change(FileDownloadStatus.DONE) - Log.e("jingo", "数据安装结束") - withContext(Dispatchers.Main) { - //任务与当前一致,需要更新渲染图层 - if (MapParamUtils.getTaskId() == taskBean.id) { - downloadManager.mapController.layerManagerHandler.updateOMDBVectorTileLayer() + importOMDBHelper.importOmdbZipFile( + importOMDBHelper.omdbFile, + task, + this, + object : MultiPathsCallback { + override fun onProgress(value: Int) { + Log.e("jingo", "安装====$value") } - } - } else { - change(FileDownloadStatus.IMPORTING, "anzhuang") - } -// } + + override fun onError(t: Throwable) { + } + + override fun onComplete() { + taskBean.status = FileDownloadStatus.DONE + downloadData.postValue(taskBean) + //任务与当前一致,需要更新渲染图层 + if (MapParamUtils.getTaskId() == taskBean.id) { + downloadManager.mapController.layerManagerHandler.updateOMDBVectorTileLayer() + } + val realm = realmOperateHelper.getRealmDefaultInstance() + realm.executeTransaction { r -> + val newTask = + realm.where(TaskBean::class.java).equalTo("id", taskBean.id) + .findFirst() + newTask?.let { + it.syncStatus = taskBean.syncStatus + it.status = taskBean.status + it.errMsg = taskBean.errMsg + //赋值时间,用于查询过滤 + it.operationTime = taskBean.operationTime + r.copyToRealmOrUpdate(it) + taskBean = realm.copyFromRealm(it) + } + } + realm.close() + } + + override fun onResult(value: String) { + taskBean.status = FileDownloadStatus.IMPORTING + taskBean.message = value + downloadData.postValue(taskBean) + } + + }) } } catch (e: Exception) { Log.e("jingo", "数据安装失败 ${e.toString()}") diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterViewModel.kt index 8c247086..b18a24f8 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterViewModel.kt @@ -11,6 +11,7 @@ import com.navinfo.omqs.bean.ScProblemTypeBean import com.navinfo.omqs.bean.ScRootCauseAnalysisBean import com.navinfo.omqs.bean.ScWarningCodeBean import com.navinfo.omqs.db.ImportOMDBHelper +import com.navinfo.omqs.db.MultiPathsCallback import com.navinfo.omqs.db.RealmOperateHelper import com.navinfo.omqs.db.RoomAppDatabase import com.navinfo.omqs.tools.MetadataUtils @@ -152,11 +153,36 @@ class PersonalCenterViewModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { Log.d("OMQSApplication", "开始导入数据") if (task != null) { - importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile, task, this) + importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile, task, this,object :MultiPathsCallback{ + override fun onProgress(value: Int) { + } + + override fun onResult(value: String) { + } + + override fun onError(t: Throwable) { + } + + override fun onComplete() { + } + }) } else { val newTask = TaskBean() newTask.id = -1 - importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile, newTask, this) + importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile, newTask, this,object :MultiPathsCallback{ + override fun onProgress(value: Int) { + + } + + override fun onResult(value: String) { + } + + override fun onError(t: Throwable) { + } + + override fun onComplete() { + } + }) } Log.d("OMQSApplication", "导入数据完成") diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskListAdapter.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskListAdapter.kt index 5a8e1e91..dff88859 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskListAdapter.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskListAdapter.kt @@ -325,18 +325,19 @@ class TaskListAdapter( if (binding.taskProgressText.visibility != View.VISIBLE) binding.taskProgressText.visibility = View.VISIBLE binding.taskDownloadBtn.setText("安装中") + Log.e("jingo", "更新进度条 ${taskBean.message}") val split = taskBean.message.split("/") if (split.size == 2) { try { val index = split[0].toInt() val count = split[1].toInt() - binding.taskProgressText.text = - "${index * 100 / count}%" + Log.e("jingo", "更新进度条 $index====$count") + binding.taskProgressText.text = "${index * 100 / count}%" } catch (e: Exception) { Log.e("jingo", "更新进度条 $e") } } else { - binding.taskProgressText.text = "0%" + binding.taskProgressText.text = taskBean.message } val errMsg = taskBean.errMsg if (errMsg != null && errMsg.isNotEmpty()) {