增加轨迹存储业务

This commit is contained in:
qiji4215 2023-04-21 14:04:40 +08:00
parent 5943949cc8
commit 4cce37e991
10 changed files with 252 additions and 91 deletions

View File

@ -94,10 +94,7 @@ public abstract class TraceDataBase extends RoomDatabase {
*/
private static class PopulateDbAsync extends AsyncTask<Void, Void, Void> {
private final ILayerManagerDao mLayerDao;
PopulateDbAsync(TraceDataBase db) {
mLayerDao = db.getLayerManagerDao();
}
@Override

View File

@ -1,6 +1,7 @@
package com.navinfo.omqs.ui.activity.map
import android.os.Bundle
import android.util.Log
import androidx.activity.viewModels
import androidx.core.view.WindowCompat
import androidx.databinding.DataBindingUtil
@ -9,6 +10,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewModelScope
import androidx.navigation.findNavController
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.map.handler.NiLocationListener
import com.navinfo.omqs.Constant
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.ActivityMainBinding
@ -55,8 +57,6 @@ class MainActivity : BaseActivity() {
binding.viewModel = viewModel
// lifecycle.addObserver(viewModel)
lifecycleScope
//初始化轨迹文件
TraceDataBase.getDatabase(this,Constant.DATA_PATH+SystemConstant.USER_ID+"/trace.sqlite")
}
override fun onStart() {
@ -64,6 +64,13 @@ class MainActivity : BaseActivity() {
//开启定位
mapController.locationLayerHandler.startLocation()
//启动轨迹存储
mapController.locationLayerHandler.setNiLocationListener(NiLocationListener {
binding!!.viewModel!!.addSaveTrace(it)
binding!!.viewModel!!.startSaveTraceThread(this)
})
//显示轨迹图层
mapController.layerManagerHandler.showNiLocationLayer(Constant.DATA_PATH+ SystemConstant.USER_ID+"/trace.sqlite")
}
override fun onPause() {

View File

@ -3,15 +3,22 @@ package com.navinfo.omqs.ui.activity.map
import android.content.Context
import android.content.DialogInterface
import android.util.Log
import android.view.View
import androidx.lifecycle.ViewModel
import com.blankj.utilcode.util.ToastUtils
import com.navinfo.collect.library.data.entity.NiLocation
import com.navinfo.collect.library.map.NIMapController
import org.videolan.libvlc.LibVlcUtil
import com.navinfo.collect.library.utils.GeometryTools
import com.navinfo.collect.library.utils.GeometryToolsKt
import com.navinfo.omqs.Constant
import com.navinfo.omqs.R
import com.navinfo.omqs.db.TraceDataBase
import com.navinfo.omqs.system.SystemConstant
import com.navinfo.omqs.ui.dialog.CommonDialog
import com.navinfo.omqs.ui.manager.TakePhotoManager
import dagger.hilt.android.lifecycle.HiltViewModel
import io.realm.RealmSet
import org.videolan.libvlc.LibVlcUtil
import java.util.*
import javax.inject.Inject
/**
@ -24,6 +31,8 @@ class MainViewModel @Inject constructor(
private var mCameraDialog: CommonDialog? = null
private var niLocationList:MutableList<NiLocation> = ArrayList<NiLocation>()
/**
* 点击我的位置回到我的位置
*/
@ -66,4 +75,49 @@ class MainViewModel @Inject constructor(
}
})
}
fun startSaveTraceThread(context: Context){
Thread(Runnable {
try {
while (true){
if(niLocationList!=null&&niLocationList.size>0){
var niLocation = niLocationList[0]
var doubleArray = doubleArrayOf()
doubleArray[0] = niLocation.longitude
doubleArray[1] = niLocation.latitude
val geometry = GeometryTools.createGeometry(doubleArray)
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 ->
niLocation.tilex = x
niLocation.tiley = y
}
}
TraceDataBase.getDatabase(context, Constant.DATA_PATH+ SystemConstant.USER_ID+"/trace.sqlite").niLocationDao.insert(niLocation)
niLocationList.removeAt(0)
Log.e("qj","saveTrace")
}
Thread.sleep(30)
}
} catch (e: InterruptedException) {
e.printStackTrace()
Log.e("qj","异常==${e.message}")
}
}).start()
}
//增加轨迹存储
fun addSaveTrace(niLocation: NiLocation){
if(niLocation!=null&&niLocationList!=null){
niLocationList.add(niLocation)
}
}
}

