增加轨迹存储渲染业务
This commit is contained in:
@@ -1530,4 +1530,23 @@
|
||||
<symbol src="assets:symbols/traffic_signal.svg" />
|
||||
</m>
|
||||
</m>
|
||||
|
||||
<m k="nav_style">
|
||||
<m v="symbol_object_line">
|
||||
<m k="rule" zoom-min="15" zoom-max="22">
|
||||
<!-- 蓝色黑色间隔线 -->
|
||||
<m v="blue_link">
|
||||
<line stroke="#00000000" stipple-stroke="#00000000" dasharray="20,20" fix="true" width="0.1" />
|
||||
</m>
|
||||
<!-- 黄色线 -->
|
||||
<m v="yellow_link">
|
||||
<line stroke="#f4ea2a" width="0.1" stipple-width="0.1"/>
|
||||
</m>
|
||||
</m>
|
||||
<line stroke="#33aaaa" width="0.3" stipple-width="0.5"/>
|
||||
</m>
|
||||
<m v="symbol_track_point" zoom-min="10" zoom-max="25">
|
||||
<symbol src="assets:symbols/dot_blue.svg" />
|
||||
</m>
|
||||
</m>
|
||||
</rendertheme>
|
||||
@@ -10,7 +10,6 @@ import androidx.sqlite.db.SupportSQLiteDatabase;
|
||||
import com.navinfo.collect.library.data.entity.CheckManager;
|
||||
import com.navinfo.collect.library.data.entity.Element;
|
||||
import com.navinfo.collect.library.data.entity.LayerManager;
|
||||
import com.navinfo.collect.library.data.entity.NiLocation;
|
||||
import com.navinfo.collect.library.data.entity.Project;
|
||||
import com.navinfo.collect.library.data.entity.TileElement;
|
||||
import com.tencent.wcdb.database.SQLiteCipherSpec;
|
||||
@@ -25,7 +24,7 @@ import com.tencent.wcdb.room.db.WCDBDatabase;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Database(entities = {Element.class, TileElement.class, LayerManager.class, Project.class, NiLocation.class, CheckManager.class},version = 1, exportSchema = false)
|
||||
@Database(entities = {Element.class, TileElement.class, LayerManager.class, Project.class, CheckManager.class},version = 1, exportSchema = false)
|
||||
public abstract class MapLifeDataBase extends RoomDatabase {
|
||||
// marking the instance as volatile to ensure atomic access to the variable
|
||||
/**
|
||||
@@ -38,11 +37,6 @@ public abstract class MapLifeDataBase extends RoomDatabase {
|
||||
*/
|
||||
public abstract IElementDao getElementDao();
|
||||
|
||||
/**
|
||||
* 地图坐标库类
|
||||
*/
|
||||
public abstract INiLocationDao getNiLocationDao();
|
||||
|
||||
/**
|
||||
* 图层要素数据库类
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
package com.navinfo.collect.library.data.dao.impl;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.room.Database;
|
||||
import androidx.room.Room;
|
||||
import androidx.room.RoomDatabase;
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase;
|
||||
|
||||
import com.navinfo.collect.library.data.entity.NiLocation;
|
||||
import com.tencent.wcdb.database.SQLiteCipherSpec;
|
||||
import com.tencent.wcdb.database.SQLiteDatabase;
|
||||
import com.tencent.wcdb.repair.BackupKit;
|
||||
import com.tencent.wcdb.repair.RecoverKit;
|
||||
import com.tencent.wcdb.room.db.WCDBDatabase;
|
||||
import com.tencent.wcdb.room.db.WCDBOpenHelperFactory;
|
||||
|
||||
@Database(entities = { NiLocation.class},version = 1, exportSchema = false)
|
||||
public abstract class TraceDataBase extends RoomDatabase {
|
||||
// marking the instance as volatile to ensure atomic access to the variable
|
||||
/**
|
||||
* 数据库单例对象
|
||||
*/
|
||||
private static volatile TraceDataBase INSTANCE;
|
||||
|
||||
/**
|
||||
* 地图坐标库类
|
||||
*/
|
||||
public abstract INiLocationDao getNiLocationDao();
|
||||
|
||||
/**
|
||||
* 数据库秘钥
|
||||
*/
|
||||
private final static String DB_PASSWORD = "123456";
|
||||
|
||||
public static TraceDataBase getDatabase(final Context context, final String name) {
|
||||
if (INSTANCE == null) {
|
||||
synchronized (TraceDataBase.class) {
|
||||
if (INSTANCE == null) {
|
||||
// [WCDB] To use Room library with WCDB, pass a WCDBOpenHelper factory object
|
||||
// to the database builder with .openHelperFactory(...). In the factory object,
|
||||
// you can specify passphrase and cipher options to open or create encrypted
|
||||
// database, as well as optimization options like asynchronous checkpoint.
|
||||
SQLiteCipherSpec cipherSpec = new SQLiteCipherSpec()
|
||||
.setPageSize(1024)
|
||||
.setSQLCipherVersion(3);
|
||||
WCDBOpenHelperFactory factory = new WCDBOpenHelperFactory()
|
||||
.passphrase(DB_PASSWORD.getBytes()) // passphrase to the database, remove this line for plain-text
|
||||
.cipherSpec(cipherSpec) // cipher to use, remove for default settings
|
||||
.writeAheadLoggingEnabled(true) // enable WAL mode, remove if not needed
|
||||
.asyncCheckpointEnabled(true); // enable asynchronous checkpoint, remove if not needed
|
||||
|
||||
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
|
||||
TraceDataBase.class, name)
|
||||
|
||||
// [WCDB] Specify open helper to use WCDB database implementation instead
|
||||
// of the Android framework.
|
||||
.openHelperFactory(factory)
|
||||
|
||||
// Wipes and rebuilds instead of migrating if no Migration object.
|
||||
// Migration is not part of this codelab.
|
||||
.fallbackToDestructiveMigration()
|
||||
.addCallback(sRoomDatabaseCallback)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the onOpen method to populate the database.
|
||||
* For this sample, we clear the database every time it is created or opened.
|
||||
* <p>
|
||||
* If you want to populate the database only when the database is created for the 1st time,
|
||||
* override RoomDatabase.Callback()#onCreate
|
||||
*/
|
||||
private static Callback sRoomDatabaseCallback = new Callback() {
|
||||
|
||||
@Override
|
||||
public void onOpen(@NonNull SupportSQLiteDatabase db) {
|
||||
super.onOpen(db);
|
||||
// If you want to keep the data through app restarts,
|
||||
// comment out the following line.
|
||||
new PopulateDbAsync(INSTANCE).execute();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Populate the database in the background.
|
||||
* If you want to start with more words, just add them.
|
||||
*/
|
||||
private static class PopulateDbAsync extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
PopulateDbAsync(TraceDataBase db) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(final Void... params) {
|
||||
// Start the app with a clean database every time.
|
||||
// Not needed if you only populate on creation.
|
||||
//mDao.deleteAll();
|
||||
Log.e("qj", "doInBackground");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据恢复
|
||||
*/
|
||||
protected boolean recoverData(){
|
||||
if(INSTANCE!=null){
|
||||
SQLiteDatabase sqlite = ((WCDBDatabase) INSTANCE.getOpenHelper().getWritableDatabase()).getInnerDatabase();
|
||||
RecoverKit recover = new RecoverKit(
|
||||
sqlite, // 要恢复到的目标 DB
|
||||
sqlite.getPath() + "-backup", // 备份文件
|
||||
DB_PASSWORD.getBytes() // 加密备份文件的密钥,非 DB 密钥
|
||||
);
|
||||
int result = recover.run(false); // fatal 参数传 false 表示遇到错误忽略并继续,
|
||||
// 若传 true 遇到错误则中止并返回 FAILED
|
||||
switch (result) {
|
||||
case RecoverKit.RESULT_OK:
|
||||
/* 成功 */
|
||||
Log.e("qj","sRoomDatabaseCallback==RecoverKit成功");
|
||||
return true;
|
||||
case RecoverKit.RESULT_CANCELED: /* 取消操作 */
|
||||
Log.e("qj","sRoomDatabaseCallback==RecoverKit取消操作");
|
||||
break;
|
||||
case RecoverKit.RESULT_FAILED: /* 失败 */
|
||||
Log.e("qj","sRoomDatabaseCallback==RecoverKit失败");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
recover.release();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 备份数据
|
||||
*/
|
||||
protected boolean backup() {
|
||||
Log.e("qj", "sRoomDatabaseCallback===backup==start");
|
||||
if (INSTANCE != null) {
|
||||
//备份文件
|
||||
SQLiteDatabase sqlite = ((WCDBDatabase) INSTANCE.getOpenHelper().getWritableDatabase()).getInnerDatabase();
|
||||
BackupKit backup = new BackupKit(
|
||||
sqlite, // 要备份的 DB
|
||||
sqlite.getPath() + "-backup", // 备份文件
|
||||
"123456".getBytes(), // 加密备份文件的密钥,非 DB 密钥
|
||||
0, null);
|
||||
int result = backup.run();
|
||||
switch (result) {
|
||||
case BackupKit.RESULT_OK:
|
||||
/* 成功 */
|
||||
Log.e("qj", "sRoomDatabaseCallback==成功");
|
||||
return true;
|
||||
case BackupKit.RESULT_CANCELED:
|
||||
/* 取消操作 */
|
||||
Log.e("qj", "sRoomDatabaseCallback==取消操作");
|
||||
break;
|
||||
case BackupKit.RESULT_FAILED:
|
||||
/* 失败 */
|
||||
Log.e("qj", "sRoomDatabaseCallback==失败");
|
||||
break;
|
||||
}
|
||||
|
||||
backup.release();
|
||||
}
|
||||
Log.e("qj", "sRoomDatabaseCallback===backup==end");
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void release() {
|
||||
INSTANCE = null;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.navinfo.collect.library.data.handler
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import androidx.room.RoomDatabase
|
||||
|
||||
open class BaseDataHandler(context: Context, dataBase: MapLifeDataBase) {
|
||||
open class BaseDataHandler(context: Context, dataBase: RoomDatabase) {
|
||||
protected val mContext: Context = context;
|
||||
protected val mDataBase: MapLifeDataBase = dataBase;
|
||||
protected val mDataBase: RoomDatabase = dataBase;
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import com.navinfo.collect.library.data.dao.impl.TraceDataBase
|
||||
import com.navinfo.collect.library.data.entity.*
|
||||
import com.navinfo.collect.library.data.entity.DataLayerItemType.*
|
||||
import com.navinfo.collect.library.utils.GeometryTools
|
||||
@@ -25,7 +26,7 @@ import kotlin.concurrent.thread
|
||||
|
||||
|
||||
open class
|
||||
DataNiLocationHandler(context: Context, dataBase: MapLifeDataBase) :
|
||||
DataNiLocationHandler(context: Context, dataBase: TraceDataBase) :
|
||||
BaseDataHandler(context, dataBase) {
|
||||
|
||||
/**
|
||||
@@ -58,11 +59,11 @@ DataNiLocationHandler(context: Context, dataBase: MapLifeDataBase) :
|
||||
}
|
||||
|
||||
}
|
||||
val niLocationLoad = mDataBase.niLocationDao.find(niLocation.id);
|
||||
val niLocationLoad = (mDataBase as TraceDataBase).niLocationDao.find(niLocation.id);
|
||||
if(niLocationLoad!=null){
|
||||
mDataBase.niLocationDao.update(niLocation)
|
||||
(mDataBase as TraceDataBase).niLocationDao.update(niLocation)
|
||||
}else{
|
||||
mDataBase.niLocationDao.insert(niLocation)
|
||||
(mDataBase as TraceDataBase).niLocationDao.insert(niLocation)
|
||||
}
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(true, "")
|
||||
@@ -89,7 +90,7 @@ DataNiLocationHandler(context: Context, dataBase: MapLifeDataBase) :
|
||||
"uuid=?",
|
||||
arrayOf("'${niLocation.id}'")
|
||||
)
|
||||
mDataBase.niLocationDao.delete(niLocation);
|
||||
(mDataBase as TraceDataBase).niLocationDao.delete(niLocation);
|
||||
} catch (e: Throwable) {
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(false, "${e.message}")
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import com.navinfo.collect.library.data.dao.impl.TraceDataBase
|
||||
import com.navinfo.collect.library.data.entity.Project
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
@@ -22,7 +23,7 @@ open class DataProjectHandler(context: Context, dataBase: MapLifeDataBase) :
|
||||
) {
|
||||
thread(start = true) {
|
||||
try {
|
||||
mDataBase.projectManagerDao.insert(project)
|
||||
(mDataBase as MapLifeDataBase).projectManagerDao.insert(project)
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(true, "")
|
||||
}
|
||||
@@ -41,7 +42,7 @@ open class DataProjectHandler(context: Context, dataBase: MapLifeDataBase) :
|
||||
*/
|
||||
fun getProjectList(callback: (list: List<Project>) -> Unit) {
|
||||
thread(start = true) {
|
||||
val list = mDataBase.projectManagerDao.findList();
|
||||
val list = (mDataBase as MapLifeDataBase).projectManagerDao.findList();
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(list)
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import androidx.lifecycle.lifecycleScope
|
||||
import com.navinfo.collect.library.R
|
||||
import com.navinfo.collect.library.data.entity.QsRecordBean
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import com.navinfo.collect.library.map.NIMapView.LAYER_GROUPS
|
||||
import com.navinfo.collect.library.map.cluster.ClusterMarkerItem
|
||||
import com.navinfo.collect.library.map.cluster.ClusterMarkerRenderer
|
||||
import com.navinfo.collect.library.map.layers.MyItemizedLayer
|
||||
@@ -96,10 +95,6 @@ open class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView,tr
|
||||
private fun initMap() {
|
||||
|
||||
loadBaseMap()
|
||||
mMapView.switchTileVectorLayerTheme(NIMapView.MAP_THEME.DEFAULT)
|
||||
//初始化之间数据图层
|
||||
initQsRecordDataLayer()
|
||||
mMapView.vtmMap.updateMap()
|
||||
|
||||
mapLifeNiLocationTileSource = MapLifeNiLocationTileSource(mContext, mTracePath)
|
||||
|
||||
@@ -107,7 +102,24 @@ open class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView,tr
|
||||
|
||||
labelNiLocationLayer = LabelLayer(mMapView.vtmMap, vectorNiLocationTileLayer, LabelTileLoaderHook(), 15)
|
||||
|
||||
// initMapLifeSource()
|
||||
if(vectorNiLocationTileLayer!=null){
|
||||
addLayer(vectorNiLocationTileLayer,NIMapView.LAYER_GROUPS.BASE)
|
||||
}
|
||||
if(labelNiLocationLayer!=null){
|
||||
addLayer(labelNiLocationLayer, NIMapView.LAYER_GROUPS.BASE)
|
||||
}
|
||||
|
||||
vectorNiLocationTileLayer.isEnabled = false
|
||||
labelNiLocationLayer.isEnabled = false
|
||||
|
||||
mMapView.switchTileVectorLayerTheme(NIMapView.MAP_THEME.DEFAULT)
|
||||
|
||||
//初始化之间数据图层
|
||||
initQsRecordDataLayer()
|
||||
|
||||
mMapView.vtmMap.updateMap()
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -522,14 +534,14 @@ open class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView,tr
|
||||
|
||||
//显示轨迹图层
|
||||
fun showNiLocationLayer() {
|
||||
if(labelNiLocationLayer!=null){
|
||||
addLayer(labelNiLocationLayer, NIMapView.LAYER_GROUPS.VECTOR)
|
||||
}
|
||||
vectorNiLocationTileLayer.isEnabled = true
|
||||
labelNiLocationLayer.isEnabled = true
|
||||
}
|
||||
|
||||
//隐藏轨迹图层
|
||||
fun hideNiLocationLayer() {
|
||||
removeLayer(labelNiLocationLayer)
|
||||
vectorNiLocationTileLayer.isEnabled = false
|
||||
labelNiLocationLayer.isEnabled = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ public class MapLifeNiLocationDecoder extends TileDecoder {
|
||||
}
|
||||
if(count==0){
|
||||
properties.put("nav_style","symbol_object_line");
|
||||
parseGeometry(layerName, GeometryTools.createGeometry("LINESTRING (116.245567 40.073475, 116.245855 40.072811, 116.24706 40.073034)"), properties);
|
||||
parseGeometry(layerName, GeometryTools.createGeometry("LINESTRING (116.245859 40.073475, 116.245855 40.073477)"), properties);
|
||||
}
|
||||
// if(count%55==0){
|
||||
// Log.e("qj","decode==geometry==symbol_track_point"+geometry.toString()+String.valueOf(anyNum));
|
||||
|
||||
@@ -6,6 +6,7 @@ import android.util.Log;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase;
|
||||
import com.navinfo.collect.library.data.dao.impl.TraceDataBase;
|
||||
import com.navinfo.collect.library.data.entity.Element;
|
||||
import com.navinfo.collect.library.data.entity.NiLocation;
|
||||
import org.oscim.core.MapElement;
|
||||
@@ -43,16 +44,16 @@ public class MapLifeNiLocationTileDataSource implements ITileDataSource {
|
||||
// 获取tile对应的坐标范围
|
||||
if (tile.zoomLevel >= 10 && tile.zoomLevel <= 20) {
|
||||
|
||||
int m = 20 - tile.zoomLevel;
|
||||
int m = 21 - 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);
|
||||
List<NiLocation> list = null;
|
||||
if(mEndTime!=0){
|
||||
list = MapLifeDataBase.getDatabase(mCon, dbName).getNiLocationDao().timeTofindList(xStart, xEnd, yStart, yEnd,mStartTime,mEndTime);
|
||||
list = TraceDataBase.getDatabase(mCon, dbName).getNiLocationDao().timeTofindList(xStart, xEnd, yStart, yEnd,mStartTime,mEndTime);
|
||||
}else{
|
||||
list = MapLifeDataBase.getDatabase(mCon, dbName).getNiLocationDao().findList(xStart, xEnd, yStart, yEnd);
|
||||
list = TraceDataBase.getDatabase(mCon, dbName).getNiLocationDao().findList(xStart, xEnd, yStart, yEnd);
|
||||
}
|
||||
|
||||
Log.e("qj","query"+(list==null?0:list.size())+"==="+xStart+"==="+xEnd+"==="+yStart+"==="+yEnd);
|
||||
|
||||
@@ -5,6 +5,8 @@ import android.content.Context;
|
||||
import org.oscim.tiling.ITileDataSource;
|
||||
import org.oscim.tiling.TileSource;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class MapLifeNiLocationTileSource extends TileSource {
|
||||
private Context mCon;
|
||||
private String dbName;
|
||||
|
||||
Reference in New Issue
Block a user