feat: Realm增加查询Link的接口
This commit is contained in:
@@ -6,7 +6,11 @@ import androidx.core.database.getBlobOrNull
|
||||
import androidx.core.database.getFloatOrNull
|
||||
import androidx.core.database.getIntOrNull
|
||||
import androidx.core.database.getStringOrNull
|
||||
import com.blankj.utilcode.util.FileIOUtils
|
||||
import com.blankj.utilcode.util.ZipUtils
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.navinfo.collect.library.data.entity.RenderEntity
|
||||
import com.navinfo.omqs.bean.ImportConfig
|
||||
import com.navinfo.omqs.hilt.ImportOMDBHiltFactory
|
||||
import com.navinfo.omqs.hilt.OMDBDataBaseHiltFactory
|
||||
@@ -90,6 +94,46 @@ class ImportOMDBHelper @AssistedInject constructor(@Assisted("context") val cont
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从zip文件中导入数据到Realm中
|
||||
* @param omdbZipFile omdb数据抽取生成的Zip文件
|
||||
* @param configFile 对应的配置文件
|
||||
* */
|
||||
suspend fun importOmdbZipFile(omdbZipFile: File): Flow<List<Map<String, Any>>> = withContext(Dispatchers.IO) {
|
||||
val importConfig = openConfigFile()
|
||||
val unZipFolder = File(omdbZipFile.parentFile, "result")
|
||||
flow<List<Map<String, Any>>> {
|
||||
if (unZipFolder.exists()) {
|
||||
unZipFolder.deleteRecursively()
|
||||
}
|
||||
unZipFolder.mkdirs()
|
||||
// 开始解压zip文件
|
||||
val unZipFiles = ZipUtils.unzipFile(omdbZipFile, unZipFolder)
|
||||
// 遍历解压后的文件,读取该数据返回
|
||||
for (txtFile in unZipFiles) {
|
||||
val listResult: MutableList<Map<String, Any>> = mutableListOf()
|
||||
// 根据文件名称获取对应的配置
|
||||
val currentConfig=importConfig.tables.find {
|
||||
txtFile.name.substring(0, txtFile.name.lastIndexOf("."))==it.table
|
||||
}
|
||||
val list = FileIOUtils.readFile2List(txtFile, "UTF-8")
|
||||
// 将list数据转换为map
|
||||
for (line in list) {
|
||||
val map = gson.fromJson<Map<String, Any>>(line, object : TypeToken<MutableMap<String, Any>>() {}.type)
|
||||
.toMutableMap()
|
||||
currentConfig?.let {
|
||||
map["QItable"] = currentConfig.table
|
||||
map["QIname"] = currentConfig.name
|
||||
map["QIcode"] = currentConfig.code
|
||||
listResult.add(map)
|
||||
}
|
||||
}
|
||||
// 1个文件发送一次flow流
|
||||
emit(listResult)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取指定数据表的列名
|
||||
fun getColumns(db: SQLiteDatabase, tableName: String): List<String> {
|
||||
val columns = mutableListOf<String>()
|
||||
@@ -110,9 +154,13 @@ class ImportOMDBHelper @AssistedInject constructor(@Assisted("context") val cont
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cursor.close()
|
||||
return columns
|
||||
}
|
||||
|
||||
/**
|
||||
* 预处理渲染要素,某些要素需要对数据做二次处理
|
||||
* */
|
||||
fun performRenderEntity(renderEntity: RenderEntity) {
|
||||
}
|
||||
}
|
||||
94
app/src/main/java/com/navinfo/omqs/db/RealmOperateHelper.kt
Normal file
94
app/src/main/java/com/navinfo/omqs/db/RealmOperateHelper.kt
Normal file
@@ -0,0 +1,94 @@
|
||||
package com.navinfo.omqs.db
|
||||
|
||||
import android.util.Log
|
||||
import com.navinfo.collect.library.data.entity.RenderEntity
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import com.navinfo.collect.library.utils.GeometryTools
|
||||
import com.navinfo.collect.library.utils.GeometryToolsKt
|
||||
import io.realm.Realm
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.locationtech.jts.geom.*
|
||||
import org.locationtech.jts.operation.buffer.BufferOp
|
||||
import org.locationtech.spatial4j.context.SpatialContext
|
||||
import org.locationtech.spatial4j.distance.DistanceUtils
|
||||
import org.oscim.core.GeoPoint
|
||||
import org.oscim.core.MercatorProjection
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
class RealmOperateHelper() {
|
||||
@Inject
|
||||
lateinit var niMapController: NIMapController
|
||||
/**
|
||||
* 根据当前点位查询匹配的Link数据
|
||||
* @param point 点位经纬度信息
|
||||
* @param buffer 点位的外扩距离
|
||||
* @param bufferType 点位外扩距离的单位: 米-Meter,像素-PIXEL
|
||||
* @param order 是否需要排序
|
||||
* */
|
||||
suspend fun queryLink(point: Point, buffer: Double = DEFAULT_BUFFER, bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE, order: Boolean = false): MutableList<RenderEntity> {
|
||||
withContext(Dispatchers.IO) {
|
||||
val polygon = getPolygonFromPoint(point, buffer, bufferType)
|
||||
// 根据polygon查询相交的tile号
|
||||
val tileXSet = mutableSetOf<Int>()
|
||||
GeometryToolsKt.getTileXByGeometry(polygon.toString(), tileXSet)
|
||||
val tileYSet = mutableSetOf<Int>()
|
||||
GeometryToolsKt.getTileYByGeometry(polygon.toString(), tileYSet)
|
||||
|
||||
// 查询realm中对应tile号的数据
|
||||
Realm.getDefaultInstance().where(RenderEntity::class.java).equalTo("table", "HAD_LINK")
|
||||
}
|
||||
return mutableListOf()
|
||||
}
|
||||
|
||||
private fun getPolygonFromPoint(point: Point, buffer: Double = DEFAULT_BUFFER, bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE): Polygon {
|
||||
// 首先计算当前点位的buffer组成的geometry
|
||||
val wkt: Polygon = if (bufferType == BUFFER_TYPE.METER) { // 如果单位是米
|
||||
// 计算米和地球角度之间的关系,在Spatial4J中,经度和纬度的单位是度,而不是米。因此,将距离从米转换为度需要使用一个转换因子,这个转换因子是由地球的周长和360度之间的比例计算得出的。
|
||||
// 在这个例子中,使用的转换因子是111000.0,这是因为地球的周长约为40075公里,而每个经度的距离大约是地球周长的1/360,因此每个经度的距离约为111.32公里
|
||||
val distanceDegrees = DistanceUtils.dist2Degrees(buffer, DistanceUtils.EARTH_MEAN_RADIUS_KM) * 111000.0
|
||||
// 计算外扩矩形
|
||||
BufferOp.bufferOp(point, distanceDegrees) as Polygon
|
||||
} else { // 如果单位是像素,需要根据当前屏幕像素计算出经纬度变化
|
||||
val currentMapScale = niMapController.mMapView.vtmMap.mapPosition.scale
|
||||
// 转换为屏幕坐标
|
||||
val pixelPoint = MercatorProjection.getPixelWithScale(GeoPoint(point.y, point.x), currentMapScale)
|
||||
// 将屏幕坐标外扩指定距离
|
||||
// 计算外扩矩形
|
||||
val envelope = Envelope(
|
||||
MercatorProjection.pixelXToLongitudeWithScale(pixelPoint.x - buffer, currentMapScale),
|
||||
MercatorProjection.pixelXToLongitudeWithScale(pixelPoint.x + buffer, currentMapScale),
|
||||
MercatorProjection.pixelYToLatitudeWithScale(pixelPoint.y - buffer, currentMapScale),
|
||||
MercatorProjection.pixelYToLatitudeWithScale(pixelPoint.y + buffer, currentMapScale),
|
||||
)
|
||||
// 将Envelope对象转换为Polygon对象
|
||||
val geometryFactory = GeometryFactory()
|
||||
val coordinates = arrayOfNulls<Coordinate>(5)
|
||||
coordinates[0] = Coordinate(envelope.minX, envelope.minY)
|
||||
coordinates[1] = Coordinate(envelope.minX, envelope.maxY)
|
||||
coordinates[2] = Coordinate(envelope.maxX, envelope.maxY)
|
||||
coordinates[3] = Coordinate(envelope.maxX, envelope.minY)
|
||||
coordinates[4] = coordinates[0]
|
||||
geometryFactory.createPolygon(coordinates)
|
||||
}
|
||||
|
||||
Log.d("queryLink", wkt.toString())
|
||||
return wkt
|
||||
}
|
||||
}
|
||||
|
||||
enum class BUFFER_TYPE(val index: Int) {
|
||||
METER(0)/*米*/, PIXEL(1)/*像素*/;
|
||||
fun getBufferTypeByIndex(index: Int): BUFFER_TYPE{
|
||||
for (item in BUFFER_TYPE.values()) {
|
||||
if (item.index == index) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return METER
|
||||
}
|
||||
}
|
||||
|
||||
private val DEFAULT_BUFFER: Double = 15.0
|
||||
private val DEFAULT_BUFFER_TYPE = BUFFER_TYPE.METER
|
||||
Reference in New Issue
Block a user