View File

@ -76,7 +76,6 @@ dependencies {
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
// implementation 'com.yanzhenjie:kalle:0.1.7'
// VTM依赖
implementation "net.sf.kxml:kxml2:2.3.0"
implementation 'org.slf4j:slf4j-api:2.0.7'

View File

@ -3,6 +3,8 @@ package com.navinfo.collect.library.map
import android.content.Context
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.navinfo.collect.library.data.entity.NiLocation
import com.navinfo.collect.library.data.handler.DataNiLocationHandler
import com.navinfo.collect.library.map.handler.*
import com.navinfo.collect.library.map.maphandler.MeasureLayerHandler
import com.navinfo.collect.library.map.handler.ViewportHandler
@ -23,7 +25,6 @@ class NIMapController {
lateinit var viewportHandler: ViewportHandler
lateinit var measureLayerHandler: MeasureLayerHandler
fun init(context: AppCompatActivity, mapView: NIMapView, options: NIMapOptions? = null, mapPath: String) {
Constant.MAP_PATH = mapPath
layerManagerHandler = LayerManagerHandler(context, mapView)

View File

@ -13,7 +13,9 @@ import android.widget.RelativeLayout;
import androidx.annotation.Nullable;
import com.navinfo.collect.library.R;
import com.navinfo.collect.library.data.entity.NiLocation;
import com.navinfo.collect.library.map.layers.NaviMapScaleBar;
import com.navinfo.collect.library.map.source.MapLifeNiLocationTileSource;
import org.oscim.android.MapPreferences;
import org.oscim.android.MapView;
@ -25,10 +27,22 @@ import org.oscim.event.Gesture;
import org.oscim.event.GestureListener;
import org.oscim.layers.GroupLayer;
import org.oscim.layers.Layer;
import org.oscim.layers.tile.buildings.BuildingLayer;
import org.oscim.layers.tile.vector.OsmTileLayer;
import org.oscim.layers.tile.vector.VectorTileLayer;
import org.oscim.layers.tile.vector.labeling.LabelLayer;
import org.oscim.layers.tile.vector.labeling.LabelTileLoaderHook;
import org.oscim.map.Map;
import org.oscim.renderer.GLViewport;
import org.oscim.theme.IRenderTheme;
import org.oscim.theme.ThemeLoader;
import org.oscim.theme.VtmThemes;
import org.oscim.tiling.source.mapfile.MapFileTileSource;
import org.oscim.tiling.source.mapfile.MultiMapFileTileSource;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
@ -85,12 +99,11 @@ public final class NIMapView extends RelativeLayout {
// private Layer gridLayer;
protected Context mContext;
/**
* 地图状态信息
*/
private MapPreferences mPrefs;
// protected String mapFilePath = Constant.ROOT_PATH + "/map";
protected String mapFilePath = "/map";
protected GroupLayer baseGroupLayer; // 用于盛放所有基础底图的图层组便于统一管理
public void setOptions(NIMapOptions option) {
@ -348,6 +361,10 @@ public final class NIMapView extends RelativeLayout {
mapPosition.setPosition(options.getCoordinate().getLatitude(), options.getCoordinate().getLongitude());
getVtmMap().animator().animateTo(100, mapPosition);
}
List<NiLocation> list = new ArrayList<NiLocation>();
list.add(new NiLocation());
}
@ -422,83 +439,84 @@ public final class NIMapView extends RelativeLayout {
// }
// }
// private void initVectorTileLayer() {
// if (baseGroupLayer == null) {
// baseGroupLayer = new GroupLayer(getVtmMap());
// }
// for (Layer layer : baseGroupLayer.layers) {
// getVtmMap().layers().remove(layer);
// }
// baseGroupLayer.layers.clear();
//
// File baseMapFolder = new File(mapFilePath);
// if (!baseMapFolder.exists()) {
// return;
// }
//
// File[] mapFileList = baseMapFolder.listFiles();
//
// if (mapFileList != null && mapFileList.length > 0) {
//
// MultiMapFileTileSource multiMapFileTileSource = new MultiMapFileTileSource();
//
// for (File mapFile : mapFileList) {
//
// if (!mapFile.exists() || !mapFile.getName().endsWith(".map")) {
// continue;
// }
//
// MapFileTileSource mTileSource = new MapFileTileSource();
//
// mTileSource.setPreferredLanguage("zh");
//
// if (mTileSource.setMapFile(mapFile.getAbsolutePath())) {
// multiMapFileTileSource.add(mTileSource);
// }
//
// }
//
// VectorTileLayer baseMapLayer = new OsmTileLayer(getVtmMap());
// baseMapLayer.setTileSource(multiMapFileTileSource);
//
// baseGroupLayer.layers.add(baseMapLayer);
//
// if (getTheme(null) != null)
// baseMapLayer.setTheme(getTheme(null));
//
// baseGroupLayer.layers.add(new BuildingLayer(getVtmMap(), baseMapLayer));
// baseGroupLayer.layers.add(new LabelLayer(getVtmMap(), baseMapLayer));
//
// for (Layer layer : baseGroupLayer.layers) {
// if (layer instanceof LabelLayer) {
// getVtmMap().layers().add(layer, LAYER_GROUPS.VECTOR.groupIndex);
// } else {
// getVtmMap().layers().add(layer, LAYER_GROUPS.BASE_VECTOR.groupIndex);
// }
// }
// }
// }
/* public void initVectorTileLayer(){
if (baseGroupLayer == null) {
baseGroupLayer = new GroupLayer(getVtmMap());
}
for (Layer layer : baseGroupLayer.layers) {
getVtmMap().layers().remove(layer);
}
baseGroupLayer.layers.clear();
// //获取渲染资源
// public IRenderTheme getTheme(final String styleId) {
// AssetsRenderTheme theme = new AssetsRenderTheme(mContext.getAssets(), null, "default.xml");
// if (styleId == null || "".equals(styleId.trim())) {
// switch (2) {
// case 0:
// theme = new AssetsRenderTheme(mContext.getAssets(), null, "default.xml");
// break;
// case 1:
// theme = new AssetsRenderTheme(mContext.getAssets(), null, "osmarender.xml");
// break;
// case 2:
// theme = new AssetsRenderTheme(mContext.getAssets(), null, "tronrender.xml");
// break;
// }
//
// }
//
// return ThemeLoader.load(theme);
// }
File baseMapFolder = new File(mapFilePath);
if (!baseMapFolder.exists()) {
return;
}
File[] mapFileList = baseMapFolder.listFiles();
if (mapFileList != null && mapFileList.length > 0) {
MultiMapFileTileSource multiMapFileTileSource = new MultiMapFileTileSource();
for (File mapFile : mapFileList) {
if (!mapFile.exists() || !mapFile.getName().endsWith(".map")) {
continue;
}
MapFileTileSource mTileSource = new MapFileTileSource();
mTileSource.setPreferredLanguage("zh");
if (mTileSource.setMapFile(mapFile.getAbsolutePath())) {
multiMapFileTileSource.add(mTileSource);
}
}
VectorTileLayer baseMapLayer = new OsmTileLayer(getVtmMap());
baseMapLayer.setTileSource(multiMapFileTileSource);
baseGroupLayer.layers.add(baseMapLayer);
if (getTheme(null) != null)
baseMapLayer.setTheme(getTheme(null));
baseGroupLayer.layers.add(new BuildingLayer(getVtmMap(), baseMapLayer));
baseGroupLayer.layers.add(new LabelLayer(getVtmMap(), baseMapLayer));
for (Layer layer : baseGroupLayer.layers) {
if (layer instanceof LabelLayer) {
getVtmMap().layers().add(layer, LAYER_GROUPS.VECTOR.groupIndex);
} else {
getVtmMap().layers().add(layer, LAYER_GROUPS.BASE.groupIndex);
}
}
}
}*/
//获取渲染资源
/*
public IRenderTheme getTheme(final String styleId) {
AssetsRenderTheme theme = new AssetsRenderTheme(mContext.getAssets(), null, "default.xml");
if (styleId == null || "".equals(styleId.trim())) {
switch (2) {
case 0:
theme = new AssetsRenderTheme(mContext.getAssets(), null, "default.xml");
break;
case 1:
theme = new AssetsRenderTheme(mContext.getAssets(), null, "osmarender.xml");
break;
case 2:
theme = new AssetsRenderTheme(mContext.getAssets(), null, "tronrender.xml");
break;
}
}
return ThemeLoader.load(theme);
}
*/
// public void addDefaultVectorTileLayer(MAP_THEME theme) {
// if (defaultVectorTileLayer != null) {
@ -969,4 +987,5 @@ public final class NIMapView extends RelativeLayout {
public void updateMap(boolean redraw) {
mapView.map().updateMap(redraw);
}
}

View File

@ -10,9 +10,11 @@ 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
import com.navinfo.collect.library.map.source.MapLifeNiLocationTileSource
import com.navinfo.collect.library.map.source.NavinfoMultiMapFileTileSource
import com.navinfo.collect.library.system.Constant
import com.navinfo.collect.library.utils.GeometryTools
@ -34,6 +36,7 @@ import org.oscim.layers.marker.*
import org.oscim.layers.tile.buildings.BuildingLayer
import org.oscim.layers.tile.vector.VectorTileLayer
import org.oscim.layers.tile.vector.labeling.LabelLayer
import org.oscim.layers.tile.vector.labeling.LabelTileLoaderHook
import org.oscim.tiling.source.OkHttpEngine.OkHttpFactory
import org.oscim.tiling.source.mapfile.MapFileTileSource
import java.io.File
@ -64,6 +67,21 @@ open class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView) :
private lateinit var markerRendererFactory: MarkerRendererFactory
private val markerItemsNames = mutableListOf<MarkerInterface>()
/**
* 轨迹渲染图层
*/
private lateinit var mapLifeNiLocationTileSource: MapLifeNiLocationTileSource
/**
* 轨迹数据图层
*/
private lateinit var vectorNiLocationTileLayer: VectorTileLayer
/**
* 增加作业渲染
*/
private lateinit var labelNiLocationLayer: LabelLayer
/**
* 文字大小
*/
@ -496,6 +514,25 @@ open class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView) :
}
}
//显示轨迹图层
fun showNiLocationLayer(dbName: String?) {
if (mapLifeNiLocationTileSource == null) {
mapLifeNiLocationTileSource = MapLifeNiLocationTileSource(mContext, dbName)
}
if (vectorNiLocationTileLayer == null) {
vectorNiLocationTileLayer = VectorTileLayer(mMapView.vtmMap, mapLifeNiLocationTileSource)
}
if (labelNiLocationLayer == null) {
labelNiLocationLayer =
LabelLayer(mMapView.vtmMap, vectorNiLocationTileLayer, LabelTileLoaderHook(), 15)
}
addLayer(labelNiLocationLayer, NIMapView.LAYER_GROUPS.VECTOR)
}
//隐藏轨迹图层
fun hideNiLocationLayer() {
removeLayer(labelNiLocationLayer)
}
}

