优化数据库查询

This commit is contained in:
squallzhjch 2023-10-20 16:30:27 +08:00
parent 7a99a9d0fb
commit 51c44f00b1
8 changed files with 746 additions and 739 deletions

File diff suppressed because it is too large Load Diff

View File

@ -37,7 +37,9 @@ import org.locationtech.jts.geom.LineString
import org.locationtech.jts.geom.MultiLineString
import org.spatialite.database.SQLiteDatabase
import java.io.File
import java.util.*
import javax.inject.Inject
import kotlin.collections.HashMap
import kotlin.streams.toList
/**
@ -155,7 +157,7 @@ class ImportOMDBHelper @AssistedInject constructor(
.directory(currentInstallTaskFolder)
.name("OMQS.realm")
.encryptionKey(Constant.PASSWORD)
.allowQueriesOnUiThread(true)
// .allowQueriesOnUiThread(true)
.schemaVersion(2)
.build()
val unZipFolder = File(omdbZipFile.parentFile, "result")
@ -181,28 +183,27 @@ class ImportOMDBHelper @AssistedInject constructor(
var tableImportTime = System.currentTimeMillis()
//总表要素统计时间
var dataImportTime = System.currentTimeMillis()
Realm.getInstance(currentInstallTaskConfig).beginTransaction()
val realm = Realm.getInstance(currentInstallTaskConfig)
realm.beginTransaction()
for (importConfig in importConfigList) {
tableNum += importConfig.tableMap.size
}
//缓存任务link信息便于下面与数据进行任务link匹配
val hashMap: HashMap<Long, HadLinkDvoBean> = HashMap<Long, HadLinkDvoBean>()
val lineList = arrayOfNulls<LineString>(task.hadLinkDvoList.size)
var index = 0
// val lineList = arrayOfNulls<LineString>(task.hadLinkDvoList.size)
// var index = 0
task.hadLinkDvoList.forEach {
hashMap[it.linkPid.toLong()] = it
lineList[index] = GeometryTools.createGeometry(it.geometry) as LineString
index++
// lineList[index] = GeometryTools.createGeometry(it.geometry) as LineString
// index++
}
val resHashMap: HashMap<String, RenderEntity> =
HashMap<String, RenderEntity>() //define empty hashmap
try {
var multipLine = MultiLineString(lineList, GeometryFactory())
// var multipLine = MultiLineString(lineList, GeometryFactory())
// 遍历解压后的文件,读取该数据返回
@ -259,13 +260,14 @@ class ImportOMDBHelper @AssistedInject constructor(
renderEntity.zoomMin = map["qi_zoomMin"].toString().toInt()
renderEntity.zoomMax = map["qi_zoomMax"].toString().toInt()
// 在外层记录当前数据的linkPid
if (renderEntity.properties.containsKey("linkPid")) {
if (map.containsKey("linkPid")) {
renderEntity.linkPid =
renderEntity.properties["linkPid"]?.split(",")?.get(0)
map["linkPid"].toString().split(",")
?.get(0)
.toString()
} else if (renderEntity.properties.containsKey("linkList")){
} else if (map.containsKey("linkList")) {
val linkList =
renderEntity.properties["linkList"]
map["linkList"].toString()
if (!linkList.isNullOrEmpty() && linkList != "null") {
val list: List<LinkList> = gson.fromJson(
linkList,
@ -774,13 +776,18 @@ class ImportOMDBHelper @AssistedInject constructor(
if (renderEntity.linkRelation == null) {
renderEntity.linkRelation = LinkRelation()
}
renderEntity.linkRelation!!.sNodeId = renderEntity.properties["snodePid"]
renderEntity.linkRelation!!.eNodeId = renderEntity.properties["enodePid"]
renderEntity.linkRelation!!.sNodeId =
renderEntity.properties["snodePid"]
renderEntity.linkRelation!!.eNodeId =
renderEntity.properties["enodePid"]
// 同时尝试更新RD_link的relation记录中的名称字段
renderEntity.linkRelation!!.linkPid =
renderEntity.properties["linkPid"]
?: UUID.randomUUID().toString()
}
Log.d("ImportOMDBHelper", "解析===1insert")
Realm.getInstance(currentInstallTaskConfig)
.insert(renderEntity)
realm.insert(renderEntity)
Log.d("ImportOMDBHelper", "解析===2insert")
}
if (currentConfig.code == DataCodeEnum.OMDB_RD_LINK.code.toInt()) {
@ -805,30 +812,33 @@ class ImportOMDBHelper @AssistedInject constructor(
)
elementIndex = 0
tableImportTime = System.currentTimeMillis()
if (insertIndex % 20000 == 0) {
if (insertIndex % 20000 == 0 || currentEntry.value.table == DataCodeEnum.OMDB_RD_LINK.name) {
Log.d(
"ImportOMDBHelper",
"表解析===结束用时时间===事物开始"
)
Realm.getInstance(currentInstallTaskConfig).commitTransaction()
Realm.getInstance(currentInstallTaskConfig).beginTransaction()
realm.commitTransaction()
realm.refresh()
realm.beginTransaction()
Log.d(
"ImportOMDBHelper",
"表解析===结束用时时间===事物结束"
)
}
}
}
Realm.getInstance(currentInstallTaskConfig).commitTransaction()
Realm.getInstance(currentInstallTaskConfig).close()
realm.commitTransaction()
realm.close()
Log.d(
"ImportOMDBHelper",
"表解析===结束用时时间${(System.currentTimeMillis() - dataImportTime)}===$dataIndex===插入$insertIndex"
)
Log.e("qj", "安装结束")
} catch (e: Exception) {
if (Realm.getInstance(currentInstallTaskConfig).isInTransaction) {
Realm.getInstance(currentInstallTaskConfig).cancelTransaction()
if (realm.isInTransaction) {
realm.cancelTransaction()
realm.close()
}
throw e
}

View File

@ -15,6 +15,7 @@ import org.locationtech.jts.geom.Coordinate
import org.locationtech.jts.geom.Geometry
import org.locationtech.jts.io.WKTWriter
import org.oscim.core.GeoPoint
import java.util.*
class ImportPreProcess {
@ -582,13 +583,6 @@ class ImportPreProcess {
} else {
renderEntity.properties["name"] = ""
}
// 同时尝试更新RD_link的relation记录中的名称字段
val rdLinkEntity = queryRdLink(renderEntity.properties["linkPid"]!!)
if (rdLinkEntity?.linkRelation == null) {
rdLinkEntity?.linkRelation = LinkRelation()
}
rdLinkEntity?.linkRelation?.linkName = renderEntity.properties["name"]
Realm.getInstance(Constant.currentInstallTaskConfig).insertOrUpdate(rdLinkEntity)
}
/**

View File

@ -178,7 +178,8 @@ class RealmOperateHelper() {
)
val realm = getRealmDefaultInstance()
try {
val realmList = realm.where(HadLinkDvoBean::class.java).equalTo("taskId", taskId).findAll()
val realmList =
realm.where(HadLinkDvoBean::class.java).equalTo("taskId", taskId).findAll()
var linkBean: HadLinkDvoBean? = null
var nearLast: Double = 99999.99
for (link in realmList) {
@ -333,7 +334,7 @@ class RealmOperateHelper() {
val result = mutableListOf<RenderEntity>()
val realmList = getSelectTaskRealmTools(realm, RenderEntity::class.java, false)
.notEqualTo("table", DataCodeEnum.OMDB_RD_LINK.name)
.equalTo("properties['${LinkTable.linkPid}']", linkPid)
.equalTo("linkPid", linkPid)
.findAll()
result.addAll(realm.copyFromRealm(realmList))
return result

View File

@ -816,8 +816,12 @@ class MainViewModel @Inject constructor(
val newLineString = GeometryTools.createLineString(linePoints)
linkId?.let {
val time = System.currentTimeMillis()
val elementList = realmOperateHelper.queryLinkByLinkPid(realm, it)
Log.e("jingo", "捕捉到数据 ${elementList.size}")
Log.e(
"jingo",
"捕捉到数据 ${elementList.size}${System.currentTimeMillis() - time}"
)
for (element in elementList) {
if (element.code == DataCodeEnum.OMDB_LINK_NAME.code) {
hisRoadName = true

View File

@ -81,11 +81,11 @@ class NaviEngine(
/**
* 要查询的link基本信息列表
*/
private val QUERY_KEY_LINK_INFO_LIST = arrayOf(
DataCodeEnum.OMDB_RD_LINK.name,
DataCodeEnum.OMDB_LINK_DIRECT.name,
DataCodeEnum.OMDB_LINK_NAME.name,
)
// private val QUERY_KEY_LINK_INFO_LIST = arrayOf(
// DataCodeEnum.OMDB_RD_LINK.name,
// DataCodeEnum.OMDB_LINK_DIRECT.name,
// DataCodeEnum.OMDB_LINK_NAME.name,
// )
// /**
// * 偏离距离 单位:米
@ -215,62 +215,56 @@ class NaviEngine(
)
route.pointList = GeometryTools.getGeoPoints(link.geometry)
var time = System.currentTimeMillis()
val res = realm.where(RenderEntity::class.java)
.equalTo("table", DataCodeEnum.OMDB_RD_LINK.name).equalTo("linkPid", link.linkPid)
.findFirst()
val res = realm.where(RenderEntity::class.java).`in`("table", QUERY_KEY_LINK_INFO_LIST)
.equalTo("properties['linkPid']", link.linkPid).findAll()
var bHasNode = false
var bHasDir = false
var bHasName = false
if (res != null) {
for (entity in res) {
when (entity.code) {
DataCodeEnum.OMDB_RD_LINK.code -> {
bHasNode = true
val snodePid = entity.properties["snodePid"]
if (snodePid != null) {
route.sNode = snodePid
} else {
bHasNode = false
}
val enodePid = entity.properties["enodePid"]
if (enodePid != null) {
route.eNode = enodePid
} else {
bHasNode = false
}
}
DataCodeEnum.OMDB_LINK_DIRECT.code -> {
val direct = entity.properties["direct"]
if (direct != null) {
bHasDir = true
route.direct = direct.toInt()
}
}
DataCodeEnum.OMDB_LINK_NAME.code -> {
bHasName = true
route.name = realm.copyFromRealm(entity)
}
}
Log.e("jingo","查询link时间 ${System.currentTimeMillis() - time}")
if (res?.linkRelation != null) {
if (res.linkRelation!!.sNodeId == null) {
callback.planningPathStatus(
NaviStatus.NAVI_STATUS_PATH_ERROR_NODE
)
return
} else {
route.sNode = res.linkRelation!!.sNodeId!!
}
}
if (!bHasNode) {
if (res.linkRelation!!.eNodeId == null) {
callback.planningPathStatus(
NaviStatus.NAVI_STATUS_PATH_ERROR_NODE
)
return
} else {
route.eNode = res.linkRelation!!.eNodeId!!
}
route.direct = res.linkRelation!!.direct
// route.name = res.linkRelation!!.linkName
time = System.currentTimeMillis()
val otherLinks = realm.where(RenderEntity::class.java)
.equalTo("table", DataCodeEnum.OMDB_RD_LINK.name)
.notEqualTo("linkPid", route.linkId).beginGroup()
.`in`("linkRelation.sNodeId", arrayOf(route.sNode, route.eNode)).or()
.`in`("linkRelation.eNodeId", arrayOf(route.sNode, route.eNode)).endGroup()
.findAll()
Log.e("jingo","拓扑道路时间 ${System.currentTimeMillis() - time}${otherLinks.size}")
} else {
callback.planningPathStatus(
NaviStatus.NAVI_STATUS_PATH_ERROR_NODE
)
return
}
if (!bHasDir) {
callback.planningPathStatus(
NaviStatus.NAVI_STATUS_PATH_ERROR_DIRECTION
)
return
}
pathList.add(route)
}
//用来存储最终的导航路径
val newRouteList = mutableListOf<NaviRoute>()
//比对路径排序用的
val tempRouteList = pathList.toMutableList()
//先找到一根有方向的link确定起终点
var routeStart: NaviRoute? = null
for (i in tempRouteList.indices) {
@ -290,7 +284,7 @@ class NaviEngine(
var sNode = ""
var eNode = ""
//如果sNodeeNode是顺方向geometry 不动,否则反转
//如果sNodeeNode是顺方向geometry 不动,否则反转
if (routeStart.direct == 3) {
routeStart.pointList.reverse()
sNode = routeStart.eNode
@ -355,15 +349,14 @@ class NaviEngine(
}
val itemMap: MutableMap<GeoPoint, MutableList<RenderEntity>> = mutableMapOf()
//查询每根link上的关联要素
//查询每根link上的关联要素
for (route in newRouteList) {
itemMap.clear()
//常规点限速
val res = realm.where(RenderEntity::class.java)
.equalTo("properties['linkPid']", route.linkId).and().`in`(
"table",
QUERY_KEY_ITEM_LIST
).findAll()
val res =
realm.where(RenderEntity::class.java).equalTo("linkPid", route.linkId).and().`in`(
"table", QUERY_KEY_ITEM_LIST
).findAll()
if (res.isNotEmpty()) {
// Log.e("jingo", "道路查询预警要素 ${route.linkId} ${res.size}条数据")
for (r in res) {
@ -541,8 +534,7 @@ class NaviEngine(
// if (route.itemList != null) {
// Log.e("jingo", "${route.linkId}我有${route.itemList!!.size}个要素 ")
// }
if (route.indexInPath < routeIndex)
continue
if (route.indexInPath < routeIndex) continue
if (route.indexInPath == routeIndex) {
currentRoute = route
}

View File

@ -8,6 +8,7 @@ import io.realm.RealmDictionary
import io.realm.RealmObject
import io.realm.RealmSet
import io.realm.annotations.Ignore
import io.realm.annotations.Index
import io.realm.annotations.PrimaryKey
import kotlinx.parcelize.Parcelize
import org.locationtech.jts.geom.Coordinate
@ -21,10 +22,12 @@ import java.util.*
@Parcelize
open class LinkRelation() : RealmObject(), Parcelable {
@PrimaryKey
var id: String = UUID.randomUUID().toString() // id
var linkPid:String = UUID.randomUUID().toString()
@Index
var sNodeId: String? = null
@Index
var eNodeId: String? = null
var linkName: String? = null
var direct: Int = 0
constructor(direct: Int) : this() {

View File

@ -8,6 +8,7 @@ import io.realm.RealmDictionary
import io.realm.RealmObject
import io.realm.RealmSet
import io.realm.annotations.Ignore
import io.realm.annotations.Index
import io.realm.annotations.PrimaryKey
import kotlinx.parcelize.Parcelize
import org.locationtech.jts.geom.Coordinate
@ -56,13 +57,16 @@ open class RenderEntity() : RealmObject(), Parcelable {
return field
}
var properties: RealmDictionary<String> = RealmDictionary()
@Ignore
var tileX: RealmSet<Int> = RealmSet() // x方向的tile编码
@Ignore
var tileY: RealmSet<Int> = RealmSet() // y方向的tile编码
var taskId: Int = 0 //任务ID
var zoomMin: Int = 18 //显示最小级别
var zoomMax: Int = 23 //显示最大级别
var enable:Int = 0 // 默认0不是显示 1为渲染显示 2为常显
var catchEnable:Int = 0 // 0不捕捉 1捕捉
@Index
lateinit var linkPid: String // RenderEntity关联的linkPid集合(可能会关联多个)
var linkRelation: LinkRelation? = null