增加质检结果展示页面

This commit is contained in:
squallzhjch
2023-04-12 15:07:46 +08:00
parent fa4ad254a5
commit 88326d3247
76 changed files with 1554 additions and 655 deletions
+42 -31
View File
@@ -1,11 +1,13 @@
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
id 'kotlin-parcelize' // 序列化
id 'kotlin-android'
id 'kotlin-kapt'
id 'realm-android'
}
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'realm-android'
ext.roomversion = "2.1.0"
ext.vtmVersion = "0.18.0"
ext.realm_version = '10.10.1'
ext.appcompatVersion = "1.3.0"
@@ -31,7 +33,7 @@ android {
}
}
ndk {
abiFilters "armeabi", "armeabi-v7a"
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a"
}
}
@@ -53,20 +55,22 @@ android {
}
}
//configurations.all {
// resolutionStrategy {
// force 'com.intellij:annotations:13.0'
// }
//}
dependencies {
api fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
api files('libs/BaiduLBS_AndroidSDK_Lib.aar')
implementation "androidx.appcompat:appcompat:$appcompatVersion"
implementation "com.google.android.material:material:$materialVersion"
api files('libs/BaiduLBS_Android.jar')
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
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:1.7.28"
implementation 'org.slf4j:slf4j-api:2.0.7'
implementation "org.mapsforge:vtm:$vtmVersion"
implementation "org.mapsforge:vtm-themes:$vtmVersion"
implementation "org.mapsforge:vtm-android:$vtmVersion"
@@ -94,30 +98,37 @@ dependencies {
implementation "com.badlogicgames.gdx:gdx-backend-android:1.11.0"
implementation "com.caverock:androidsvg:1.4"
implementation "org.mapsforge:vtm-jts:$vtmVersion"
implementation "org.locationtech.jts:jts-core:1.18.2"
implementation "com.squareup.okhttp3:okhttp:3.12.13"
implementation "com.squareup.okio:okio:1.15.0"
implementation 'org.locationtech.jts:jts-core:1.19.0'
implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.11'
implementation 'com.squareup.okio:okio:3.3.0'
implementation "com.fasterxml.jackson.core:jackson-annotations:2.9.9"
implementation "com.fasterxml.jackson.core:jackson-core:2.9.9"
implementation "com.fasterxml.jackson.core:jackson-databind:2.9.9"
implementation 'com.tencent.wcdb:room:1.0.8' // 代替 room-runtime,同时也不需要再引用 wcdb-android
implementation "androidx.sqlite:sqlite:2.0.1"
implementation "androidx.room:room-runtime:2.1.0"
annotationProcessor "androidx.room:room-compiler:2.1.0"
kapt "androidx.room:room-compiler:2.1.0"
androidTestImplementation 'androidx.room:room-testing:2.0.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
kapt 'androidx.lifecycle:lifecycle-compiler:2.0.0'
implementation 'com.tencent.wcdb:wcdb-android:1.0.0'
implementation "androidx.core:core-ktx:1.8.0"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
// 协程核心库
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
// 协程Android支持库
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
// 协程Java8支持库
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.6.4'
//room 数据库相关
api 'com.tencent.wcdb:room:1.1-19' // 代替 room-runtime,同时也不需要再引用 wcdb-android
api 'androidx.sqlite:sqlite-ktx:2.3.1'
api "androidx.room:room-runtime:2.5.1"
api "androidx.room:room-ktx:2.5.1"
annotationProcessor "androidx.room:room-compiler:2.5.1"
annotationProcessor 'android.arch.persistence.room:compiler:1.1.1'
kapt 'android.arch.persistence.room:compiler:1.1.1'// compiler 需要用 room 的
kapt "androidx.room:room-compiler:2.5.1"
kapt "androidx.room:room-ktx:2.5.1"
// //分页加载
// api "androidx.room:room-paging:$roomversion"
// api "androidx.paging:paging-runtime-ktx:3.1.1"
androidTestImplementation "android.arch.persistence.room:testing:1.1.1"
api 'com.tencent.wcdb:wcdb-android:1.1-19'
// // 协程核心库
// implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
// // 协程Android支持库
// implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
// // 协程Java8支持库
// implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.6.4'
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,57 +1,57 @@
package com.navinfo.collect.library.data.entity
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
//enum class StatusEnum(val status: Int) {
// NONE(0), WAITING(1), LOADING(2), PAUSE(3),
// ERROR(4), DONE(5), UPDATE(6)
//}
open class OfflineMapCityBean @JvmOverloads constructor(
@PrimaryKey var id: String = "",
var fileName: String = "",
var name: String = "",
var url: String = "",
var version: Long = 0L,
var fileSize: Long = 0L,
var currentSize: Long = 0L,
var status: Int = NONE
) : RealmObject() {
companion object Status{
const val NONE = 0 //无状态
const val WAITING = 1 //等待中
const val LOADING = 2 //下载中
const val PAUSE = 3 //暂停
const val ERROR = 4 //错误
const val DONE = 5 //完成
const val UPDATE = 6 //有新版本要更新
}
// // status的转换对象
// var statusEnum: StatusEnum
// get() {
// return try {
// StatusEnum.values().find { it.status == status }!!
// } catch (e: IllegalArgumentException) {
// StatusEnum.NONE
// }
// }
// set(value) {
// status = value.status
// }
fun getFileSizeText(): String {
return if (fileSize < 1024.0)
"$fileSize B"
else if (fileSize < 1048576.0)
"%.2f K".format(fileSize / 1024.0)
else if (fileSize < 1073741824.0)
"%.2f M".format(fileSize / 1048576.0)
else
"%.2f M".format(fileSize / 1073741824.0)
}
}
//package com.navinfo.collect.library.data.entity
//
//import io.realm.RealmObject
//import io.realm.annotations.PrimaryKey
//
////enum class StatusEnum(val status: Int) {
//// NONE(0), WAITING(1), LOADING(2), PAUSE(3),
//// ERROR(4), DONE(5), UPDATE(6)
////}
//
//open class OfflineMapCityBean @JvmOverloads constructor(
// @PrimaryKey var id: String = "",
// var fileName: String = "",
// var name: String = "",
// var url: String = "",
// var version: Long = 0L,
// var fileSize: Long = 0L,
// var currentSize: Long = 0L,
// var status: Int = NONE
//) : RealmObject() {
//
// companion object Status{
// const val NONE = 0 //无状态
// const val WAITING = 1 //等待中
// const val LOADING = 2 //下载中
// const val PAUSE = 3 //暂停
// const val ERROR = 4 //错误
// const val DONE = 5 //完成
// const val UPDATE = 6 //有新版本要更新
// }
//
//// // status的转换对象
//// var statusEnum: StatusEnum
//// get() {
//// return try {
//// StatusEnum.values().find { it.status == status }!!
//// } catch (e: IllegalArgumentException) {
//// StatusEnum.NONE
//// }
//// }
//// set(value) {
//// status = value.status
//// }
//
// fun getFileSizeText(): String {
// return if (fileSize < 1024.0)
// "$fileSize B"
// else if (fileSize < 1048576.0)
// "%.2f K".format(fileSize / 1024.0)
// else if (fileSize < 1073741824.0)
// "%.2f M".format(fileSize / 1048576.0)
// else
// "%.2f M".format(fileSize / 1073741824.0)
// }
//
//
//}
@@ -1,43 +1,43 @@
package com.navinfo.collect.library.data.entity
import io.realm.RealmModel
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
import io.realm.annotations.RealmClass
@RealmClass
open class OfflineMapCityRealmObject: RealmModel {
@PrimaryKey
var id: String = ""
var fileName: String=""
var name: String = ""
var url: String = ""
var version: Long = 0
var fileSize: Long = 0
var currentSize:Long = 0
var status:Int = 0
constructor(){
}
constructor(
id: String,
fileName: String,
name: String,
url: String,
version: Long,
fileSize: Long,
currentSize: Long,
status: Int
) {
this.id = id
this.fileName = fileName
this.name = name
this.url = url
this.version = version
this.fileSize = fileSize
this.currentSize = currentSize
this.status = status
}
}
//package com.navinfo.collect.library.data.entity
//
//import io.realm.RealmModel
//import io.realm.RealmObject
//import io.realm.annotations.PrimaryKey
//import io.realm.annotations.RealmClass
//
//@RealmClass
//open class OfflineMapCityRealmObject: RealmModel {
// @PrimaryKey
// var id: String = ""
// var fileName: String=""
// var name: String = ""
// var url: String = ""
// var version: Long = 0
// var fileSize: Long = 0
// var currentSize:Long = 0
// var status:Int = 0
//
// constructor(){
//
// }
//
// constructor(
// id: String,
// fileName: String,
// name: String,
// url: String,
// version: Long,
// fileSize: Long,
// currentSize: Long,
// status: Int
// ) {
// this.id = id
// this.fileName = fileName
// this.name = name
// this.url = url
// this.version = version
// this.fileSize = fileSize
// this.currentSize = currentSize
// this.status = status
// }
//}
@@ -1,17 +1,20 @@
package com.navinfo.collect.library.map.handler
import android.content.Context
import android.os.Environment
import com.navinfo.collect.library.map.NIMapView
import com.navinfo.collect.library.map.NIMapView.LAYER_GROUPS
import com.navinfo.collect.library.map.source.NavinfoMapRastorTileSource
import com.navinfo.collect.library.map.source.NavinfoMultiMapFileTileSource
import com.navinfo.collect.library.system.Constant
import okhttp3.Cache
import okhttp3.OkHttpClient
import org.oscim.layers.GroupLayer
import org.oscim.layers.Layer
import org.oscim.layers.LocationLayer
import org.oscim.layers.tile.bitmap.BitmapTileLayer
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.tiling.source.OkHttpEngine.OkHttpFactory
import org.oscim.tiling.source.mapfile.MapFileTileSource
import java.io.File
/**
@@ -19,7 +22,8 @@ import java.io.File
*/
class LayerManagerHandler(context: Context, mapView: NIMapView) :
BaseHandler(context, mapView) {
private var baseRasterLayer: Layer? = null
private var baseGroupLayer // 用于盛放所有基础底图的图层组,便于统一管理
: GroupLayer? = null
init {
initMap()
@@ -29,8 +33,10 @@ class LayerManagerHandler(context: Context, mapView: NIMapView) :
* 初始化地图
*/
private fun initMap() {
switchBaseMapType(BASE_MAP_TYPE.CYCLE_MAP)
loadBaseMap()
mMapView.switchTileVectorLayerTheme(NIMapView.MAP_THEME.DEFAULT)
mMapView.vtmMap.updateMap()
// initVectorTileLayer()
// initMapLifeSource()
}
@@ -39,15 +45,60 @@ class LayerManagerHandler(context: Context, mapView: NIMapView) :
/**
* 切换基础底图样式
*/
fun switchBaseMapType(type: BASE_MAP_TYPE) {
if (baseRasterLayer != null) {
mMapView.vtmMap.layers().remove(baseRasterLayer)
baseRasterLayer = null
mMapView.vtmMap.updateMap()
fun loadBaseMap() {
if (baseGroupLayer == null) {
baseGroupLayer = GroupLayer(mMapView.vtmMap)
addLayer(baseGroupLayer!!, NIMapView.LAYER_GROUPS.BASE)
}
baseGroupLayer?.let {
for (layer in it.layers) {
removeLayer(layer)
}
it.layers.clear()
val builder = OkHttpClient.Builder()
val urlTileSource: NavinfoMultiMapFileTileSource =
NavinfoMultiMapFileTileSource.builder()
.httpFactory(OkHttpFactory(builder)) //.locale("en")
.build()
// Cache the tiles into file system
val cacheDirectory = File(Constant.MAP_PATH, "cache")
val cacheSize = 200 * 1024 * 1024 // 10 MB
val cache = Cache(cacheDirectory, cacheSize.toLong())
builder.cache(cache)
// val headerMap = HashMap<String, String>()
// headerMap["token"] = ""//Constant.TOKEN
// urlTileSource.setHttpRequestHeaders(headerMap)
val baseLayer = VectorTileLayer(mMapView.vtmMap, urlTileSource)
val baseMapFolder = File("${Constant.MAP_PATH}offline")
if (baseMapFolder.exists()) {
val dirFileList = baseMapFolder.listFiles()
if (dirFileList != null && dirFileList.isNotEmpty()) {
for (mapFile in dirFileList) {
if (!mapFile.isFile || !mapFile.name.endsWith(".map")) {
continue
}
val mTileSource = MapFileTileSource()
mTileSource.setPreferredLanguage("zh")
if (mTileSource.setMapFile(mapFile.absolutePath)) {
urlTileSource.add(mTileSource)
}
}
}
baseLayer.tileSource = urlTileSource
it.layers.add(baseLayer)
it.layers.add(BuildingLayer(mMapView.vtmMap, baseLayer))
it.layers.add(LabelLayer(mMapView.vtmMap, baseLayer))
for (layer in it.layers) {
addLayer(layer, NIMapView.LAYER_GROUPS.BASE)
}
mMapView.updateMap()
}
}
baseRasterLayer = getRasterTileLayer(type.url, type.tilePath, true)
addLayer(baseRasterLayer!!, LAYER_GROUPS.BASE)
mMapView.updateMap()
}
private fun getRasterTileLayer(
@@ -61,16 +112,13 @@ class LayerManagerHandler(context: Context, mapView: NIMapView) :
.httpFactory(OkHttpFactory(builder)).build()
// 如果使用缓存
if (useCache) {
val cacheDirectory: File =
File(Constant.MAP_PATH, "tiles-raster")
val cacheDirectory =
File(Constant.MAP_PATH, "cache")
val cacheSize = 300 * 1024 * 1024 // 300 MB
val cache = Cache(cacheDirectory, cacheSize.toLong())
builder.cache(cache)
}
// mTileSource.setHttpEngine(new OkHttpEngine.OkHttpFactory(builder));
// mTileSource.setHttpRequestHeaders(Collections.singletonMap("User-Agent", "vtm-android-example"));
// mTileSource.setCache(new TileCache(mContext, defaultDir, url.substring(url.indexOf(":")+1)));
return BitmapTileLayer(mMapView.vtmMap, mTileSource)
}
}
@@ -12,8 +12,7 @@ import com.navinfo.collect.library.map.NIMapView
import org.oscim.layers.LocationLayer
class LocationLayerHandler(context: Context, mapView: NIMapView) :
BaseHandler(context, mapView) {
class LocationLayerHandler(context: Context, mapView: NIMapView) : BaseHandler(context, mapView) {
private var mCurrentLocation: BDLocation? = null
private var bFirst = true
@@ -55,13 +54,11 @@ class LocationLayerHandler(context: Context, mapView: NIMapView) :
val errorCode = it.locType
mCurrentLocation = it
mLocationLayer.setPosition(
it.latitude,
it.longitude,
it.radius
it.latitude, it.longitude, it.radius
)
//第一次定位成功显示当前位置
if (this.bFirst) {
animateToCurrentPosition()
animateToCurrentPosition(16.0)
}
}
@@ -97,9 +94,7 @@ class LocationLayerHandler(context: Context, mapView: NIMapView) :
// locationOption.setOpenAutoNotifyMode()
//设置打开自动回调位置模式,该开关打开后,期间只要定位SDK检测到位置变化就会主动回调给开发者
locationOption.setOpenAutoNotifyMode(
1000,
1,
LocationClientOption.LOC_SENSITIVITY_HIGHT
1000, 1, LocationClientOption.LOC_SENSITIVITY_HIGHT
)
//需将配置好的LocationClientOption对象,通过setLocOption方法传递给LocationClient对象使用
locationClient.locOption = locationOption
@@ -130,12 +125,21 @@ class LocationLayerHandler(context: Context, mapView: NIMapView) :
/**
* 回到当前位置
*/
fun animateToCurrentPosition()
{
fun animateToCurrentPosition(zoom: Double) {
mCurrentLocation?.run {
val mapPosition = mMapView.vtmMap.mapPosition;
mapPosition.setPosition(this.latitude, this.longitude);
mMapView.vtmMap.animator().animateTo(300, mapPosition);
val mapPosition = mMapView.vtmMap.mapPosition
mapPosition.zoom = zoom
mapPosition.setPosition(this.latitude, this.longitude)
mMapView.vtmMap.animator().animateTo(300, mapPosition)
}
}
fun animateToCurrentPosition() {
mCurrentLocation?.run {
val mapPosition = mMapView.vtmMap.mapPosition
mapPosition.setPosition(this.latitude, this.longitude)
mMapView.vtmMap.animator().animateTo(300, mapPosition)
}
}
}
@@ -143,8 +147,7 @@ class LocationLayerHandler(context: Context, mapView: NIMapView) :
/**
* 实现定位回调
*/
private class MyLocationListener(callback: (BDLocation) -> Unit) :
BDAbstractLocationListener() {
private class MyLocationListener(callback: (BDLocation) -> Unit) : BDAbstractLocationListener() {
val call = callback;
override fun onReceiveLocation(location: BDLocation) {
call(location)
@@ -1,39 +1,38 @@
package com.navinfo.collect.library.map.source;
import android.util.Log;
import com.navinfo.collect.library.system.Constant;
import org.oscim.core.BoundingBox;
import org.oscim.core.MapElement;
import org.oscim.core.Tag;
import org.oscim.core.Tile;
import org.oscim.tiling.ITileDataSource;
import org.oscim.tiling.OverzoomTileDataSource;
import org.oscim.tiling.source.UrlTileSource;
import org.oscim.tiling.source.geojson.GeojsonTileSource;
import org.oscim.tiling.source.mapfile.IMapFileTileSource;
import org.oscim.tiling.source.mapfile.MapDatabase;
import org.oscim.tiling.source.mapfile.MapFileTileSource;
import org.oscim.utils.FastMath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/*
*com.navinfo.map.source
*com.nmp.map.source
*zhjch
*2021/9/17
*9:46
*说明()
*/
public class NavinfoMultiMapFileTileSource extends GeojsonTileSource implements IMapFileTileSource {
public class NavinfoMultiMapFileTileSource extends UrlTileSource implements IMapFileTileSource {
// private static final String DEFAULT_URL = "http://cmp-gateway-sp9-port.ayiqdpfs.cloud.app.ncloud.navinfo.com/maponline/map/online";
private static final String DEFAULT_URL = "http://epohvqjxts85k6u-port.ayiqdpfs.cloud.app.ncloud.navinfo.com/map/online/geoJson";
private static final String DEFAULT_PATH = "x={X}&y={Y}&z={Z}";
private static final String DEFAULT_URL = "http://c.tile.opencyclemap.org/cycle";
private static final String DEFAULT_PATH = "/{Z}}/{X}/{Y}.png";
private static final TileUrlFormatter mTileUrlFormatter = URL_FORMATTER;
@@ -67,7 +66,6 @@ public class NavinfoMultiMapFileTileSource extends GeojsonTileSource implements
public String getTileUrl(Tile tile) {
StringBuilder sb = new StringBuilder();
sb.append(DEFAULT_URL).append("?").append(mTileUrlFormatter.formatTilePath(this, tile));
System.out.println(sb.toString());
return sb.toString();
}
@@ -125,66 +123,13 @@ public class NavinfoMultiMapFileTileSource extends GeojsonTileSource implements
mapDatabase.restrictToZoomRange(zoomLevels[0], zoomLevels[1]);
multiMapDatabase.add(mapDatabase);
} catch (IOException e) {
Log.e("jingo", e.getMessage());
log.debug(e.getMessage());
}
}
// return new NavinfoMultiMapDatabase(this, new NavinfoVectorTileDecoder(locale), getHttpEngine());
return new OverzoomTileDataSource(multiMapDatabase, mOverZoom);
}
private static Map<String, Tag> mappings = new LinkedHashMap<>();
private static Tag addMapping(String key, String val) {
Tag tag = new Tag(key, val);
mappings.put(key + "=" + val, tag);
return tag;
}
@Override
public void decodeTags(MapElement mapElement, Map<String, Object> properties) {
boolean hasName = false;
String fallbackName = null;
for (Map.Entry<String, Object> entry : properties.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 (locale.equals(key.substring(5))) {
hasName = true;
mapElement.tags.add(new Tag(Tag.KEY_NAME, val, false));
}
continue;
}
Tag tag = mappings.get(key + "=" + val);
if (tag == null)
tag = addMapping(key, val);
mapElement.tags.add(tag);
}
if (!hasName && fallbackName != null)
mapElement.tags.add(new Tag(Tag.KEY_NAME, fallbackName, false));
// Calculate height of building parts
if (!properties.containsKey(Tag.KEY_HEIGHT)) {
if (properties.containsKey(Tag.KEY_VOLUME) && properties.containsKey(Tag.KEY_AREA)) {
Object volume = properties.get(Tag.KEY_VOLUME);
String volumeStr = (volume instanceof String) ? (String) volume : String.valueOf(volume);
Object area = properties.get(Tag.KEY_AREA);
String areaStr = (area instanceof String) ? (String) area : String.valueOf(area);
float height = Float.parseFloat(volumeStr) / Float.parseFloat(areaStr);
String heightStr = String.valueOf(FastMath.round2(height));
mapElement.tags.add(new Tag(Tag.KEY_HEIGHT, heightStr, false));
}
}
}
@Override
public OpenResult open() {
@@ -194,8 +139,10 @@ public class NavinfoMultiMapFileTileSource extends GeojsonTileSource implements
if (result != OpenResult.SUCCESS)
openResult = result;
}
if(openResult != OpenResult.SUCCESS)
return super.open();
if(openResult != OpenResult.SUCCESS) {
return super.open();
}
return openResult;
}
@@ -11,6 +11,9 @@ import java.util.Map;
public class Constant {
//服务地址
public static String URL_BASE = "http://cmp-gateway-sp9-port.ayiqdpfs.cloud.app.ncloud.navinfo.com/";
public static String MAP_PATH = Environment.getExternalStorageDirectory() + "/map/";
public static void setVisibleTypeMap(Map<String, Boolean> visibleTypeMap) {