View File

@ -9,6 +9,7 @@ import com.baidu.location.BDLocation
import com.baidu.location.LocationClient
import com.baidu.location.LocationClientOption
import com.baidu.location.LocationClientOption.LocationMode
import com.navinfo.collect.library.data.entity.NiLocation
import com.navinfo.collect.library.map.GeoPoint
import com.navinfo.collect.library.map.NIMapView
import org.oscim.layers.LocationLayer
@ -20,6 +21,7 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : Bas
private var bFirst = true
private val mLocationLayer: LocationLayer = LocationLayer(mMapView.vtmMap)
private lateinit var locationClient: LocationClient
private lateinit var niLocationListener: NiLocationListener
init {
///添加定位图层到地图,[NIMapView.LAYER_GROUPS.NAVIGATION] 是最上层layer组
@ -58,6 +60,10 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : Bas
mLocationLayer.setPosition(
it.latitude, it.longitude, it.radius
)
Log.e("qj","location==${it.longitude}==errorCode===$errorCode===${it.locTypeDescription}")
if(niLocationListener!=null){
getCurrentNiLocation()?.let { it1 -> niLocationListener.call(it1) }
}
//第一次定位成功显示当前位置
if (this.bFirst) {
animateToCurrentPosition(16.0)
@ -102,6 +108,7 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : Bas
locationClient.locOption = locationOption
} catch (e: Throwable) {
Toast.makeText(mContext, "定位初始化失败 $e", Toast.LENGTH_SHORT)
Log.e("qj","定位初始化失败$e")
}
}
@ -151,6 +158,39 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : Bas
}
return null
}
//获取当前定位对象
fun getCurrentNiLocation(): NiLocation? {
if(mCurrentLocation!=null){
val niLocation:NiLocation = NiLocation()
niLocation.longitude = mCurrentLocation!!.longitude
niLocation.latitude = mCurrentLocation!!.latitude
niLocation.direction = mCurrentLocation!!.direction.toDouble()
niLocation.altitude = mCurrentLocation!!.altitude
niLocation.radius = mCurrentLocation!!.radius.toDouble()
niLocation.time = mCurrentLocation!!.time
niLocation.adCode = mCurrentLocation!!.adCode
niLocation.country = mCurrentLocation!!.country
niLocation.province = mCurrentLocation!!.province
niLocation.city = mCurrentLocation!!.city
niLocation.district = mCurrentLocation!!.district
niLocation.cityCode = mCurrentLocation!!.cityCode
niLocation.floor = mCurrentLocation!!.floor
niLocation.satelliteNumber = mCurrentLocation!!.satelliteNumber
niLocation.address = mCurrentLocation!!.addrStr
niLocation.street = mCurrentLocation!!.street
niLocation.town = mCurrentLocation!!.town
niLocation.streetNumber = mCurrentLocation!!.streetNumber
niLocation.errorCode = mCurrentLocation!!.locType.toString()
return niLocation
}
return null
}
//设置定位回调
fun setNiLocationListener(listener: NiLocationListener){
niLocationListener = listener
}
}
/**
@ -161,4 +201,14 @@ private class MyLocationListener(callback: (BDLocation) -> Unit) : BDAbstractLoc
override fun onReceiveLocation(location: BDLocation) {
call(location)
}
}
/**
* 实现定位回调
*/
public class NiLocationListener(callback: (NiLocation) -> Unit){
val call = callback;
fun onReceiveLocation(location: NiLocation) {
call(location)
}
}

View File

@ -40,8 +40,6 @@ public class MapLifeNiLocationTileDataSource implements ITileDataSource {
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void query(MapTile tile, ITileDataSink mapDataSink) {
// 获取tile对应的坐标范围
if (tile.zoomLevel >= 10 && tile.zoomLevel <= 20) {

View File

@ -2,7 +2,6 @@ package com.navinfo.collect.library.utils;
import android.graphics.Point;
import android.util.Log;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
@ -15,7 +14,6 @@ import org.locationtech.jts.io.WKTReader;
import org.locationtech.jts.operation.linemerge.LineMerger;
import org.oscim.core.GeoPoint;
import org.oscim.map.Map;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
@ -69,6 +67,7 @@ public class GeometryTools {
}
/**
* 返回点几何
*