优化数据库查询
This commit is contained in:
parent
202e2b3a8e
commit
129c48f11d
@ -154,7 +154,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")
|
||||
|
@ -431,7 +431,7 @@ class LoginViewModel @Inject constructor(
|
||||
.directory(userFolder)
|
||||
.name("OMQS.realm")
|
||||
.encryptionKey(Constant.PASSWORD)
|
||||
.allowQueriesOnUiThread(true)
|
||||
// .allowQueriesOnUiThread(true)
|
||||
.schemaVersion(2)
|
||||
.build()
|
||||
Realm.setDefaultConfiguration(config)
|
||||
|
@ -50,7 +50,9 @@ import io.realm.Realm
|
||||
import io.realm.RealmConfiguration
|
||||
import io.realm.RealmSet
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import org.locationtech.jts.geom.Geometry
|
||||
import org.oscim.core.GeoPoint
|
||||
@ -239,11 +241,14 @@ class MainViewModel @Inject constructor(
|
||||
//导航信息
|
||||
private var naviEngine: NaviEngine? = null
|
||||
|
||||
private var naviEngineNew: NaviEngineNew = NaviEngineNew(realmOperateHelper)
|
||||
|
||||
// 0:不导航 1:导航 2:暂停
|
||||
private var naviEngineStatus = 0
|
||||
|
||||
// 定义一个互斥锁
|
||||
private val naviMutex = Mutex()
|
||||
private var testRealm: Realm? = null;
|
||||
|
||||
init {
|
||||
mapController.mMapView.vtmMap.events.bind(Map.UpdateListener { e, mapPosition ->
|
||||
@ -336,32 +341,44 @@ class MainViewModel @Inject constructor(
|
||||
File(Constant.USER_DATA_PATH + "/${MapParamUtils.getTaskId()}")
|
||||
Constant.currentSelectTaskConfig =
|
||||
RealmConfiguration.Builder().directory(Constant.currentSelectTaskFolder)
|
||||
.name("OMQS.realm").encryptionKey(Constant.PASSWORD).allowQueriesOnUiThread(true)
|
||||
.name("OMQS.realm").encryptionKey(Constant.PASSWORD)
|
||||
// .allowQueriesOnUiThread(true)
|
||||
.schemaVersion(2).build()
|
||||
MapParamUtils.setTaskConfig(Constant.currentSelectTaskConfig)
|
||||
socketServer = SocketServer(mapController, traceDataBase, sharedPreferences)
|
||||
|
||||
// viewModelScope.launch(Dispatchers.Default) {
|
||||
// naviTestFlow().collect { point ->
|
||||
// if (naviEngineStatus == 1) {
|
||||
// naviEngine?.let {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
|
||||
naviTestFlow().collect { point ->
|
||||
if (naviEngineStatus == 1) {
|
||||
naviEngineNew.let {
|
||||
// naviMutex.lock()
|
||||
Log.e("jingo","${Thread.currentThread().name} ${Thread.currentThread().hashCode()}")
|
||||
if (testRealm == null)
|
||||
testRealm = realmOperateHelper.getSelectTaskRealmInstance()
|
||||
if (currentTaskBean != null) {
|
||||
naviEngineNew.bindingRoute(
|
||||
taskBean = currentTaskBean!!,
|
||||
geoPoint = point,
|
||||
realm = testRealm!!
|
||||
)
|
||||
}
|
||||
// it.bindingRoute(null, point)
|
||||
// naviMutex.unlock()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// fun naviTestFlow(): Flow<GeoPoint> = flow {
|
||||
//
|
||||
// while (true) {
|
||||
// emit(mapController.mMapView.vtmMap.mapPosition.geoPoint)
|
||||
// delay(1000)
|
||||
// }
|
||||
// }
|
||||
fun naviTestFlow(): Flow<GeoPoint> = flow {
|
||||
|
||||
while (true) {
|
||||
emit(mapController.mMapView.vtmMap.mapPosition.geoPoint)
|
||||
delay(5000)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前任务
|
||||
@ -559,62 +576,62 @@ class MainViewModel @Inject constructor(
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
//用于定位点捕捉道路
|
||||
mapController.locationLayerHandler.niLocationFlow.collect { location ->
|
||||
|
||||
//过滤掉无效点
|
||||
if (!naviLocationTest && !GeometryTools.isCheckError(
|
||||
location.longitude,
|
||||
location.latitude
|
||||
)
|
||||
) {
|
||||
val geometry = GeometryTools.createGeometry(
|
||||
GeoPoint(
|
||||
location.latitude, location.longitude
|
||||
)
|
||||
)
|
||||
val tileX = RealmSet<Int>()
|
||||
GeometryToolsKt.getTileXByGeometry(geometry.toString(), tileX)
|
||||
val tileY = RealmSet<Int>()
|
||||
GeometryToolsKt.getTileYByGeometry(geometry.toString(), tileY)
|
||||
|
||||
//遍历存储tile对应的x与y的值
|
||||
tileX.forEach { x ->
|
||||
tileY.forEach { y ->
|
||||
location.tilex = x
|
||||
location.tiley = y
|
||||
}
|
||||
}
|
||||
location.groupId = uuid
|
||||
try {
|
||||
location.timeStamp = DateTimeUtil.getTime(location.time).toString()
|
||||
} catch (e: Exception) {
|
||||
|
||||
}
|
||||
|
||||
location.taskId =
|
||||
sharedPreferences.getInt(Constant.SELECT_TASK_ID, -1).toString()
|
||||
|
||||
//判断如果是连接状态并处于录像模式,标记为有效点
|
||||
if (shareUtil?.connectstate == true && shareUtil?.takeCameraMode == 0) {
|
||||
location.media = 1
|
||||
}
|
||||
var disance = 0.0
|
||||
//增加间距判断
|
||||
if (lastNiLocaion != null) {
|
||||
disance = GeometryTools.getDistance(
|
||||
location.latitude,
|
||||
location.longitude,
|
||||
lastNiLocaion!!.latitude,
|
||||
lastNiLocaion!!.longitude
|
||||
)
|
||||
}
|
||||
//室内整理工具时不能进行轨迹存储,判断轨迹间隔要超过2.5并小于60米
|
||||
if (Constant.INDOOR_IP.isEmpty() && (disance == 0.0 || (disance > 2.5 && disance < 60))) {
|
||||
traceDataBase.niLocationDao.insert(location)
|
||||
mapController.markerHandle.addNiLocationMarkerItem(location)
|
||||
mapController.mMapView.vtmMap.updateMap(true)
|
||||
lastNiLocaion = location
|
||||
}
|
||||
}
|
||||
//
|
||||
// //过滤掉无效点
|
||||
// if (!naviLocationTest && !GeometryTools.isCheckError(
|
||||
// location.longitude,
|
||||
// location.latitude
|
||||
// )
|
||||
// ) {
|
||||
// val geometry = GeometryTools.createGeometry(
|
||||
// GeoPoint(
|
||||
// location.latitude, location.longitude
|
||||
// )
|
||||
// )
|
||||
// val tileX = RealmSet<Int>()
|
||||
// GeometryToolsKt.getTileXByGeometry(geometry.toString(), tileX)
|
||||
// val tileY = RealmSet<Int>()
|
||||
// GeometryToolsKt.getTileYByGeometry(geometry.toString(), tileY)
|
||||
//
|
||||
// //遍历存储tile对应的x与y的值
|
||||
// tileX.forEach { x ->
|
||||
// tileY.forEach { y ->
|
||||
// location.tilex = x
|
||||
// location.tiley = y
|
||||
// }
|
||||
// }
|
||||
// location.groupId = uuid
|
||||
// try {
|
||||
// location.timeStamp = DateTimeUtil.getTime(location.time).toString()
|
||||
// } catch (e: Exception) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// location.taskId =
|
||||
// sharedPreferences.getInt(Constant.SELECT_TASK_ID, -1).toString()
|
||||
//
|
||||
// //判断如果是连接状态并处于录像模式,标记为有效点
|
||||
// if (shareUtil?.connectstate == true && shareUtil?.takeCameraMode == 0) {
|
||||
// location.media = 1
|
||||
// }
|
||||
// var disance = 0.0
|
||||
// //增加间距判断
|
||||
// if (lastNiLocaion != null) {
|
||||
// disance = GeometryTools.getDistance(
|
||||
// location.latitude,
|
||||
// location.longitude,
|
||||
// lastNiLocaion!!.latitude,
|
||||
// lastNiLocaion!!.longitude
|
||||
// )
|
||||
// }
|
||||
// //室内整理工具时不能进行轨迹存储,判断轨迹间隔要超过2.5并小于60米
|
||||
// if (Constant.INDOOR_IP.isEmpty() && (disance == 0.0 || (disance > 2.5 && disance < 60))) {
|
||||
// traceDataBase.niLocationDao.insert(location)
|
||||
// mapController.markerHandle.addNiLocationMarkerItem(location)
|
||||
// mapController.mMapView.vtmMap.updateMap(true)
|
||||
// lastNiLocaion = location
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
@ -636,11 +653,11 @@ class MainViewModel @Inject constructor(
|
||||
naviEngine!!.bindingRoute(location, point)
|
||||
naviMutex.unlock()
|
||||
} else {
|
||||
captureLink(
|
||||
GeoPoint(
|
||||
location.latitude, location.longitude
|
||||
)
|
||||
)
|
||||
// captureLink(
|
||||
// GeoPoint(
|
||||
// location.latitude, location.longitude
|
||||
// )
|
||||
// )
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -983,6 +1000,7 @@ class MainViewModel @Inject constructor(
|
||||
if (!hisRoadName) {
|
||||
liveDataRoadName.postValue(null)
|
||||
}
|
||||
Log.e("jingo", "另一个地方查询数据库")
|
||||
realm.close()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
@ -1001,6 +1019,7 @@ class MainViewModel @Inject constructor(
|
||||
mapPosition.setBearing(0f) // 锁定角度,自动将地图旋转到正北方向
|
||||
mapController.mMapView.vtmMap.setMapPosition(mapPosition)
|
||||
mapController.locationLayerHandler.animateToCurrentPosition()
|
||||
naviEngineStatus = 1
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1677,7 +1696,7 @@ class MainViewModel @Inject constructor(
|
||||
val tempTime = nowTime - lastTime
|
||||
if (tempTime > 10000) {
|
||||
liveDataMessage.postValue("下个定位点与当前定位点时间间隔超过10秒(${tempTime}),将直接跳转到下个点")
|
||||
delay(5000)
|
||||
delay(2000)
|
||||
} else {
|
||||
delay(tempTime)
|
||||
}
|
||||
|
@ -276,7 +276,8 @@ class TaskViewModel @Inject constructor(
|
||||
Constant.currentSelectTaskFolder = File(Constant.USER_DATA_PATH + "/${taskBean.id}")
|
||||
Constant.currentSelectTaskConfig =
|
||||
RealmConfiguration.Builder().directory(Constant.currentSelectTaskFolder)
|
||||
.name("OMQS.realm").encryptionKey(Constant.PASSWORD).allowQueriesOnUiThread(true)
|
||||
.name("OMQS.realm").encryptionKey(Constant.PASSWORD)
|
||||
//.allowQueriesOnUiThread(true)
|
||||
.schemaVersion(2).build()
|
||||
MapParamUtils.setTaskConfig(Constant.currentSelectTaskConfig)
|
||||
mapController.layerManagerHandler.updateOMDBVectorTileLayer()
|
||||
|
96
app/src/main/java/com/navinfo/omqs/util/NaviEngineNew.kt
Normal file
96
app/src/main/java/com/navinfo/omqs/util/NaviEngineNew.kt
Normal file
@ -0,0 +1,96 @@
|
||||
package com.navinfo.omqs.util
|
||||
|
||||
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.NiLocation
|
||||
import com.navinfo.collect.library.data.entity.RenderEntity
|
||||
import com.navinfo.collect.library.data.entity.TaskBean
|
||||
import com.navinfo.collect.library.enums.DataCodeEnum
|
||||
import com.navinfo.collect.library.utils.FootAndDistance
|
||||
import com.navinfo.collect.library.utils.GeometryTools
|
||||
import com.navinfo.omqs.db.RealmOperateHelper
|
||||
import io.realm.Realm
|
||||
import org.oscim.core.GeoPoint
|
||||
import java.time.LocalDate
|
||||
import java.time.LocalDateTime
|
||||
|
||||
class NaviEngineNew(
|
||||
private val realmOperateHelper: RealmOperateHelper,
|
||||
) {
|
||||
/**
|
||||
* 要查询的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 locationList = mutableListOf<NiLocation>()
|
||||
|
||||
|
||||
suspend fun bindingRoute(
|
||||
niLocation: NiLocation? = null,
|
||||
taskBean: TaskBean,
|
||||
geoPoint: GeoPoint,
|
||||
realm:Realm
|
||||
) {
|
||||
// val geoPoint = GeoPoint(niLocation.latitude, niLocation.longitude)
|
||||
var latestRoute: HadLinkDvoBean? = null
|
||||
var lastDis = -1.0
|
||||
|
||||
for (link in taskBean.hadLinkDvoList) {
|
||||
val linkGeometry = GeometryTools.createGeometry(link.geometry)
|
||||
val footAndDistance = GeometryTools.pointToLineDistance(geoPoint, linkGeometry)
|
||||
val meterD = footAndDistance.getMeterDistance()
|
||||
if (meterD < 15 && (lastDis < 0 || lastDis > meterD)) {
|
||||
latestRoute = link
|
||||
lastDis = meterD
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
latestRoute?.let {
|
||||
var lastTime = System.currentTimeMillis()
|
||||
|
||||
var nowTime = System.currentTimeMillis()
|
||||
Log.e("jingo","打开数据库 ${nowTime - lastTime}")
|
||||
lastTime = nowTime
|
||||
val res2 =
|
||||
realm.where(RenderEntity::class.java).`in`("table", QUERY_KEY_LINK_INFO_LIST)
|
||||
.equalTo("properties['linkPid']", it.linkPid).findAll()
|
||||
nowTime = System.currentTimeMillis()
|
||||
Log.e("jingo", "第一种 耗时 ${nowTime - lastTime}")
|
||||
if (res2 != null) {
|
||||
for (entity in res2) {
|
||||
when (entity.code) {
|
||||
DataCodeEnum.OMDB_RD_LINK.code -> {
|
||||
val snodePid = entity.properties["snodePid"]
|
||||
if (snodePid != null) {
|
||||
} else {
|
||||
}
|
||||
val enodePid = entity.properties["enodePid"]
|
||||
if (enodePid != null) {
|
||||
} else {
|
||||
}
|
||||
}
|
||||
DataCodeEnum.OMDB_LINK_DIRECT.code -> {
|
||||
val direct = entity.properties["direct"]
|
||||
if (direct != null) {
|
||||
}
|
||||
}
|
||||
DataCodeEnum.OMDB_LINK_NAME.code -> {
|
||||
// var name = realm.copyFromRealm(res4)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -24,7 +24,10 @@ open class ReferenceEntity() : RealmObject() {
|
||||
var zoomMax: Int = 23 //显示最大级别
|
||||
var taskId: Int = 0 //任务ID
|
||||
var enable:Int = 0 // 默认0不是显示 1为渲染显示
|
||||
|
||||
var tileXMin:Int =0
|
||||
var tileXMax:Int = 0
|
||||
var tileYMin:Int =0
|
||||
var tileYMax:Int = 0
|
||||
var geometry: String = "" // 要素渲染参考的geometry,该数据可能会在导入预处理环节被修改,原始geometry会保存在properties的geometry字段下
|
||||
get() {
|
||||
wkt = GeometryTools.createGeometry(field)
|
||||
@ -34,7 +37,13 @@ open class ReferenceEntity() : RealmObject() {
|
||||
field = value
|
||||
// 根据geometry自动计算当前要素的x-tile和y-tile
|
||||
GeometryToolsKt.getTileXByGeometry(value, tileX)
|
||||
tileXMin = tileX.min()
|
||||
tileXMax = tileX.max()
|
||||
|
||||
GeometryToolsKt.getTileYByGeometry(value, tileY)
|
||||
|
||||
tileYMin = tileY.min()
|
||||
tileYMax = tileY.max()
|
||||
// 根据传入的geometry文本,自动转换为Geometry对象
|
||||
try {
|
||||
wkt = GeometryTools.createGeometry(value)
|
||||
|
@ -34,7 +34,15 @@ open class RenderEntity() : RealmObject(), Parcelable {
|
||||
field = value
|
||||
// 根据geometry自动计算当前要素的x-tile和y-tile
|
||||
GeometryToolsKt.getTileXByGeometry(value, tileX)
|
||||
|
||||
tileXMin = tileX.min()
|
||||
tileXMax = tileX.max()
|
||||
|
||||
GeometryToolsKt.getTileYByGeometry(value, tileY)
|
||||
|
||||
tileYMin = tileY.min()
|
||||
tileYMax = tileY.max()
|
||||
|
||||
// 根据传入的geometry文本,自动转换为Geometry对象
|
||||
try {
|
||||
wkt = GeometryTools.createGeometry(value)
|
||||
@ -58,6 +66,10 @@ open class RenderEntity() : RealmObject(), Parcelable {
|
||||
var properties: RealmDictionary<String> = RealmDictionary()
|
||||
var tileX: RealmSet<Int> = RealmSet() // x方向的tile编码
|
||||
var tileY: RealmSet<Int> = RealmSet() // y方向的tile编码
|
||||
var tileXMin:Int =0
|
||||
var tileXMax:Int = 0
|
||||
var tileYMin:Int =0
|
||||
var tileYMax:Int = 0
|
||||
var taskId: Int = 0 //任务ID
|
||||
var zoomMin: Int = 18 //显示最小级别
|
||||
var zoomMax: Int = 23 //显示最大级别
|
||||
|
@ -224,7 +224,6 @@ private class MyLocationListener(callback: (BDLocation) -> Unit) : BDAbstractLoc
|
||||
val call = callback;
|
||||
override fun onReceiveLocation(location: BDLocation) {
|
||||
call(location)
|
||||
Log.e("jingo", "定位结果:速度=" + location.speed + " 方向=" + location.direction)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import android.util.Log;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.navinfo.collect.library.data.entity.ReferenceEntity;
|
||||
import com.navinfo.collect.library.data.entity.RenderEntity;
|
||||
import com.navinfo.collect.library.system.Constant;
|
||||
import com.navinfo.collect.library.utils.GeometryTools;
|
||||
import com.navinfo.collect.library.utils.MapParamUtils;
|
||||
@ -17,6 +18,7 @@ import org.oscim.tiling.ITileDataSink;
|
||||
import org.oscim.tiling.ITileDataSource;
|
||||
import org.oscim.tiling.QueryResult;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -43,6 +45,8 @@ public class OMDBReferenceDataSource implements ITileDataSource {
|
||||
public void query(MapTile tile, ITileDataSink mapDataSink) {
|
||||
// 获取tile对应的坐标范围
|
||||
if (tile.zoomLevel >= Constant.OMDB_MIN_ZOOM && tile.zoomLevel <= Constant.DATA_ZOOM) {
|
||||
Realm realm = Realm.getInstance(MapParamUtils.getTaskConfig());
|
||||
RealmQuery<ReferenceEntity> realmQuery = realm.where(ReferenceEntity.class);
|
||||
int m = Constant.DATA_ZOOM - tile.zoomLevel;
|
||||
int xStart = tile.tileX;
|
||||
int xEnd = tile.tileX + 1;
|
||||
@ -57,11 +61,13 @@ public class OMDBReferenceDataSource implements ITileDataSource {
|
||||
final int currentTileX = xStart;
|
||||
|
||||
if (isUpdate) {
|
||||
Realm.getInstance(MapParamUtils.getTaskConfig()).refresh();
|
||||
realm.refresh();
|
||||
isUpdate = false;
|
||||
}
|
||||
|
||||
String sql = " tileX>=" + xStart + " and tileX<=" + xEnd + " and tileY>=" + yStart + " and tileY<=" + yEnd + "";
|
||||
String sql = " ((tileXMin <= " + xStart + " and tileXMax >= " + xStart + ") or (tileXMin <=" + xEnd + " and tileXMax >=" + xStart + ")) and ((tileYMin <= " + yStart + " and tileYMax >= " + yStart + ") or (tileYMin <=" + yEnd + " and tileYMin >=" + yStart + "))";
|
||||
|
||||
// String sql = " tileX>=" + xStart + " and tileX<=" + xEnd + " and tileY>=" + yStart + " and tileY<=" + yEnd + "";
|
||||
|
||||
if (MapParamUtils.getDataLayerEnum() != null) {
|
||||
sql += " and enable" + MapParamUtils.getDataLayerEnum().getSql();
|
||||
@ -69,8 +75,7 @@ public class OMDBReferenceDataSource implements ITileDataSource {
|
||||
sql += " and enable>=0";
|
||||
}
|
||||
|
||||
RealmQuery<ReferenceEntity> realmQuery = Realm.getInstance(MapParamUtils.getTaskConfig()).where(ReferenceEntity.class)
|
||||
.rawPredicate(sql);
|
||||
realmQuery.rawPredicate(sql);
|
||||
// 筛选不显示的数据
|
||||
if (Constant.HAD_LAYER_INVISIABLE_ARRAY != null && Constant.HAD_LAYER_INVISIABLE_ARRAY.length > 0) {
|
||||
realmQuery.beginGroup();
|
||||
@ -91,10 +96,11 @@ public class OMDBReferenceDataSource implements ITileDataSource {
|
||||
} else {
|
||||
mapDataSink.completed(QueryResult.SUCCESS);
|
||||
}
|
||||
Realm.getInstance(MapParamUtils.getTaskConfig()).close();
|
||||
realm.close();
|
||||
} else {
|
||||
mapDataSink.completed(QueryResult.SUCCESS);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -11,21 +11,45 @@ import com.navinfo.collect.library.utils.GeometryTools;
|
||||
import com.navinfo.collect.library.utils.MapParamUtils;
|
||||
|
||||
import org.locationtech.jts.geom.Polygon;
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.layers.tile.MapTile;
|
||||
import org.oscim.map.Map;
|
||||
import org.oscim.map.Viewport;
|
||||
import org.oscim.tiling.ITileDataSink;
|
||||
import org.oscim.tiling.ITileDataSource;
|
||||
import org.oscim.tiling.QueryResult;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import io.realm.Realm;
|
||||
import io.realm.RealmConfiguration;
|
||||
import io.realm.RealmQuery;
|
||||
|
||||
public class OMDBTileDataSource implements ITileDataSource {
|
||||
|
||||
class RealmObject {
|
||||
int threadCode;
|
||||
int realmConfigCode;
|
||||
Realm realm;
|
||||
}
|
||||
|
||||
// class DataObject {
|
||||
// int threadCode = 0;
|
||||
// byte zoom = 0;
|
||||
// String lonLat = "";
|
||||
// List<String> listIds = new ArrayList<>();
|
||||
// }
|
||||
|
||||
private boolean isUpdate;
|
||||
private Viewport viewport;
|
||||
|
||||
private List<RealmObject> realmObjectList = new ArrayList<>();
|
||||
|
||||
// private List<DataObject> dataObjectList = new ArrayList<>();
|
||||
|
||||
private final ThreadLocal<OMDBDataDecoder> mThreadLocalDecoders = new ThreadLocal<OMDBDataDecoder>() {
|
||||
@Override
|
||||
protected OMDBDataDecoder initialValue() {
|
||||
@ -42,6 +66,40 @@ public class OMDBTileDataSource implements ITileDataSource {
|
||||
public void query(MapTile tile, ITileDataSink mapDataSink) {
|
||||
// 获取tile对应的坐标范围
|
||||
if (tile.zoomLevel >= Constant.OMDB_MIN_ZOOM && tile.zoomLevel <= Constant.DATA_ZOOM) {
|
||||
Realm realm = null;
|
||||
int threadCode = Thread.currentThread().hashCode();
|
||||
// MapPosition pos = new MapPosition();
|
||||
// viewport.getMapPosition(pos);
|
||||
// DataObject newDataObject = new DataObject();
|
||||
// newDataObject.zoom = tile.zoomLevel;
|
||||
// newDataObject.threadCode = threadCode;
|
||||
// newDataObject.lonLat = pos.getX() + "," + pos.getY();
|
||||
synchronized (realmObjectList) {
|
||||
int configCode = MapParamUtils.getTaskConfig().hashCode();
|
||||
for (RealmObject object : realmObjectList) {
|
||||
if (object.threadCode == threadCode) {
|
||||
if (object.realmConfigCode == configCode) {
|
||||
realm = object.realm;
|
||||
} else {
|
||||
object.realm.close();
|
||||
realmObjectList.remove(object);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (realm == null) {
|
||||
realm = Realm.getInstance(MapParamUtils.getTaskConfig());
|
||||
RealmObject o = new RealmObject();
|
||||
o.threadCode = threadCode;
|
||||
o.realmConfigCode = configCode;
|
||||
o.realm = realm;
|
||||
realmObjectList.add(o);
|
||||
}
|
||||
}
|
||||
// Log.e("jingo", " " + Realm.getDefaultInstance().hashCode() + " " + Realm.getInstance(MapParamUtils.getTaskConfig()).hashCode());
|
||||
|
||||
// Realm realm = Realm.getInstance(MapParamUtils.getTaskConfig());
|
||||
RealmQuery<RenderEntity> realmQuery = realm.where(RenderEntity.class);
|
||||
int m = Constant.DATA_ZOOM - tile.zoomLevel;
|
||||
int xStart = tile.tileX;
|
||||
int xEnd = tile.tileX + 1;
|
||||
@ -56,19 +114,27 @@ public class OMDBTileDataSource implements ITileDataSource {
|
||||
|
||||
final int currentTileX = xStart;
|
||||
if (isUpdate) {
|
||||
Realm.getInstance(MapParamUtils.getTaskConfig()).refresh();
|
||||
realm.refresh();
|
||||
isUpdate = false;
|
||||
}
|
||||
|
||||
String sql =" tileX>=" + xStart + " and tileX<=" + xEnd + " and tileY>=" + yStart + " and tileY<=" + yEnd + "";
|
||||
|
||||
String sql = " ((tileXMin <= " + xStart + " and tileXMax >= " + xStart + ") or (tileXMin <=" + xEnd + " and tileXMax >=" + xStart + ")) and ((tileYMin <= " + yStart + " and tileYMax >= " + yStart + ") or (tileYMin <=" + yEnd + " and tileYMin >=" + yStart + "))";
|
||||
if (MapParamUtils.getDataLayerEnum() != null) {
|
||||
sql += " and enable" + MapParamUtils.getDataLayerEnum().getSql();
|
||||
} else {
|
||||
sql += " and enable>=0";
|
||||
}
|
||||
|
||||
RealmQuery<RenderEntity> realmQuery = Realm.getInstance(MapParamUtils.getTaskConfig()).where(RenderEntity.class).rawPredicate(sql);
|
||||
realmQuery.rawPredicate(sql);
|
||||
if (MapParamUtils.getDataLayerEnum() != null) {
|
||||
MapParamUtils.getDataLayerEnum().getSql();
|
||||
}
|
||||
|
||||
// realmQuery.greaterThanOrEqualTo("tileXMin", xStart);
|
||||
// realmQuery.lessThanOrEqualTo("tileXMax", xEnd);
|
||||
// realmQuery.greaterThanOrEqualTo("tileYMin", yStart);
|
||||
// realmQuery.lessThanOrEqualTo("tileYMax", yEnd);
|
||||
// realmQuery.like("geometry","116.31509664888955 39.83318797612014 0");
|
||||
// 筛选不显示的数据
|
||||
if (Constant.HAD_LAYER_INVISIABLE_ARRAY != null && Constant.HAD_LAYER_INVISIABLE_ARRAY.length > 0) {
|
||||
realmQuery.beginGroup();
|
||||
@ -77,13 +143,47 @@ public class OMDBTileDataSource implements ITileDataSource {
|
||||
}
|
||||
realmQuery.endGroup();
|
||||
}
|
||||
long time = System.currentTimeMillis();
|
||||
List<RenderEntity> listResult = realmQuery/*.distinct("id")*/.findAll();
|
||||
long newTime = System.currentTimeMillis() - time;
|
||||
|
||||
Log.e("jingo", "当前OMDBTileDataSource " + Thread.currentThread().hashCode() + " 当前realm " + realm.hashCode() + " 查询耗时" + newTime );
|
||||
// 数据记录的tile号是以正外接tile号列表,此处过滤并未与当前tile相交的数据
|
||||
if (!listResult.isEmpty()) {
|
||||
Polygon tilePolygon = GeometryTools.getTilePolygon(tile);
|
||||
System.out.println("第一条数据的最小x值:" + listResult.get(0).getTileX().stream().min(Integer::compare).get());
|
||||
System.out.println("当前tile的:" + listResult.get(0).getTileX().stream().min(Integer::compare).get());
|
||||
listResult = listResult.stream().filter((RenderEntity renderEntity) -> renderEntity.getWkt().intersects(tilePolygon))
|
||||
// System.out.println("第一条数据的最小x值:" + listResult.get(0).getTileX().stream().min(Integer::compare).get());
|
||||
// System.out.println("当前tile的:" + listResult.get(0).getTileX().stream().min(Integer::compare).get());
|
||||
// synchronized (dataObjectList) {
|
||||
// int index = -1;
|
||||
// for (int i = 0; i < dataObjectList.size(); i++) {
|
||||
// DataObject dataObject = dataObjectList.get(i);
|
||||
// if (dataObject.threadCode == newDataObject.threadCode) {
|
||||
// index = i;
|
||||
// } else if (dataObject.zoom == tile.zoomLevel && dataObject.lonLat.equals(newDataObject.lonLat)) {
|
||||
// listResult = listResult.stream().filter((RenderEntity renderEntity) -> {
|
||||
// for (String id : dataObject.listIds) {
|
||||
// if (id.equals(renderEntity.getId())) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// return renderEntity.getWkt().intersects(tilePolygon);
|
||||
// })
|
||||
// /*过滤数据,只有最小x(屏幕的最小x或数据的最小x会被渲染,跨Tile的其他数据不再重复渲染)*/
|
||||
//// .filter((RenderEntity renderEntity) -> MercatorProjection.longitudeToTileX(viewport.fromScreenPoint(0,0).getLongitude(), (byte) Constant.DATA_ZOOM) == currentTileX || renderEntity.getTileX().stream().min(Integer::compare).get() == currentTileX)
|
||||
// .collect(Collectors.toList());
|
||||
// }
|
||||
// }
|
||||
// if (index > -1) {
|
||||
// dataObjectList.remove(index);
|
||||
// }
|
||||
// for (RenderEntity renderEntity : listResult) {
|
||||
// newDataObject.listIds.add(renderEntity.getId());
|
||||
// }
|
||||
// dataObjectList.add(newDataObject);
|
||||
// }
|
||||
listResult = listResult.stream().filter((RenderEntity renderEntity) ->
|
||||
renderEntity.getWkt().intersects(tilePolygon)
|
||||
)
|
||||
/*过滤数据,只有最小x(屏幕的最小x或数据的最小x会被渲染,跨Tile的其他数据不再重复渲染)*/
|
||||
// .filter((RenderEntity renderEntity) -> MercatorProjection.longitudeToTileX(viewport.fromScreenPoint(0,0).getLongitude(), (byte) Constant.DATA_ZOOM) == currentTileX || renderEntity.getTileX().stream().min(Integer::compare).get() == currentTileX)
|
||||
.collect(Collectors.toList());
|
||||
@ -92,10 +192,12 @@ public class OMDBTileDataSource implements ITileDataSource {
|
||||
} else {
|
||||
mapDataSink.completed(QueryResult.SUCCESS);
|
||||
}
|
||||
Realm.getInstance(MapParamUtils.getTaskConfig()).close();
|
||||
|
||||
// realm.close();
|
||||
} else {
|
||||
mapDataSink.completed(QueryResult.SUCCESS);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
x
Reference in New Issue
Block a user