From 129c48f11d8db510635bca584cc6c60710fc6be9 Mon Sep 17 00:00:00 2001 From: squallzhjch Date: Thu, 19 Oct 2023 14:47:15 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/navinfo/omqs/db/ImportOMDBHelper.kt | 2 +- .../omqs/ui/activity/login/LoginViewModel.kt | 2 +- .../omqs/ui/activity/map/MainViewModel.kt | 175 ++++++++++-------- .../ui/fragment/tasklist/TaskViewModel.kt | 3 +- .../com/navinfo/omqs/util/NaviEngineNew.kt | 96 ++++++++++ .../library/data/entity/ReferenceEntity.kt | 11 +- .../library/data/entity/RenderEntity.kt | 12 ++ .../map/handler/LocationLayerHandler.kt | 1 - .../map/source/OMDBReferenceDataSource.java | 28 +-- .../map/source/OMDBTileDataSource.java | 130 +++++++++++-- 10 files changed, 352 insertions(+), 108 deletions(-) create mode 100644 app/src/main/java/com/navinfo/omqs/util/NaviEngineNew.kt 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 24cc8c0f..4129f1de 100644 --- a/app/src/main/java/com/navinfo/omqs/db/ImportOMDBHelper.kt +++ b/app/src/main/java/com/navinfo/omqs/db/ImportOMDBHelper.kt @@ -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") diff --git a/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginViewModel.kt index 037b2e97..1a8dfacc 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginViewModel.kt @@ -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) 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 8f79c704..3b51016a 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 @@ -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 = flow { -// -// while (true) { -// emit(mapController.mMapView.vtmMap.mapPosition.geoPoint) -// delay(1000) -// } -// } + fun naviTestFlow(): Flow = 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() - GeometryToolsKt.getTileXByGeometry(geometry.toString(), tileX) - val tileY = RealmSet() - 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() +// GeometryToolsKt.getTileXByGeometry(geometry.toString(), tileX) +// val tileY = RealmSet() +// 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) } 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 358f63c7..1ca96f20 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 @@ -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() diff --git a/app/src/main/java/com/navinfo/omqs/util/NaviEngineNew.kt b/app/src/main/java/com/navinfo/omqs/util/NaviEngineNew.kt new file mode 100644 index 00000000..73e20fd9 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/util/NaviEngineNew.kt @@ -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() + + + 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) + } + } + } + + } + + } + + } +} \ No newline at end of file diff --git a/collect-library/src/main/java/com/navinfo/collect/library/data/entity/ReferenceEntity.kt b/collect-library/src/main/java/com/navinfo/collect/library/data/entity/ReferenceEntity.kt index 07d2917b..1e509da0 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/data/entity/ReferenceEntity.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/data/entity/ReferenceEntity.kt @@ -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) diff --git a/collect-library/src/main/java/com/navinfo/collect/library/data/entity/RenderEntity.kt b/collect-library/src/main/java/com/navinfo/collect/library/data/entity/RenderEntity.kt index deeade38..0a33336e 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/data/entity/RenderEntity.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/data/entity/RenderEntity.kt @@ -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 = RealmDictionary() var tileX: RealmSet = RealmSet() // x方向的tile编码 var tileY: RealmSet = 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 //显示最大级别 diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt index a44d100f..cddaf7d9 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt @@ -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) } } diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDataSource.java b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDataSource.java index 61a0334b..44a128e9 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDataSource.java +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDataSource.java @@ -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,12 +45,14 @@ 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 realmQuery = realm.where(ReferenceEntity.class); int m = Constant.DATA_ZOOM - tile.zoomLevel; int xStart = tile.tileX; int xEnd = tile.tileX + 1; int yStart = tile.tileY; int yEnd = tile.tileY + 1; - if (m>0) { + if (m > 0) { xStart = (int) (xStart << m); xEnd = (int) (xEnd << m); yStart = (int) (yStart << m); @@ -56,21 +60,22 @@ public class OMDBReferenceDataSource implements ITileDataSource { } final int currentTileX = xStart; - if(isUpdate){ - Realm.getInstance(MapParamUtils.getTaskConfig()).refresh(); + if (isUpdate) { + 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){ +// String sql = " tileX>=" + xStart + " and tileX<=" + xEnd + " and tileY>=" + yStart + " and tileY<=" + yEnd + ""; + + if (MapParamUtils.getDataLayerEnum() != null) { sql += " and enable" + MapParamUtils.getDataLayerEnum().getSql(); - }else{ + } else { sql += " and enable>=0"; } - RealmQuery 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 @@ -109,8 +115,8 @@ public class OMDBReferenceDataSource implements ITileDataSource { } } - public void update(){ + public void update() { isUpdate = true; - Log.e("qj",Thread.currentThread().getName()); + Log.e("qj", Thread.currentThread().getName()); } } diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileDataSource.java b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileDataSource.java index c6e5be22..41022674 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileDataSource.java +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileDataSource.java @@ -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 listIds = new ArrayList<>(); +// } + private boolean isUpdate; private Viewport viewport; + + private List realmObjectList = new ArrayList<>(); + +// private List dataObjectList = new ArrayList<>(); + private final ThreadLocal mThreadLocalDecoders = new ThreadLocal() { @Override protected OMDBDataDecoder initialValue() { @@ -42,12 +66,46 @@ 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 realmQuery = realm.where(RenderEntity.class); int m = Constant.DATA_ZOOM - tile.zoomLevel; int xStart = tile.tileX; int xEnd = tile.tileX + 1; int yStart = tile.tileY; int yEnd = tile.tileY + 1; - if (m>0) { + if (m > 0) { xStart = (int) (xStart << m); xEnd = (int) (xEnd << m); yStart = (int) (yStart << m); @@ -55,20 +113,28 @@ public class OMDBTileDataSource implements ITileDataSource { } final int currentTileX = xStart; - if(isUpdate){ - Realm.getInstance(MapParamUtils.getTaskConfig()).refresh(); + if (isUpdate) { + realm.refresh(); isUpdate = false; } - String sql =" tileX>=" + xStart + " and tileX<=" + xEnd + " and tileY>=" + yStart + " and tileY<=" + yEnd + ""; - - if(MapParamUtils.getDataLayerEnum()!=null){ + 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{ + } else { sql += " and enable>=0"; } - RealmQuery 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 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 @@ -110,8 +212,8 @@ public class OMDBTileDataSource implements ITileDataSource { } } - public void update(){ + public void update() { isUpdate = true; - Log.e("qj",Thread.currentThread().getName()); + Log.e("qj", Thread.currentThread().getName()); } }