增加质检结果展示页面

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

View File

@ -4,6 +4,7 @@ plugins {
id 'kotlin-kapt'
id 'com.google.dagger.hilt.android'
id 'realm-android'
id 'kotlin-parcelize' //
}
android {
namespace 'com.navinfo.omqs'
@ -11,7 +12,7 @@ android {
defaultConfig {
applicationId "com.navinfo.omqs"
minSdk 24
minSdk 26
targetSdk 33
versionCode 1
versionName "1.0"
@ -36,14 +37,17 @@ android {
viewBinding true
dataBinding true
}
}
dependencies {
implementation project(':collect-library')
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'com.google.android.material:material:1.8.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.navigation:navigation-fragment-ktx:2.5.3'
implementation 'androidx.navigation:navigation-ui-ktx:2.5.3'
@ -55,17 +59,26 @@ dependencies {
// https://github.com/K1rakishou/Fuck-Storage-Access-Framework
implementation 'com.github.K1rakishou:Fuck-Storage-Access-Framework:v1.1.3'
// Android工具类库 https://blankj.com/2016/07/31/android-utils-code/
implementation 'com.blankj:utilcodex:1.30.1'
implementation 'com.blankj:utilcodex:1.31.1'
//
//hilt
implementation "com.google.dagger:hilt-android:2.44"
kapt "com.google.dagger:hilt-compiler:2.44"
implementation 'com.google.dagger:hilt-android:2.45'
kapt 'com.google.dagger:hilt-compiler:2.45'
// Retrofit
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("com.squareup.okhttp3:okhttp:4.9.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.9.0")
implementation('com.squareup.okhttp3:okhttp:5.0.0-alpha.11')
implementation('com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.11')
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"
//excel word等文件
implementation 'org.apache.poi:poi:5.2.3'
implementation 'org.apache.poi:poi-ooxml:5.2.3'
}
//
kapt {

View File

@ -5,6 +5,7 @@ import android.util.Log
import com.navinfo.omqs.tools.FileManager
import dagger.hilt.android.HiltAndroidApp
import io.realm.Realm
import io.realm.RealmConfiguration
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.io.File
@ -12,7 +13,17 @@ import java.io.File
@HiltAndroidApp
class OMQSApplication : Application() {
override fun onCreate() {
FileManager.initRootDir(this)
super.onCreate()
FileManager.initRootDir(this)
Realm.init(this)
val password = "password".encodeToByteArray().copyInto(ByteArray(64))
// 1110000011000010111001101110011011101110110111101110010011001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// Log.d("", "密码是: ${BigInteger(1, password).toString(2).padStart(64, '0')}")
val config = RealmConfiguration.Builder()
.directory(File(Constant.DATA_PATH))
.name("HDData")
// .encryptionKey(password)
.build()
Realm.setDefaultConfiguration(config)
}
}

View File

@ -0,0 +1,6 @@
package com.navinfo.omqs.bean
import java.io.Serializable
open class BaseBean : Serializable, Cloneable {
}

View File

@ -0,0 +1,57 @@
package com.navinfo.omqs.bean
import android.os.Parcelable
import androidx.room.Entity
import androidx.room.PrimaryKey
import kotlinx.parcelize.Parcelize
@Entity(tableName = "OfflineMapCity")
@Parcelize
data 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
) : Parcelable {
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)
}
}

View File

@ -0,0 +1,115 @@
package com.navinfo.omqs.bean
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
/**
* @author zhjch
* @version V1.0
* @ClassName: Rd_qcRecord
* @Date 2016/1/12
* @Description: ${TODO}(质检对象)
*/
open class QsRecord @JvmOverloads constructor(
/**
* id 主键
*
*/
@PrimaryKey var id: String = "",
/**
* linkPid 绑定的道路ID
*/
var linkPid: String = "",
/**
*问题分类
*/
var classType: String = "",
/**
* 问题类型
*/
var type: String = "",
/**
* 问题现象
*/
var phenomenon: String = "",
/**
* 问题描述
*/
var description: String = "",
/**
* 设置initial_cause
* @param initial_cause
* initial_cause
*/
// var initial_cause: String? = StringEntity.STRING_DEFAULT
// /**
// * 获取root_cause
// * @return root_cause
// */
// /**
// * 设置root_cause
// * @param root_cause
// * root_cause
// */
////根本原因RCA
// var root_cause: String? = StringEntity.STRING_DEFAULT
// /**
// * 获取check_userid
// * @return check_userid
// */
// /**
// * 设置check_userid
// * @param check_userid
// * check_userid
// */
////质检员
// var check_userid: String? = StringEntity.STRING_DEFAULT
// /**
// * 获取check_time
// * @return check_time
// */
// /**
// * 设置check_time
// * @param check_time
// * check_time
// */
////质检日期
// var check_time: String? = StringEntity.STRING_DEFAULT
// /**
// * 获取confirm_userid
// * @return confirm_userid
// */
// /**
// * 设置confirm_userid
// * @param confirm_userid
// * confirm_userid
// */
////确认人
// var confirm_userid: String? = StringEntity.STRING_DEFAULT
// /**
// * 获取t_lifecycle
// * @return t_lifecycle
// */
// /**
// * 设置t_lifecycle
// * @param t_lifecycle
// * t_lifecycle
// */
////状态 0 无; 1 删除2 更新3 新增;
// var t_lifecycle = 0
// /**
// * 获取t_status
// * @return t_status
// */
// /**
// * 设置t_status
// * @param t_status
// * t_status
// */
////问题记录提交状态 0 未提交1 已提交;
// var t_status = 0
) : RealmObject(
)

View File

@ -0,0 +1,30 @@
package com.navinfo.omqs.bean
import android.os.Parcelable
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import kotlinx.parcelize.Parcelize
@Entity(tableName = "ScProblemType")
@Parcelize
data class ScProblemTypeBean(
@PrimaryKey(autoGenerate = true)
var id: Long = 0,
/**
* 问题分类
*/
@ColumnInfo("CLASS_TYPE")
var classType: String = "",
/**
* 问题类型
*/
@ColumnInfo("TYPE")
var problemType: String = "",
/**
* 问题现象
*/
@ColumnInfo("PHENOMENON")
var phenomenon: String = ""
) : Parcelable

View File

@ -0,0 +1,24 @@
package com.navinfo.omqs.bean
import android.os.Parcelable
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import kotlinx.parcelize.Parcelize
@Entity(tableName = "ScRootCauseAnalysis")
@Parcelize
data class ScRootCauseAnalysisBean(
@PrimaryKey(autoGenerate = true)
var id: Long = 0,
/**
* 问题环节
*/
@ColumnInfo("PROBLEM_LINK")
var problemLink: String = "",
/**
* 问题原因
*/
@ColumnInfo("PROBLEM_CAUSE")
var problemCause: String = "",
) : Parcelable

View File

@ -0,0 +1,21 @@
package com.navinfo.omqs.db
import androidx.room.Database
import androidx.room.RoomDatabase
import com.navinfo.omqs.bean.OfflineMapCityBean
import com.navinfo.omqs.bean.ScProblemTypeBean
import com.navinfo.omqs.bean.ScRootCauseAnalysisBean
import com.navinfo.omqs.db.dao.OfflineMapDao
import com.navinfo.omqs.db.dao.ScProblemTypeDao
import com.navinfo.omqs.db.dao.ScRootCauseAnalysisDao
@Database(
entities = [OfflineMapCityBean::class, ScProblemTypeBean::class, ScRootCauseAnalysisBean::class],
version = 1,
exportSchema = false
)
abstract class RoomAppDatabase : RoomDatabase() {
abstract fun getOfflineMapDao(): OfflineMapDao
abstract fun getScProblemTypeDao(): ScProblemTypeDao
abstract fun getScRootCauseAnalysisDao(): ScRootCauseAnalysisDao
}

View File

@ -0,0 +1,23 @@
package com.navinfo.omqs.db.dao
import androidx.room.*
import com.navinfo.omqs.bean.OfflineMapCityBean
@Dao
interface OfflineMapDao {
@Insert
suspend fun insert(message: OfflineMapCityBean): Long
@Update(onConflict = OnConflictStrategy.REPLACE)
suspend fun update(message: OfflineMapCityBean)
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertOrUpdate(list: List<OfflineMapCityBean>)
@Query("select * from OfflineMapCity order by id")
suspend fun getOfflineMapList(): List<OfflineMapCityBean>
@Query("select * from OfflineMapCity where status != 0 order by id")
suspend fun getOfflineMapListWithOutNone(): List<OfflineMapCityBean>
}

View File

@ -0,0 +1,50 @@
package com.navinfo.omqs.db.dao
import androidx.room.*
import androidx.sqlite.db.SupportSQLiteDatabase
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase.getDatabase
import com.navinfo.omqs.bean.ScProblemTypeBean
@Dao
interface ScProblemTypeDao {
// @Insert(onConflict = OnConflictStrategy.REPLACE)
// suspend fun insert(bean: ScProblemTypeBean): Long
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertList(list: List<ScProblemTypeBean>)
@Query("delete from ScProblemType")
suspend fun deleteAll()
/**
* 更新整个数据库表由于没有
*/
@Transaction
suspend fun insertOrUpdateList(list: List<ScProblemTypeBean>) {
//先删除
deleteAll()
//后插入
insertList(list)
}
/**
* 获取问题分类并去重
*/
@Query("select DISTINCT CLASS_TYPE from ScProblemType order by CLASS_TYPE")
suspend fun findClassTypeList(): List<String>?
/**
* 获取问题类型并去重
*/
@Query("select DISTINCT TYPE from ScProblemType where CLASS_TYPE=:type order by TYPE")
suspend fun findProblemTypeList(type: String): List<String>
/**
*
*/
@Query("select PHENOMENON from ScProblemType where CLASS_TYPE=:classType and TYPE=:type order by PHENOMENON")
suspend fun getPhenomenonList(classType: String, type: String): List<String>
}

View File

@ -0,0 +1,25 @@
package com.navinfo.omqs.db.dao
import androidx.room.*
import com.navinfo.omqs.bean.ScRootCauseAnalysisBean
@Dao
interface ScRootCauseAnalysisDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertList(list: List<ScRootCauseAnalysisBean>)
@Query("delete from ScRootCauseAnalysis")
suspend fun deleteAll()
@Transaction
suspend fun insertOrUpdateList(list: List<ScRootCauseAnalysisBean>) {
//先删除
deleteAll()
//后插入
insertList(list)
}
}

