1. 增加OMDB数据图层 2. 修改Realm数据库文件位置

This commit is contained in:
xiaoyan 2023-04-24 10:52:14 +08:00
parent 51bd47842a
commit 60622a3197
11 changed files with 370 additions and 41 deletions

View File

@ -20,20 +20,6 @@ class OMQSApplication : Application() {
Util.getInstance().init(applicationContext) Util.getInstance().init(applicationContext)
NetUtils.getInstance().init(this) NetUtils.getInstance().init(this)
TakePhotoManager.getInstance().init(this, 1) TakePhotoManager.getInstance().init(this, 1)
FileManager.initRootDir(this)
Realm.init(this)
val password = "encryp".encodeToByteArray().copyInto(ByteArray(64))
// 656e6372797000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Log.d("OMQSApplication", "密码是: ${byteArrayToHexString(password)}")
// 1110000011000010111001101110011011101110110111101110010011001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
val config = RealmConfiguration.Builder()
.directory(File(Constant.DATA_PATH))
.name("OMQS.realm")
.encryptionKey(password)
// .modules(Realm.getDefaultModule(), MyRealmModule())
.schemaVersion(1)
.build()
Realm.setDefaultConfiguration(config)
} }
private fun getKey(inputString: String): String { private fun getKey(inputString: String): String {
@ -42,7 +28,4 @@ class OMQSApplication : Application() {
return hashBytes.joinToString("") { "%02x".format(it) }; return hashBytes.joinToString("") { "%02x".format(it) };
} }
fun byteArrayToHexString(byteArray: ByteArray): String {
return byteArray.joinToString("") { "%02x".format(it) }
}
} }

View File

@ -10,7 +10,7 @@ import com.hjq.permissions.XXPermissions
/** /**
* 权限申请Activity * 权限申请Activity
*/ */
open class PermissionsActivity : BaseActivity() { open abstract class PermissionsActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val permissionList = mutableListOf<String>() val permissionList = mutableListOf<String>()
@ -29,11 +29,11 @@ open class PermissionsActivity : BaseActivity() {
//定位权限 //定位权限
permissionList.add(Permission.ACCESS_FINE_LOCATION) permissionList.add(Permission.ACCESS_FINE_LOCATION)
permissionList.add(Permission.ACCESS_COARSE_LOCATION) permissionList.add(Permission.ACCESS_COARSE_LOCATION)
//android10 // //android10
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) { // if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
permissionList.add(Permission.ACCESS_BACKGROUND_LOCATION) // permissionList.add(Permission.ACCESS_BACKGROUND_LOCATION)
} // }
/* XXPermissions.with(this) XXPermissions.with(this)
// 申请单个权限 // 申请单个权限
.permission(permissionList) .permission(permissionList)
// 设置权限请求拦截器(局部设置) // 设置权限请求拦截器(局部设置)
@ -50,10 +50,10 @@ open class PermissionsActivity : BaseActivity() {
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
) )
.show() .show()
onPermissionsGranted() onPermissionsDenied()
return return
} else { } else {
onPermissionsDenied() onPermissionsGranted()
} }
// 在SD卡创建项目目录 // 在SD卡创建项目目录
} }
@ -73,20 +73,16 @@ open class PermissionsActivity : BaseActivity() {
onPermissionsDenied() onPermissionsDenied()
} }
} }
})*/ })
} }
/** /**
* 权限全部同意 * 权限全部同意
*/ */
open fun onPermissionsGranted() { open abstract fun onPermissionsGranted()
}
/** /**
* 权限 * 权限
*/ */
open fun onPermissionsDenied() { open abstract fun onPermissionsDenied()
}
} }

View File