View File

@ -1,12 +1,16 @@
package com.navinfo.omqs.hilt
import android.app.Application
import android.content.Context
import android.util.Log
import androidx.room.Room
import com.google.gson.Gson
import com.navinfo.omqs.Constant
import com.navinfo.omqs.OMQSApplication
import com.navinfo.omqs.db.RoomAppDatabase
import com.navinfo.omqs.http.RetrofitNetworkServiceAPI
import com.navinfo.omqs.tools.RealmCoroutineScope
import com.tencent.wcdb.database.SQLiteCipherSpec
import com.tencent.wcdb.room.db.WCDBOpenHelperFactory
import dagger.Lazy
import dagger.Module
import dagger.Provides
@ -95,12 +99,41 @@ class GlobalModule {
return retrofit.create(RetrofitNetworkServiceAPI::class.java)
}
/**
* realm 注册
*/
@Provides
@Singleton
fun provideRealmService(context: Application): RealmCoroutineScope {
return RealmCoroutineScope(context)
@Provides
fun provideDatabase(context: Application): RoomAppDatabase {
val DB_PASSWORD = "123456";
val cipherSpec = SQLiteCipherSpec()
.setPageSize(1024)
.setSQLCipherVersion(3)
val factory = WCDBOpenHelperFactory()
// .passphrase(DB_PASSWORD.toByteArray()) // 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
return Room.databaseBuilder(
context,
RoomAppDatabase::class.java,
"${Constant.DATA_PATH}/omqs.db"
)
// [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();
}
// /**
// * realm 注册
// */
// @Provides
// @Singleton
// fun provideRealmService(context: Application): RealmCoroutineScope {
// return RealmCoroutineScope(context)
// }
}

View File