@ -7,14 +7,18 @@ import android.widget.Toast
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.navinfo.omqs.Constant
import com.navinfo.omqs.bean.LoginUserBean import com.navinfo.omqs.bean.LoginUserBean
import com.navinfo.omqs.db.RoomAppDatabase import com.navinfo.omqs.db.RoomAppDatabase
import com.navinfo.omqs.http.NetResult import com.navinfo.omqs.http.NetResult
import com.navinfo.omqs.http.NetworkService import com.navinfo.omqs.http.NetworkService
import com.navinfo.omqs.tools.FileManager import com.navinfo.omqs.tools.FileManager
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import io.realm.Realm
import io.realm.RealmConfiguration
import kotlinx.coroutines.* import kotlinx.coroutines.*
import okio.IOException import okio.IOException
import java.io.File
import javax.inject.Inject import javax.inject.Inject
enum class LoginStatus { enum class LoginStatus {
@ -110,8 +114,7 @@ class LoginViewModel @Inject constructor(
//文件夹初始化 //文件夹初始化
try { try {
loginStatus.postValue(LoginStatus.LOGIN_STATUS_FOLDER_INIT) loginStatus.postValue(LoginStatus.LOGIN_STATUS_FOLDER_INIT)
createUserFolder(context) createUserFolder(context, "1")
// 初始化Realm
} catch (e: IOException) { } catch (e: IOException) {
loginStatus.postValue(LoginStatus.LOGIN_STATUS_FOLDER_FAILURE) loginStatus.postValue(LoginStatus.LOGIN_STATUS_FOLDER_FAILURE)
} }
@ -151,8 +154,21 @@ class LoginViewModel @Inject constructor(
* 创建用户目录 * 创建用户目录
*/ */
@Throws(IOException::class) @Throws(IOException::class)
private fun createUserFolder(context: Context) { private fun createUserFolder(context: Context, userId: String) {
// 在SD卡创建用户目录解压资源等 // 在SD卡创建用户目录解压资源等
// 初始化Realm
Realm.init(context.applicationContext)
val password = "encryp".encodeToByteArray().copyInto(ByteArray(64))
// 656e6372797000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Log.d("OMQSApplication", "密码是: ${byteArrayToHexString(password)}")
val config = RealmConfiguration.Builder()
.directory(File("${Constant.DATA_PATH}/${userId}"))
.name("OMQS.realm")
.encryptionKey(password)
// .modules(Realm.getDefaultModule(), MyRealmModule())
.schemaVersion(1)
.build()
Realm.setDefaultConfiguration(config)
} }
/** /**
@ -169,4 +185,8 @@ class LoginViewModel @Inject constructor(
super.onCleared() super.onCleared()
cancelLogin() cancelLogin()
} }
private fun byteArrayToHexString(byteArray: ByteArray): String {
return byteArray.joinToString("") { "%02x".format(it) }
}
} }

View File

@ -17,6 +17,7 @@ import com.github.k1rakishou.fsaf.callback.FSAFActivityCallbacks
import com.github.k1rakishou.fsaf.callback.FileChooserCallback import com.github.k1rakishou.fsaf.callback.FileChooserCallback
import com.navinfo.collect.library.data.RealmUtils import com.navinfo.collect.library.data.RealmUtils
import com.navinfo.collect.library.data.entity.OMDBEntity import com.navinfo.collect.library.data.entity.OMDBEntity
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.omqs.R import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.FragmentPersonalCenterBinding import com.navinfo.omqs.databinding.FragmentPersonalCenterBinding
import com.navinfo.omqs.db.ImportOMDBHelper import com.navinfo.omqs.db.ImportOMDBHelper
@ -30,6 +31,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.FlowCollector import kotlinx.coroutines.flow.FlowCollector
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.oscim.core.GeoPoint
import java.io.File import java.io.File
import java.util.UUID import java.util.UUID
import javax.inject.Inject import javax.inject.Inject
@ -46,6 +48,8 @@ class PersonalCenterFragment : Fragment(), FSAFActivityCallbacks {
private val viewModel by lazy { viewModels<PersonalCenterViewModel>().value } private val viewModel by lazy { viewModels<PersonalCenterViewModel>().value }
@Inject @Inject
lateinit var importOMDBHiltFactory: ImportOMDBHiltFactory lateinit var importOMDBHiltFactory: ImportOMDBHiltFactory
@Inject
lateinit var niMapController: NIMapController
override fun onCreateView( override fun onCreateView(
@ -107,6 +111,8 @@ class PersonalCenterFragment : Fragment(), FSAFActivityCallbacks {
} }
R.id.personal_center_menu_test -> { R.id.personal_center_menu_test -> {
viewModel.readRealmData() viewModel.readRealmData()
// 定位到指定位置
niMapController.mMapView.vtmMap.animator().animateTo(GeoPoint(28.608398, 115.67901))
} }
} }
true true

View File

@ -10,6 +10,7 @@ import com.blankj.utilcode.util.UriUtils
import com.blankj.utilcode.util.ZipUtils import com.blankj.utilcode.util.ZipUtils
import com.google.gson.Gson import com.google.gson.Gson
import com.navinfo.collect.library.data.entity.* import com.navinfo.collect.library.data.entity.*
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.utils.GeometryTools import com.navinfo.collect.library.utils.GeometryTools
import com.navinfo.omqs.bean.ScProblemTypeBean import com.navinfo.omqs.bean.ScProblemTypeBean
import com.navinfo.omqs.bean.ScRootCauseAnalysisBean import com.navinfo.omqs.bean.ScRootCauseAnalysisBean

View File

@ -23,7 +23,10 @@ open class RenderEntity(): RealmObject() {
lateinit var table: String //要素表名 lateinit var table: String //要素表名
var code: Int = 0 // 要素编码 var code: Int = 0 // 要素编码
var geometry: String = "" var geometry: String = ""
get() = field get() {
wkt = GeometryTools.createGeometry(field)
return field
}
set(value) { set(value) {
field = value field = value
// 根据geometry自动计算当前要素的x-tile和y-tile // 根据geometry自动计算当前要素的x-tile和y-tile
@ -39,8 +42,8 @@ open class RenderEntity(): RealmObject() {
@Ignore @Ignore
var wkt: Geometry? = null var wkt: Geometry? = null
var properties: RealmDictionary<String?> = RealmDictionary() var properties: RealmDictionary<String?> = RealmDictionary()
val tileX: RealmSet<Int> = RealmSet() // x方向的tile编码 var tileX: RealmSet<Int> = RealmSet() // x方向的tile编码
val tileY: RealmSet<Int> = RealmSet() // y方向的tile编码 var tileY: RealmSet<Int> = RealmSet() // y方向的tile编码
constructor(name: String, properties: RealmDictionary<String?>): this() { constructor(name: String, properties: RealmDictionary<String?>): this() {
this.name = name this.name = name

View File

@ -15,6 +15,7 @@ import com.navinfo.collect.library.map.cluster.ClusterMarkerRenderer
import com.navinfo.collect.library.map.layers.MyItemizedLayer import com.navinfo.collect.library.map.layers.MyItemizedLayer
import com.navinfo.collect.library.map.source.MapLifeNiLocationTileSource import com.navinfo.collect.library.map.source.MapLifeNiLocationTileSource
import com.navinfo.collect.library.map.source.NavinfoMultiMapFileTileSource import com.navinfo.collect.library.map.source.NavinfoMultiMapFileTileSource
import com.navinfo.collect.library.map.source.OMDBTileSource
import com.navinfo.collect.library.system.Constant import com.navinfo.collect.library.system.Constant
import com.navinfo.collect.library.utils.GeometryTools import com.navinfo.collect.library.utils.GeometryTools
import io.realm.Realm import io.realm.Realm
@ -30,12 +31,17 @@ import org.oscim.backend.CanvasAdapter
import org.oscim.backend.canvas.Bitmap import org.oscim.backend.canvas.Bitmap
import org.oscim.backend.canvas.Paint import org.oscim.backend.canvas.Paint
import org.oscim.core.GeoPoint import org.oscim.core.GeoPoint
import org.oscim.event.EventListener
import org.oscim.layers.GroupLayer import org.oscim.layers.GroupLayer
import org.oscim.layers.marker.* import org.oscim.layers.marker.MarkerInterface
import org.oscim.layers.marker.MarkerItem
import org.oscim.layers.marker.MarkerRendererFactory
import org.oscim.layers.marker.MarkerSymbol
import org.oscim.layers.tile.buildings.BuildingLayer import org.oscim.layers.tile.buildings.BuildingLayer
import org.oscim.layers.tile.vector.VectorTileLayer import org.oscim.layers.tile.vector.VectorTileLayer
import org.oscim.layers.tile.vector.labeling.LabelLayer import org.oscim.layers.tile.vector.labeling.LabelLayer
import org.oscim.layers.tile.vector.labeling.LabelTileLoaderHook import org.oscim.layers.tile.vector.labeling.LabelTileLoaderHook
import org.oscim.map.Map
import org.oscim.tiling.source.OkHttpEngine.OkHttpFactory import org.oscim.tiling.source.OkHttpEngine.OkHttpFactory
import org.oscim.tiling.source.mapfile.MapFileTileSource import org.oscim.tiling.source.mapfile.MapFileTileSource
import java.io.File import java.io.File
@ -79,7 +85,11 @@ open class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView,tr
* 增加作业渲染 * 增加作业渲染
*/ */
private lateinit var labelNiLocationLayer: LabelLayer private lateinit var labelNiLocationLayer: LabelLayer
/**
* 显示待测评OMDB数据的图层
* */
private lateinit var omdbVectorTileLayer: VectorTileLayer
private lateinit var omdbLabelLayer: LabelLayer
/** /**
* 文字大小 * 文字大小
*/ */
@ -87,6 +97,14 @@ open class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView,tr
init { init {
initMap() initMap()
mMapView.vtmMap.events.bind(Map.UpdateListener { e, mapPosition ->
val isOmdbZoom = mapPosition.zoomLevel>=Constant.OMDB_MIN_ZOOM
baseGroupLayer?.layers?.forEach {
it.isEnabled = !isOmdbZoom
}
omdbVectorTileLayer.isEnabled = isOmdbZoom
omdbLabelLayer.isEnabled = isOmdbZoom
})
} }
/** /**
@ -96,6 +114,8 @@ open class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView,tr
loadBaseMap() loadBaseMap()
initOMDBVectorTileLayer()
mapLifeNiLocationTileSource = MapLifeNiLocationTileSource(mContext, mTracePath) mapLifeNiLocationTileSource = MapLifeNiLocationTileSource(mContext, mTracePath)
vectorNiLocationTileLayer = VectorTileLayer(mMapView.vtmMap, mapLifeNiLocationTileSource) vectorNiLocationTileLayer = VectorTileLayer(mMapView.vtmMap, mapLifeNiLocationTileSource)
@ -119,9 +139,19 @@ open class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView,tr
mMapView.vtmMap.updateMap() mMapView.vtmMap.updateMap()
} }
private fun initOMDBVectorTileLayer() {
val omdbTileSource: OMDBTileSource = OMDBTileSource()
omdbVectorTileLayer = VectorTileLayer(mMapView.vtmMap, omdbTileSource)
omdbLabelLayer = LabelLayer(mMapView.vtmMap, omdbVectorTileLayer, LabelTileLoaderHook(), Constant.OMDB_MIN_ZOOM)
if(omdbVectorTileLayer!=null){
addLayer(omdbVectorTileLayer,NIMapView.LAYER_GROUPS.VECTOR_TILE)
}
if(omdbLabelLayer!=null){
addLayer(omdbLabelLayer, NIMapView.LAYER_GROUPS.VECTOR_TILE)
}
}
/** /**
* 切换基础底图样式 * 切换基础底图样式

View File

@ -0,0 +1,190 @@
package com.navinfo.collect.library.map.source;
import static org.oscim.core.MercatorProjection.latitudeToY;
import static org.oscim.core.MercatorProjection.longitudeToX;
import android.os.Build;
import android.util.Log;
import androidx.annotation.RequiresApi;
import com.navinfo.collect.library.data.entity.GeometryFeatureEntity;
import com.navinfo.collect.library.data.entity.RenderEntity;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.MultiLineString;
import org.locationtech.jts.geom.MultiPoint;
import org.locationtech.jts.geom.MultiPolygon;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.Polygon;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKBReader;
import org.oscim.core.MapElement;
import org.oscim.core.Tag;
import org.oscim.core.Tile;
import org.oscim.tiling.ITileDataSink;
import org.oscim.tiling.source.mvt.TileDecoder;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
public class OMDBDataDecoder extends TileDecoder {
private final String mLocale;
private static final float REF_TILE_SIZE = 4096.0f;
private final GeometryFactory mGeomFactory;
private final MapElement mMapElement;
private ITileDataSink mTileDataSink;
private double mTileY, mTileX, mTileScale;
public OMDBDataDecoder() {
super();
mLocale = "";
mGeomFactory = new GeometryFactory();
mMapElement = new MapElement();
mMapElement.layer = 5;
}
@Override
public boolean decode(Tile tile, ITileDataSink sink, InputStream is) throws IOException {
mTileDataSink = sink;
mTileScale = 1 << tile.zoomLevel;
mTileX = tile.tileX / mTileScale;
mTileY = tile.tileY / mTileScale;
mTileScale *= Tile.SIZE;
return true;
}
@RequiresApi(api = Build.VERSION_CODES.N)
public boolean decode(Tile tile, ITileDataSink sink, List<RenderEntity> listResult) {
mTileDataSink = sink;
mTileScale = 1 << tile.zoomLevel;
mTileX = tile.tileX / mTileScale;
mTileY = tile.tileY / mTileScale;
mTileScale *= Tile.SIZE;
listResult.stream().iterator().forEachRemaining(new Consumer<RenderEntity>() {
@Override
public void accept(RenderEntity renderEntity) {
Log.d("RealmDBTileDataSource", renderEntity.getGeometry());
Map<String, Object> properties= new HashMap<>(renderEntity.getProperties().size());
properties.putAll(renderEntity.getProperties());
parseGeometry(renderEntity.getTable(), renderEntity.getWkt(), properties);
}
});
return true;
}
public void parseGeometry(String layerName, Geometry geometry, Map<String, Object> tags) {
mMapElement.clear();
mMapElement.tags.clear();
parseTags(tags, layerName);
if (mMapElement.tags.size() == 0) {
return;
}
boolean err = false;
if (geometry instanceof Point) {
mMapElement.startPoints();
processCoordinateArray(geometry.getCoordinates(), false);
} else if (geometry instanceof MultiPoint) {
MultiPoint multiPoint = (MultiPoint) geometry;
for (int i = 0; i < multiPoint.getNumGeometries(); i++) {
mMapElement.startPoints();
processCoordinateArray(multiPoint.getGeometryN(i).getCoordinates(), false);
}
} else if (geometry instanceof LineString) {
processLineString((LineString) geometry);
} else if (geometry instanceof MultiLineString) {
MultiLineString multiLineString = (MultiLineString) geometry;
for (int i = 0; i < multiLineString.getNumGeometries(); i++) {
processLineString((LineString) multiLineString.getGeometryN(i));
}
} else if (geometry instanceof Polygon) {
Polygon polygon = (Polygon) geometry;
processPolygon(polygon);
} else if (geometry instanceof MultiPolygon) {
MultiPolygon multiPolygon = (MultiPolygon) geometry;
for (int i = 0; i < multiPolygon.getNumGeometries(); i++) {
processPolygon((Polygon) multiPolygon.getGeometryN(i));
}
} else {
err = true;
}
if (!err) {
mTileDataSink.process(mMapElement);
}
}
private void processLineString(LineString lineString) {
mMapElement.startLine();
processCoordinateArray(lineString.getCoordinates(), false);
}
private void processPolygon(Polygon polygon) {
mMapElement.startPolygon();
processCoordinateArray(polygon.getExteriorRing().getCoordinates(), true);
for (int i = 0; i < polygon.getNumInteriorRing(); i++) {
mMapElement.startHole();
processCoordinateArray(polygon.getInteriorRingN(i).getCoordinates(), true);
}
}
private void processCoordinateArray(Coordinate[] coordinates, boolean removeLast) {
int length = removeLast ? coordinates.length - 1 : coordinates.length;
for (int i = 0; i < length; i++) {
mMapElement.addPoint((float) ((longitudeToX(coordinates[i].x) - mTileX) * mTileScale),
(float) ((latitudeToY(coordinates[i].y) - mTileY) * mTileScale));
}
// int length = removeLast ? coordinates.length - 1 : coordinates.length;
// // 初始化3D数据类型
// float[] point3D = new float[coordinates.length*3];
// for (int i = 0; i < length; i++) {
// point3D[i*3] = (float) coordinates[i].x;
// point3D[(i*3)+1] = (float) coordinates[i].y;
// point3D[(i*3)+2] = (float) coordinates[i].z;
// }
// mMapElement.points = point3D;
// mMapElement.pointNextPos = mMapElement.points.length;
// mMapElement.type = GeometryBuffer.GeometryType.TRIS;
}
private void parseTags(Map<String, Object> map, String layerName) {
mMapElement.tags.add(new Tag("layer", layerName));
boolean hasName = false;
String fallbackName = null;
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
String val = (value instanceof String) ? (String) value : String.valueOf(value);
if (key.startsWith(Tag.KEY_NAME)) {
int len = key.length();
if (len == 4) {
fallbackName = val;
continue;
}
if (len < 7)
continue;
if (mLocale.equals(key.substring(5))) {
hasName = true;
mMapElement.tags.add(new Tag(Tag.KEY_NAME, val, false));
}
} else {
mMapElement.tags.add(new Tag(key, val));
}
}
if (!hasName && fallbackName != null)
mMapElement.tags.add(new Tag(Tag.KEY_NAME, fallbackName, false));
}
}

View File

@ -0,0 +1,74 @@
package com.navinfo.collect.library.map.source;
import android.os.Build;
import android.util.Log;
import androidx.annotation.RequiresApi;
import com.navinfo.collect.library.data.RealmUtils;
import com.navinfo.collect.library.data.entity.GeometryFeatureEntity;
import com.navinfo.collect.library.data.entity.RenderEntity;
import com.navinfo.collect.library.system.Constant;
import org.oscim.layers.tile.MapTile;
import org.oscim.tiling.ITileDataSink;
import org.oscim.tiling.ITileDataSource;
import org.oscim.tiling.QueryResult;
import java.util.List;
import io.realm.Realm;
import io.realm.RealmQuery;
public class OMDBTileDataSource implements ITileDataSource {
private final ThreadLocal<OMDBDataDecoder> mThreadLocalDecoders = new ThreadLocal<OMDBDataDecoder>() {
@Override
protected OMDBDataDecoder initialValue() {
return new OMDBDataDecoder();
}
};
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void query(MapTile tile, ITileDataSink mapDataSink) {
// 获取tile对应的坐标范围
if (tile.zoomLevel>=Constant.OMDB_MIN_ZOOM&&tile.zoomLevel<=Constant.OVER_ZOOM) {
int m = Constant.OVER_ZOOM-tile.zoomLevel;
int xStart = (int)tile.tileX<<m;
int xEnd = (int)((tile.tileX+1)<<m);
int yStart = (int)tile.tileY<<m;
int yEnd = (int)((tile.tileY+1)<<m);
RealmQuery<RenderEntity> realmQuery = Realm.getDefaultInstance().where(RenderEntity.class)
.rawPredicate("tileX>="+xStart+" and tileX<="+xEnd+" and tileY>="+yStart+" and tileY<="+yEnd);
// // 筛选不显示的数据
// if (Constant.HAD_LAYER_INVISIABLE_ARRAY!=null&&Constant.HAD_LAYER_INVISIABLE_ARRAY.length>0) {
// realmQuery.beginGroup();
// for (String type: Constant.HAD_LAYER_INVISIABLE_ARRAY) {
// realmQuery.notEqualTo("name", type);
// }
// realmQuery.endGroup();
// }
List<RenderEntity> listResult = realmQuery/*.distinct("id")*/.findAll();
if (!listResult.isEmpty()) {
mThreadLocalDecoders.get().decode(tile, mapDataSink, listResult);
}
mapDataSink.completed(QueryResult.SUCCESS);
Log.d("RealmDBTileDataSource", "tile:"+tile.getBoundingBox().toString());
} else {
mapDataSink.completed(QueryResult.SUCCESS);
}
}
@Override
public void dispose() {
}
@Override
public void cancel() {
if (Realm.getDefaultInstance().isInTransaction()) {
Realm.getDefaultInstance().cancelTransaction();
}
}
}

View File

@ -0,0 +1,25 @@
package com.navinfo.collect.library.map.source;
import com.navinfo.collect.library.system.Constant;
import org.oscim.tiling.ITileDataSource;
import org.oscim.tiling.OverzoomTileDataSource;
import org.oscim.tiling.TileSource;
public class OMDBTileSource extends TileSource {
@Override
public ITileDataSource getDataSource() {
return new OverzoomTileDataSource(new OMDBTileDataSource(), Constant.OVER_ZOOM);
}
@Override
public OpenResult open() {
return OpenResult.SUCCESS;
}
@Override
public void close() {
}
}

View File

@ -31,5 +31,6 @@ public class Constant {
public static String[] HAD_LAYER_INVISIABLE_ARRAY; public static String[] HAD_LAYER_INVISIABLE_ARRAY;
public static final int OVER_ZOOM = 21; public static final int OVER_ZOOM = 21;
public static final int MAX_ZOOM = 25; public static final int MAX_ZOOM = 25;
public static final int OMDB_MIN_ZOOM = 18;
} }