@ -1,9 +1,9 @@
package com.navinfo.omqs.hilt
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.omqs.db.RoomAppDatabase
import com.navinfo.omqs.http.RetrofitNetworkServiceAPI
import com.navinfo.omqs.http.offlinemapdownload.OfflineMapDownloadManager
import com.navinfo.omqs.tools.RealmCoroutineScope
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@ -28,9 +28,10 @@ class MainActivityModule {
@Provides
fun providesOfflineMapDownloadManager(
networkServiceAPI: RetrofitNetworkServiceAPI,
realmManager: RealmCoroutineScope
roomAppDatabase: RoomAppDatabase,
mapController: NIMapController
): OfflineMapDownloadManager =
OfflineMapDownloadManager(networkServiceAPI, realmManager)
OfflineMapDownloadManager(networkServiceAPI, roomAppDatabase, mapController)
/**
* 实验失败这样创建viewmodel不会在activity销毁的时候同时销毁

View File

@ -1,6 +1,6 @@
package com.navinfo.omqs.http
import com.navinfo.collect.library.data.entity.OfflineMapCityBean
import com.navinfo.omqs.bean.OfflineMapCityBean
/**

View File

@ -1,6 +1,6 @@
package com.navinfo.omqs.http
import com.navinfo.collect.library.data.entity.OfflineMapCityBean
import com.navinfo.omqs.bean.OfflineMapCityBean
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import javax.inject.Inject

View File

@ -1,6 +1,6 @@
package com.navinfo.omqs.http
import com.navinfo.collect.library.data.entity.OfflineMapCityBean
import com.navinfo.omqs.bean.OfflineMapCityBean
import okhttp3.ResponseBody
import retrofit2.Response
import retrofit2.http.GET

View File

@ -2,16 +2,19 @@ package com.navinfo.omqs.http.offlinemapdownload
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.Observer
import com.navinfo.collect.library.data.entity.OfflineMapCityBean
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.omqs.db.RoomAppDatabase
import com.navinfo.omqs.bean.OfflineMapCityBean
import com.navinfo.omqs.http.RetrofitNetworkServiceAPI
import com.navinfo.omqs.tools.RealmCoroutineScope
import java.util.concurrent.ConcurrentHashMap
/**
* 管理离线地图下载
*/
class OfflineMapDownloadManager(
val netApi: RetrofitNetworkServiceAPI, val realmManager: RealmCoroutineScope
val netApi: RetrofitNetworkServiceAPI,
val roomDatabase: RoomAppDatabase,
val mapController: NIMapController
) {
/**
* 最多同时下载数量

View File

@ -4,8 +4,8 @@ import android.util.Log
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import com.navinfo.collect.library.data.entity.OfflineMapCityBean
import com.navinfo.omqs.Constant
import com.navinfo.omqs.bean.OfflineMapCityBean
import kotlinx.coroutines.*
import java.io.File
import java.io.IOException
@ -32,8 +32,8 @@ class OfflineMapDownloadScope(
/**
* 管理观察者同时只有一个就行了
*/
// private var observer: Observer<OfflineMapCityBean>? = null
private var lifecycleOwner: LifecycleOwner? = null
private val observer = Observer<Any> {}
// private var lifecycleOwner: LifecycleOwner? = null
/**
*通知UI更新
@ -89,10 +89,10 @@ class OfflineMapDownloadScope(
if (cityBean.status != status || status == OfflineMapCityBean.LOADING) {
cityBean.status = status
downloadData.postValue(cityBean)
downloadManager.realmManager.launch {
downloadManager.realmManager.insertOrUpdate(cityBean)
launch(Dispatchers.IO) {
downloadManager.roomDatabase.getOfflineMapDao().update(cityBean)
}
}
}
@ -101,7 +101,7 @@ class OfflineMapDownloadScope(
*/
fun observer(owner: LifecycleOwner, ob: Observer<OfflineMapCityBean>) {
removeObserver()
this.lifecycleOwner = owner
// this.lifecycleOwner = owner
downloadData.observe(owner, ob)
}
@ -156,6 +156,9 @@ class OfflineMapDownloadScope(
fileTemp.renameTo(File("${Constant.OFFLINE_MAP_PATH}${cityBean.fileName}"))
Log.e("jingo", "文件下载完成 修改文件 $res")
change(OfflineMapCityBean.DONE)
withContext(Dispatchers.Main) {
downloadManager.mapController.layerManagerHandler.loadBaseMap()
}
} else {
change(OfflineMapCityBean.PAUSE)
}
@ -168,9 +171,10 @@ class OfflineMapDownloadScope(
}
fun removeObserver() {
lifecycleOwner?.let {
downloadData.removeObservers(it)
null
}
downloadData.observeForever(observer)
// lifecycleOwner?.let {
downloadData.removeObserver(observer)
// null
// }
}
}

View File

@ -1,9 +1,8 @@
package com.navinfo.omqs.tools
import android.content.Context
import android.util.Log
import com.navinfo.collect.library.data.entity.OfflineMapCityBean
import com.navinfo.omqs.Constant
import com.navinfo.omqs.bean.OfflineMapCityBean
import java.io.File
class FileManager {

View File

@ -1,57 +1,47 @@
package com.navinfo.omqs.tools
import android.app.Application
import com.navinfo.collect.library.data.entity.OfflineMapCityBean
import com.navinfo.omqs.Constant
import io.realm.Realm
import io.realm.RealmConfiguration
import io.realm.RealmModel
import io.realm.Sort
import io.realm.kotlin.where
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.newSingleThreadContext
import java.io.File
class RealmCoroutineScope(context: Application) :
CoroutineScope by CoroutineScope(newSingleThreadContext("RealmThread")) {
lateinit var realm: Realm
init {
launch {
Realm.init(context)
val password = "password".encodeToByteArray().copyInto(ByteArray(64))
// 1110000011000010111001101110011011101110110111101110010011001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// Log.d("", "密码是: ${BigInteger(1, password).toString(2).padStart(64, '0')}")
val config = RealmConfiguration.Builder()
.directory(File(Constant.DATA_PATH))
.name("HDData")
// .encryptionKey(password)
.build()
Realm.setDefaultConfiguration(config)
realm = Realm.getDefaultInstance()
}
}
suspend fun getOfflineCityList(): List<OfflineMapCityBean> {
var list: List<OfflineMapCityBean> = mutableListOf()
realm.executeTransaction {
val objects = realm.where<OfflineMapCityBean>().findAll().sort("id", Sort.ASCENDING)
list = realm.copyFromRealm(objects)
}
return list
}
suspend fun insertOrUpdate(objects: Collection<RealmModel?>?) {
realm.executeTransaction {
realm.insertOrUpdate(objects)
}
}
suspend fun insertOrUpdate(realmModel: RealmModel?) {
realm.executeTransaction {
realm.insertOrUpdate(realmModel)
}
}
}
//package com.navinfo.omqs.tools
//
//import android.app.Application
//import com.navinfo.collect.library.data.entity.OfflineMapCityBean
//import com.navinfo.omqs.Constant
//import io.realm.Realm
//import io.realm.RealmConfiguration
//import io.realm.RealmModel
//import io.realm.Sort
//import io.realm.kotlin.where
//import kotlinx.coroutines.CoroutineScope
//import kotlinx.coroutines.launch
//import kotlinx.coroutines.newSingleThreadContext
//import java.io.File
//
//class RealmCoroutineScope(context: Application) :
// CoroutineScope by CoroutineScope(newSingleThreadContext("RealmThread")) {
// lateinit var realm: Realm
//
// init {
// launch {
// realm = Realm.getDefaultInstance()
// }
// }
//
// suspend fun getOfflineCityList(): List<OfflineMapCityBean> {
// var list: List<OfflineMapCityBean> = mutableListOf()
// realm.executeTransaction {
// val objects = realm.where<OfflineMapCityBean>().findAll().sort("id", Sort.ASCENDING)
// list = realm.copyFromRealm(objects)
// }
// return list
// }
//
// suspend fun insertOrUpdate(objects: Collection<RealmModel?>?) {
// realm.executeTransaction {
// realm.insertOrUpdate(objects)
// }
// }
//
// suspend fun insertOrUpdate(realmModel: RealmModel?) {
// realm.executeTransaction {
// realm.insertOrUpdate(realmModel)
// }
// }
//
//}

View File

@ -1,84 +0,0 @@
package com.navinfo.omqs.ui
import android.content.Intent
import android.os.Bundle
import androidx.core.view.WindowCompat
import androidx.navigation.ui.AppBarConfiguration
import com.github.k1rakishou.fsaf.FileChooser
import com.github.k1rakishou.fsaf.callback.FSAFActivityCallbacks
import com.navinfo.omqs.databinding.ActivityMainBinding
import com.navinfo.omqs.ui.activity.PermissionsActivity
class MainActivity : PermissionsActivity(), FSAFActivityCallbacks {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityMainBinding
private val fileChooser by lazy { FileChooser(this@MainActivity) }
override fun onCreate(savedInstanceState: Bundle?) {
WindowCompat.setDecorFitsSystemWindows(window, false)
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// val navController = findNavController(R.id.nav_host_fragment_content_main)
// appBarConfiguration = AppBarConfiguration(navController.graph)
// setupActionBarWithNavController(navController, appBarConfiguration)
fileChooser.setCallbacks(this@MainActivity)
// binding.fab.setOnClickListener { view ->
// Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
// .setAnchorView(R.id.fab)
// .setAction("Action", null).show()
// // 开始数据导入功能
// fileChooser.openChooseFileDialog(object: FileChooserCallback() {
// override fun onCancel(reason: String) {
// }
//
// override fun onResult(uri: Uri) {
// val file = UriUtils.uri2File(uri)
// Snackbar.make(view, "文件大小为:${file.length()}", Snackbar.LENGTH_LONG)
// .show()
// }
// })
// }
}
override fun onPermissionsGranted() {
}
override fun onPermissionsDenied() {
}
// override fun onCreateOptionsMenu(menu: Menu): Boolean {
// // Inflate the menu; this adds items to the action bar if it is present.
// menuInflater.inflate(R.menu.menu_main, menu)
// return true
// }
// override fun onOptionsItemSelected(item: MenuItem): Boolean {
// // Handle action bar item clicks here. The action bar will
// // automatically handle clicks on the Home/Up button, so long
// // as you specify a parent activity in AndroidManifest.xml.
// return when (item.itemId) {
// R.id.action_settings -> true
// else -> super.onOptionsItemSelected(item)
// }
// }
//
// override fun onSupportNavigateUp(): Boolean {
// val navController = findNavController(R.id.nav_host_fragment_content_main)
// return navController.navigateUp(appBarConfiguration)
// || super.onSupportNavigateUp()
// }
override fun fsafStartActivityForResult(intent: Intent, requestCode: Int) {
startActivityForResult(intent, requestCode)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
fileChooser.onActivityResult(requestCode, resultCode, data)
}
}

View File

@ -8,10 +8,10 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.navinfo.omqs.bean.LoginUserBean
import com.navinfo.omqs.db.RoomAppDatabase
import com.navinfo.omqs.http.NetResult
import com.navinfo.omqs.http.NetworkService
import com.navinfo.omqs.tools.FileManager
import com.navinfo.omqs.tools.RealmCoroutineScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.*
import okio.IOException
@ -57,7 +57,7 @@ enum class LoginStatus {
@HiltViewModel
class LoginViewModel @Inject constructor(
private val networkService: NetworkService,
private val realmManager: RealmCoroutineScope
private val roomAppDatabase: RoomAppDatabase
) : ViewModel() {
//用户信息
val loginUser: MutableLiveData<LoginUserBean> = MutableLiveData()
@ -126,9 +126,7 @@ class LoginViewModel @Inject constructor(
for (cityBean in result.data) {
FileManager.checkOfflineMapFileInfo(cityBean)
}
realmManager.launch {
realmManager.insertOrUpdate(result.data)
}
roomAppDatabase.getOfflineMapDao().insertOrUpdate(result.data)
}
}
is NetResult.Error -> {

View File

@ -7,6 +7,7 @@ import androidx.activity.viewModels
import androidx.core.view.WindowCompat
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.viewModelScope
import androidx.navigation.findNavController
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.omqs.Constant
import com.navinfo.omqs.R
@ -28,6 +29,7 @@ class MainActivity : BaseActivity() {
//注入地图控制器
@Inject
lateinit var mapController: NIMapController
@Inject
lateinit var offlineMapDownloadManager: OfflineMapDownloadManager
@ -39,9 +41,9 @@ class MainActivity : BaseActivity() {
//初始化地图
mapController.init(
this,
binding.mapView.mainActivityMap,
binding.mainActivityMap,
null,
Constant.ROOT_PATH + "/map/"
Constant.MAP_PATH
)
//关联生命周期
binding.lifecycleOwner = this
@ -83,4 +85,11 @@ class MainActivity : BaseActivity() {
binding.mainActivityDrawer.open()
}
/**
* 点击录音按钮
*/
fun voiceOnclick() {
val naviController = findNavController(R.id.main_activity_right_fragment)
naviController.navigate(R.id.EvaluationResultFragment)
}
}

View File

@ -0,0 +1,32 @@
package com.navinfo.omqs.ui.fragment.empty
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.navinfo.omqs.databinding.FragmentEmptyBinding
class EmptyFragment :Fragment(){
private var _binding: FragmentEmptyBinding? = null
private val binding get() = _binding!!
// private val viewModel by lazy { viewModels<EvaluationResultViewModel>().value}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentEmptyBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@ -0,0 +1,16 @@
package com.navinfo.omqs.ui.fragment.evaluationresult
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
class EvaluationResultAdapter(activity: FragmentActivity, val fragmentList: List<Fragment>) :
FragmentStateAdapter(activity) {
override fun getItemCount(): Int {
return fragmentList.size
}
override fun createFragment(position: Int): Fragment {
return fragmentList[position]
}
}

View File

@ -0,0 +1,131 @@
package com.navinfo.omqs.ui.fragment.evaluationresult
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayoutMediator
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.FragmentEvaluationResultBinding
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class EvaluationResultFragment : Fragment() {
private var _binding: FragmentEvaluationResultBinding? = null
private val binding get() = _binding!!
private val viewModel by lazy { viewModels<EvaluationResultViewModel>().value }
private var phenomenonFragmentAdapter: EvaluationResultAdapter? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
_binding = FragmentEvaluationResultBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//返回按钮
binding.evaluationBar.setNavigationOnClickListener {
findNavController().popBackStack()
}
//监听数据变化
viewModel.classTypeListLiveData.observe(viewLifecycleOwner) {
if (it == null || it.isEmpty()) {
Toast.makeText(requireContext(), "还没有导入元数据!", Toast.LENGTH_SHORT).show()
} else {
binding.evaluationClassType.adapter =
ArrayAdapter(requireContext(), R.layout.text_item_select, it)
}
}
//选择问题分类的回调
binding.evaluationClassType.onItemSelectedListener =
object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(
parent: AdapterView<*>?, view: View?, position: Int, id: Long
) {
viewModel.getProblemTypeList(position)
}
override fun onNothingSelected(parent: AdapterView<*>?) {}
}
/**
* 监听联动选择的内容
*/
viewModel.problemTypeListLiveData.observe(viewLifecycleOwner) {
binding.evaluationClassTabLayout.let { tabLayout ->
tabLayout.removeAllTabs()
val fragmentList = mutableListOf<Fragment>()
for (item in it) {
val tab = tabLayout.newTab()
tab.text = item
tabLayout.addTab(tab)
fragmentList.add(PhenomenonFragment(viewModel.currentClassType,item))
}
phenomenonFragmentAdapter =
activity?.let { a -> EvaluationResultAdapter(a, fragmentList) }
binding.evaluationViewpager.adapter = phenomenonFragmentAdapter
TabLayoutMediator(
binding.evaluationClassTabLayout,
binding.evaluationViewpager
) { tab, position ->
tab.text = it[position]
}.attach()
updateHeight(0)
}
}
//获取数据
viewModel.getClassTypeList()
binding.evaluationViewpager.registerOnPageChangeCallback(object :
ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
updateHeight(position)
}
})
}
private fun updateHeight(position: Int) {
phenomenonFragmentAdapter?.let {
if (it.fragmentList.size > position) {
val fragment: Fragment = it.fragmentList[position]
if (fragment.view != null) {
val viewWidth = View.MeasureSpec.makeMeasureSpec(
fragment.requireView().width, View.MeasureSpec.EXACTLY
)
val viewHeight =
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
fragment.requireView().measure(viewWidth, viewHeight)
binding.evaluationViewpager.let { viewpager ->
if (viewpager.layoutParams.height != fragment.requireView().measuredHeight) {
//必须要用对象去接收,然后修改该对象再采用该对象,否则无法生效...
val layoutParams: ViewGroup.LayoutParams =
viewpager.layoutParams
layoutParams.height = fragment.requireView().measuredHeight
viewpager.layoutParams = layoutParams
}
}
}
}
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@ -0,0 +1,73 @@
package com.navinfo.omqs.ui.fragment.evaluationresult
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.navinfo.omqs.db.RoomAppDatabase
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okhttp3.Dispatcher
import javax.inject.Inject
@HiltViewModel
class EvaluationResultViewModel @Inject constructor(
private val roomAppDatabase: RoomAppDatabase,
) : ViewModel() {
init {
Log.e("jingo", "EvaluationResultViewModel 创建了 ${hashCode()}")
}
override fun onCleared() {
super.onCleared()
Log.e("jingo", "EvaluationResultViewModel 销毁了 ${hashCode()}")
}
/**
* 问题分类 liveData
*/
val classTypeListLiveData = MutableLiveData<List<String>?>()
/**
* 问题类型 liveData
*/
val problemTypeListLiveData = MutableLiveData<List<String>>()
var currentClassType: String = ""
/**
* 查询数据库获取问题分类
*/
fun getClassTypeList() {
viewModelScope.launch(Dispatchers.IO) {
val list = roomAppDatabase.getScProblemTypeDao().findClassTypeList()
classTypeListLiveData.postValue(list)
}
}
/**
* 查询问题类型
*/
fun getProblemTypeList(index: Int) {
viewModelScope.launch(Dispatchers.IO) {
classTypeListLiveData.value?.let {
if (index < it.size) {
currentClassType = it[index]
val list =
roomAppDatabase.getScProblemTypeDao().findProblemTypeList(currentClassType)
problemTypeListLiveData.postValue(list)
}
}
}
}
fun getPhenomenonList() {
viewModelScope.launch (Dispatchers.IO){
}
}
}

View File

@ -0,0 +1,24 @@
package com.navinfo.omqs.ui.fragment.evaluationresult
import android.view.LayoutInflater
import android.view.ViewGroup
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.TextItemSelectBinding
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
import com.navinfo.omqs.ui.other.BaseViewHolder
class PhenomenonAdapter() : BaseRecyclerViewAdapter<String>() {
override fun getItemViewRes(position: Int): Int {
return R.layout.text_item_select
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
val viewBinding =
TextItemSelectBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return BaseViewHolder(viewBinding)
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
(holder.viewBinding as TextItemSelectBinding).itemId.text = data[position]
}
}

View File

@ -0,0 +1,59 @@
package com.navinfo.omqs.ui.fragment.evaluationresult
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.navinfo.omqs.databinding.FragmentPhenomenonBinding
import com.navinfo.omqs.db.RoomAppDatabase
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import javax.inject.Inject
@AndroidEntryPoint
class PhenomenonFragment(private val classType: String, private val title: String) :
Fragment() {
@Inject
lateinit var roomAppDatabase: RoomAppDatabase
private var _binding: FragmentPhenomenonBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentPhenomenonBinding.inflate(inflater, container, false)
Log.e("jingo", "PhenomenonFragment onCreateView ${hashCode()}")
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.phenomenonRecyclerview.setHasFixedSize(true)
binding.phenomenonRecyclerview.layoutManager = LinearLayoutManager(context)
val adapter = PhenomenonAdapter()
binding.phenomenonRecyclerview.adapter = adapter
lifecycleScope.launch {
Log.e("jingo", "$classType $title ")
val list = roomAppDatabase.getScProblemTypeDao().getPhenomenonList(classType, title)
Log.e("jingo", "${list.toString()}")
adapter.refreshData(list)
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
Log.e("jingo", "PhenomenonFragment onDestroyView ${hashCode()}")
}
override fun onResume() {
super.onResume()
}
}

View File

@ -3,7 +3,6 @@ package com.navinfo.omqs.ui.fragment.offlinemap
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
import dagger.hilt.EntryPoint
/**
* 离线地图主页面viewpage适配器

View File

@ -6,9 +6,9 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.Observer
import com.navinfo.collect.library.data.entity.OfflineMapCityBean
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.AdapterOfflineMapCityBinding
import com.navinfo.omqs.bean.OfflineMapCityBean
import com.navinfo.omqs.http.offlinemapdownload.OfflineMapDownloadManager
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
import com.navinfo.omqs.ui.other.BaseViewHolder
@ -22,7 +22,7 @@ import javax.inject.Inject
*使用 LiveData observeForever 然后在 ViewHolder 销毁前手动调用 removeObserver
*使用 LifecycleRegistry ViewHolder 分发生命周期(这里使用了这个)
*/
class OfflineMapCityListAdapter @Inject constructor(
class OfflineMapCityListAdapter(
private val downloadManager: OfflineMapDownloadManager, private val context: Context
) : BaseRecyclerViewAdapter<OfflineMapCityBean>() {
@ -126,7 +126,7 @@ class OfflineMapCityListAdapter @Inject constructor(
}
}
override fun getItemViewType(position: Int): Int {
override fun getItemViewRes(position: Int): Int {
return R.layout.adapter_offline_map_city
}
}

View File

@ -4,14 +4,10 @@ import android.content.Context
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.navinfo.collect.library.data.entity.OfflineMapCityBean
import com.navinfo.omqs.tools.FileManager
import com.navinfo.omqs.tools.RealmCoroutineScope
import com.navinfo.omqs.db.RoomAppDatabase
import com.navinfo.omqs.bean.OfflineMapCityBean
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import io.realm.Realm
import io.realm.Sort
import io.realm.kotlin.where
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import javax.inject.Inject
@ -22,6 +18,7 @@ import javax.inject.Inject
@HiltViewModel
class OfflineMapCityListViewModel @Inject constructor(
@ApplicationContext val context: Context,
private val roomDatabase: RoomAppDatabase
) : ViewModel() {
val cityListLiveData = MutableLiveData<List<OfflineMapCityBean>>()
@ -31,13 +28,14 @@ class OfflineMapCityListViewModel @Inject constructor(
*/
fun getCityList() {
viewModelScope.launch(Dispatchers.IO) {
val realm = Realm.getDefaultInstance()
val objects = realm.where<OfflineMapCityBean>().findAll().sort("id", Sort.ASCENDING)
val list = realm.copyFromRealm(objects)
realm.close()
for (item in list) {
FileManager.checkOfflineMapFileInfo(item)
}
// val realm = Realm.getDefaultInstance()
// val objects = realm.where<OfflineMapCityBean>().findAll().sort("id", Sort.ASCENDING)
// val list = realm.copyFromRealm(objects)
// realm.close()
// for (item in list) {
// FileManager.checkOfflineMapFileInfo(item)
// }
val list = roomDatabase.getOfflineMapDao().getOfflineMapList()
cityListLiveData.postValue(list)
}
}

View File

@ -1,23 +1,16 @@
package com.navinfo.omqs.ui.fragment.offlinemap
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayout.OnTabSelectedListener
import com.google.android.material.tabs.TabLayoutMediator
import com.navinfo.omqs.databinding.FragmentOfflineMapBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/**
* 离线地图
* 离线地图总页面
*/
class OfflineMapFragment : Fragment() {

View File

@ -6,16 +6,33 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.navinfo.omqs.databinding.FragmentOfflineMapBinding
import androidx.fragment.app.viewModels
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.recyclerview.widget.LinearLayoutManager
import com.navinfo.omqs.databinding.FragmentOfflineMapStateListBinding
import com.navinfo.omqs.http.offlinemapdownload.OfflineMapDownloadManager
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
/**
* 离线地图管理页面
*/
@AndroidEntryPoint
class OfflineMapStateListFragment : Fragment() {
@Inject
lateinit var downloadManager: OfflineMapDownloadManager
private var _binding: FragmentOfflineMapStateListBinding? = null
private val viewModel by viewModels<OfflineMapStateListViewModel>()
private val binding get() = _binding!!
private val adapter: OfflineMapCityListAdapter by lazy {
OfflineMapCityListAdapter(
downloadManager,
requireContext()
)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
@ -27,11 +44,24 @@ class OfflineMapStateListFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val layoutManager = LinearLayoutManager(context)
//// 设置 RecyclerView 的固定大小,避免在滚动时重新计算视图大小和布局,提高性能
binding.offlineMapCityStateListRecyclerview.setHasFixedSize(true)
binding.offlineMapCityStateListRecyclerview.layoutManager = layoutManager
binding.offlineMapCityStateListRecyclerview.adapter = adapter
viewModel.cityListLiveData.observe(viewLifecycleOwner) {
adapter.refreshData(it)
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onResume() {
super.onResume()
viewModel.getCityList()
}
}

View File

@ -0,0 +1,40 @@
package com.navinfo.omqs.ui.fragment.offlinemap
import android.content.Context
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.navinfo.omqs.db.RoomAppDatabase
import com.navinfo.omqs.bean.OfflineMapCityBean
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import javax.inject.Inject
/**
* 离线地图城市列表viewModel
*/
@HiltViewModel
class OfflineMapStateListViewModel @Inject constructor(
@ApplicationContext val context: Context,
private val roomDatabase: RoomAppDatabase
) : ViewModel() {
val cityListLiveData = MutableLiveData<List<OfflineMapCityBean>>()
/**
* 去获取正在下载或 已经下载的离线地图列表
*/
fun getCityList() {
viewModelScope.launch(Dispatchers.IO) {
val list = roomDatabase.getOfflineMapDao().getOfflineMapListWithOutNone()
if (cityListLiveData.value != null) {
if (cityListLiveData.value!!.size != list.size)
cityListLiveData.postValue(list)
}else{
cityListLiveData.postValue(list)
}
}
}
}

View File

@ -1,10 +0,0 @@
package com.navinfo.omqs.ui.fragment.offlinemap
import com.navinfo.omqs.databinding.AdapterOfflineMapCityBinding
import com.navinfo.omqs.ui.other.BaseViewHolder
class OfflineMapViewHolder(dataBinding: AdapterOfflineMapCityBinding) : BaseViewHolder(dataBinding) {
init{
dataBinding.offlineMapDownloadBtn
}
}

View File

@ -15,10 +15,12 @@ import com.github.k1rakishou.fsaf.callback.FSAFActivityCallbacks
import com.github.k1rakishou.fsaf.callback.FileChooserCallback
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.FragmentPersonalCenterBinding
import dagger.hilt.android.AndroidEntryPoint
/**
* 个人中心
*/
@AndroidEntryPoint
class PersonalCenterFragment : Fragment(), FSAFActivityCallbacks {
private var _binding: FragmentPersonalCenterBinding? = null
@ -54,6 +56,18 @@ class PersonalCenterFragment : Fragment(), FSAFActivityCallbacks {
}
})
}
R.id.personal_center_menu_import_yuan_data->{
// 用户选中导入数据,打开文件选择器,用户选择导入的数据文件目录
fileChooser.openChooseFileDialog(object: FileChooserCallback() {
override fun onCancel(reason: String) {
}
override fun onResult(uri: Uri) {
viewModel.importScProblemData(uri)
}
})
}
}
true
}

View File

@ -1,16 +1,89 @@
package com.navinfo.omqs.ui.fragment.personalcenter
import android.net.Uri
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.blankj.utilcode.util.UriUtils
import com.navinfo.omqs.bean.ScProblemTypeBean
import com.navinfo.omqs.bean.ScRootCauseAnalysisBean
import com.navinfo.omqs.db.RoomAppDatabase
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.apache.poi.ss.usermodel.Cell
import org.apache.poi.ss.usermodel.Row
import org.apache.poi.ss.usermodel.Sheet
import org.apache.poi.ss.usermodel.WorkbookFactory
import java.io.File
import java.io.FileInputStream
import java.io.IOException
import java.io.InputStream
import javax.inject.Inject
class PersonalCenterViewModel: ViewModel() {
@HiltViewModel
class PersonalCenterViewModel @Inject constructor(
private val roomAppDatabase: RoomAppDatabase
) : ViewModel() {
fun importOmdbData(omdbFile: File) {
// 检查File是否为sqlite数据库
if (omdbFile == null || omdbFile.exists()) {
if (omdbFile == null || !omdbFile.exists()) {
throw Exception("文件不存在")
}
if (!omdbFile.name.endsWith(".sqlite") and !omdbFile.name.endsWith("db")) {
throw Exception("文件不存在")
}
}
fun importScProblemData(uri: Uri) {
viewModelScope.launch(Dispatchers.IO) {
try {
val file = UriUtils.uri2File(uri)
val inputStream: InputStream =
FileInputStream(file) //getAssets().open("sample.xlsx")
val workbook = WorkbookFactory.create(inputStream)
//获取所有sheet
val sheet1 = workbook.getSheet("SC_PROBLEM_TYPE")
sheet1?.let {
val rowCount: Int = it.physicalNumberOfRows // 获取行数
val list = mutableListOf<ScProblemTypeBean>()
for (i in 1 until rowCount) {
val row: Row = it.getRow(i) // 获取行
val cellCount: Int = row.physicalNumberOfCells // 获取列数
if (cellCount == 3) {
val bean = ScProblemTypeBean()
bean.classType = row.getCell(0).stringCellValue
bean.problemType = row.getCell(1).stringCellValue
bean.phenomenon = row.getCell(2).stringCellValue
list.add(bean)
Log.e("jingo", bean.toString())
}
}
roomAppDatabase.getScProblemTypeDao().insertOrUpdateList(list)
}
val sheet2 = workbook.getSheet("SC_ROOT_CAUSE_ANALYSIS")
sheet2?.let {
val rowCount: Int = it.physicalNumberOfRows // 获取行数
val list = mutableListOf<ScRootCauseAnalysisBean>()
for (i in 1 until rowCount) {
val row: Row = it.getRow(i) // 获取行
val cellCount: Int = row.physicalNumberOfCells // 获取列数
if (cellCount == 2) {
val bean = ScRootCauseAnalysisBean()
bean.problemLink = row.getCell(0).stringCellValue
bean.problemCause = row.getCell(1).stringCellValue
list.add(bean)
Log.e("jingo", bean.toString())
}
}
roomAppDatabase.getScRootCauseAnalysisDao().insertOrUpdateList(list)
}
workbook.close()
} catch (e: IOException) {
e.printStackTrace()
Log.e("jingo", e.toString())
}
}
}
}

View File

@ -5,6 +5,7 @@ import android.view.View.OnClickListener
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.navinfo.omqs.R
/**
* RecyclerView 适配器基础类
@ -26,6 +27,11 @@ abstract class BaseRecyclerViewAdapter<T>(var data: List<T> = listOf()) :
// )
// }
abstract fun getItemViewRes(position: Int): Int
override fun getItemViewType(position: Int): Int {
return getItemViewRes(position)
}
override fun getItemCount(): Int {
return data.size

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#100F0F"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2L18,7L6,7v12zM8.46,11.88l1.41,-1.41L12,12.59l2.12,-2.12 1.41,1.41L13.41,14l2.12,2.12 -1.41,1.41L12,15.41l-2.12,2.12 -1.41,-1.41L10.59,14l-2.13,-2.12zM15.5,4l-1,-1h-5l-1,1L5,4v2h14L19,4z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#18FD00"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,15c1.66,0 2.99,-1.34 2.99,-3L15,6c0,-1.66 -1.34,-3 -3,-3S9,4.34 9,6v6c0,1.66 1.34,3 3,3zM17.3,12c0,3 -2.54,5.1 -5.3,5.1S6.7,15 6.7,12L5,12c0,3.42 2.72,6.23 6,6.72L11,22h2v-3.28c3.28,-0.48 6,-3.3 6,-6.72h-1.7z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#100F0F"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M17,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,7l-4,-4zM12,19c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3zM15,9L5,9L5,5h10v4z"/>
</vector>

View File

@ -5,7 +5,6 @@
tools:context=".ui.activity.map.MainActivity">
<data>
<variable
name="mainActivity"
type="com.navinfo.omqs.ui.activity.map.MainActivity" />
@ -21,20 +20,65 @@
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<include
android:id="@+id/map_view"
layout="@layout/map_view"
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:mainActivity="@{mainActivity}"
app:viewModel="@{viewModel}" />
tools:context=".ui.activity.map.MainActivity">
<com.navinfo.collect.library.map.NIMapView
android:id="@+id/main_activity_map"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageButton
android:id="@+id/main_activity_person_center"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:onClick="@{()->mainActivity.openMenu()}"
android:src="@drawable/baseline_person_24"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/main_activity_location"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginLeft="20dp"
android:layout_marginBottom="80dp"
android:onClick="@{()->viewModel.onClickLocationButton()}"
android:src="@drawable/baseline_my_location_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
<ImageButton
android:id="@+id/main_activity_voice"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="120dp"
android:onClick="@{()->mainActivity.voiceOnclick()}"
android:src="@drawable/baseline_keyboard_voice_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<fragment
android:id="@+id/main_activity_right_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:layout_constraintHorizontal_bias="0.3"
app:layout_constraintRight_toRightOf="parent"
app:navGraph="@navigation/right_fragment_nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
<fragment
android:id="@+id/main_activity_fragment"
android:id="@+id/main_activity_drawer_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="left"
app:navGraph="@navigation/nav_graph" />
app:navGraph="@navigation/left_drawer_nav_graph" />
</androidx.drawerlayout.widget.DrawerLayout>
</layout>

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.navinfo.collect.library.map.NIMapView
android:id="@+id/main_activity_map1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:context=".ui.fragment.empty.EmptyFragment">
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".ui.fragment.evaluationresult.EvaluationResultFragment">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/evaluation_appbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/evaluation_bar"
style="@style/Widget.MaterialComponents.Toolbar.Surface"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/default_blue"
app:menu="@menu/evaluation_bar_mean"
app:navigationIcon="@drawable/btn_back_xml"
app:title="测评结果" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="10dp"
android:padding="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/evaluation_appbar_layout">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="问题分类" />
<Spinner
android:id="@+id/evaluation_class_type"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="5dp"
android:background="@drawable/fm_card_map_down_status_bg" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/evaluation_class_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/evaluation_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,99 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:orientation="vertical">
<RelativeLayout
style="@style/title_default_style"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#553C3F41">
<ImageView
android:id="@+id/btn_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:paddingBottom="@dimen/default_widget_padding"
android:paddingLeft="@dimen/default_widget_padding"
android:paddingRight="@dimen/default_widget_padding"
android:paddingTop="@dimen/default_widget_padding"
android:src="@drawable/btn_back_xml" />
<RadioGroup
android:id="@+id/rg_city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:gravity="center"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rb_manager"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/fm_card_map_btn_bg_line"
android:button="@null"
android:drawableLeft="@null"
android:gravity="center"
android:paddingBottom="@dimen/default_widget_padding"
android:paddingLeft="@dimen/default_widget_padding"
android:paddingRight="@dimen/default_widget_padding"
android:paddingTop="@dimen/default_widget_padding"
android:text="下载管理"
android:textColor="@color/btn_blue_white"
android:textSize="18sp" />
<RadioButton
android:id="@+id/rb_city_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/fm_card_map_btn_bg_line"
android:button="@null"
android:checked="true"
android:drawableLeft="@null"
android:gravity="center"
android:paddingBottom="@dimen/default_widget_padding"
android:paddingLeft="@dimen/default_widget_padding"
android:paddingRight="@dimen/default_widget_padding"
android:paddingTop="@dimen/default_widget_padding"
android:text="城市列表"
android:textColor="@color/btn_blue_white"
android:textSize="18sp" />
</RadioGroup>
</RelativeLayout>
<EditText
android:id="@+id/edt_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/input_blue_type"
android:hint="搜索"></EditText>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_map_download_network_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_gravity="center"
android:textColor="#FFFFFF"
android:visibility="gone"
android:text="网络错误,请检查网络后重试"></TextView>
<!-- <com.yanzhenjie.recyclerview.SwipeRecyclerView-->
<!-- android:id="@+id/lv_map_manager"-->
<!-- android:layout_width="match_parent"-->
<!-- android:visibility="invisible"-->
<!-- android:layout_height="match_parent">-->
<!-- </com.yanzhenjie.recyclerview.SwipeRecyclerView>-->
<!-- <com.yanzhenjie.recyclerview.SwipeRecyclerView-->
<!-- android:id="@+id/lv_map_city"-->
<!-- android:visibility="visible"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent">-->
<!-- </com.yanzhenjie.recyclerview.SwipeRecyclerView>-->
</FrameLayout>
</LinearLayout>

View File

@ -26,20 +26,13 @@
android:text="城市列表" />
</com.google.android.material.tabs.TabLayout>
<EditText
android:id="@+id/offline_map_search"
style="@style/input_blue_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="搜索"
app:layout_constraintTop_toBottomOf="@id/offline_map_tab_layout" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/offline_map_viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/offline_map_search" />
app:layout_constraintTop_toBottomOf="@id/offline_map_tab_layout" />
<ImageView
android:id="@+id/offline_map_back"
@ -51,4 +44,6 @@
app:layout_constraintBottom_toBottomOf="@id/offline_map_tab_layout"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@id/offline_map_tab_layout" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -6,8 +6,19 @@
android:layout_height="match_parent"
tools:context=".ui.fragment.offlinemap.OfflineMapCityListFragment">
<EditText
android:id="@+id/offline_map_search"
style="@style/input_blue_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="搜索"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/offline_map_city_list_recyclerview"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/offline_map_search" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -4,15 +4,11 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/default_red"
tools:context=".ui.fragment.offlinemap.OfflineMapStateListFragment">
<TextView
android:text="第一页"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/offline_map_city_state_list_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -2,7 +2,7 @@
<com.google.android.material.navigation.NavigationView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".ui.fragment.personalcenter.PersonalCenterFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="left"

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.navinfo.omqs.ui.fragment.evaluationresult.PhenomenonFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/phenomenon_recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,48 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="mainActivity"
type="com.navinfo.omqs.ui.activity.map.MainActivity" />
<variable
name="viewModel"
type="com.navinfo.omqs.ui.activity.map.MainViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.activity.map.MainActivity">
<com.navinfo.collect.library.map.NIMapView
android:id="@+id/main_activity_map"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageButton
android:id="@+id/main_activity_person_center"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:onClick="@{()->mainActivity.openMenu()}"
android:src="@drawable/baseline_person_24"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/main_activity_location"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginLeft="20dp"
android:layout_marginBottom="80dp"
android:onClick="@{()->viewModel.onClickLocationButton()}"
android:src="@drawable/baseline_my_location_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/action_settings" />
<Spinner
android:id="@+id/evaluation_class_type"
android:layout_width="match_parent"
android:layout_height="50dp" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/evaluation_class_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/default_blue">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="下载管理" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="城市列表" />
</com.google.android.material.tabs.TabLayout>
</LinearLayout>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/item_id"
android:layout_width="match_parent"
android:gravity="center"
android:layout_height="wrap_content"
android:padding="5dp"
android:textColor="@color/black"
android:textSize="18sp">
</TextView>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/delete"
android:contentDescription="删除数据"
android:icon="@drawable/baseline_delete_forever_24"
android:title="删除"
app:showAsAction="ifRoom" />
<item
android:id="@+id/save"
android:contentDescription="保存数据"
android:icon="@drawable/baseline_save_24"
android:title="保存"
app:showAsAction="ifRoom" />
</menu>

View File

@ -15,9 +15,9 @@
android:icon="@drawable/ic_baseline_import_export_24"
android:title="导入数据" />
<item
android:id="@+id/personal_center_menu_offline_map2"
android:icon="@drawable/baseline_person_24"
android:title="menu_slideshow" />
android:id="@+id/personal_center_menu_import_yuan_data"
android:icon="@drawable/ic_baseline_import_export_24"
android:title="导入元数据" />
</group>
<group
android:id="@+id/group2"

View File

@ -2,7 +2,7 @@
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
android:id="@+id/left_drawer_nav_graph"
app:startDestination="@id/PersonalCenterFragment">
<fragment

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/right_fragment_nav_graph"
app:startDestination="@id/EmptyFragment">
<fragment
android:id="@+id/EmptyFragment"
android:name="com.navinfo.omqs.ui.fragment.empty.EmptyFragment"
android:label="空页面"
tools:layout="@layout/fragment_empty"></fragment>
<fragment
android:id="@+id/EvaluationResultFragment"
android:name="com.navinfo.omqs.ui.fragment.evaluationresult.EvaluationResultFragment"
android:label="评测页面"
tools:layout="@layout/fragment_evaluation_result"></fragment>
</navigation>

View File

@ -1,5 +1,6 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
dependencies {
classpath "io.realm:realm-gradle-plugin:10.11.1"

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.

View File

@ -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)
// }
//
//
//}

View File

@ -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
// }
//}

View File

@ -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)
}
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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) {

View File

@ -1,30 +1,32 @@
pluginManagement {
repositories {
gradlePluginPortal()
google()
gradlePluginPortal()
mavenCentral()
maven { url 'https://jitpack.io' }
maven { url "https://maven.aliyun.com/repository/google" }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'https://download.flutter.io' }
maven { url 'https://storage.googleapis.com/download.flutter.io' }
maven { url 'https://maven.aliyun.com/repository/central' }
maven { url 'https://jitpack.io' }
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
gradlePluginPortal()
maven { url 'https://jitpack.io' }
maven { url "https://maven.aliyun.com/repository/google" }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'https://download.flutter.io' }
maven { url 'https://storage.googleapis.com/download.flutter.io' }
maven { url 'https://maven.aliyun.com/repository/central' }
maven { url 'https://jitpack.io' }
}
}
rootProject.name = "OMQualityInspection"