Conflicts:
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt
	app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
	app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultViewModel.kt
This commit is contained in:
qiji4215
2023-04-28 16:20:31 +08:00
36 changed files with 913 additions and 363 deletions

View File

@@ -59,6 +59,7 @@
android:name=".ui.activity.map.MainActivity"
android:launchMode="singleTask"
android:screenOrientation="landscape"
android:exported="false"
android:theme="@style/Theme.OMQualityInspection" />
<meta-data

View File

@@ -1,21 +0,0 @@
package com.navinfo.omqs.bean
import io.realm.RealmObject
import io.realm.annotations.RealmClass
@RealmClass
open class HadLinkDvoBean @JvmOverloads constructor(
/**
* 图幅号
*/
var mesh: String = "",
/**
* linkPid
*/
var linkPid: String = "",
/**
* (几何)加偏后
*/
var geometry: String = ""
) : RealmObject()

View File

@@ -1,6 +1,7 @@
package com.navinfo.omqs.bean
import com.google.gson.annotations.SerializedName
import com.navinfo.collect.library.data.entity.HadLinkDvoBean
import com.navinfo.omqs.Constant
import com.navinfo.omqs.tools.FileManager
import com.navinfo.omqs.tools.FileManager.Companion.FileDownloadStatus
@@ -8,9 +9,7 @@ import io.realm.RealmList
import io.realm.RealmObject
import io.realm.annotations.Ignore
import io.realm.annotations.PrimaryKey
import io.realm.annotations.RealmClass
@RealmClass
open class TaskBean @JvmOverloads constructor(
/**
* 测评任务id

View File

@@ -136,13 +136,13 @@ class ImportOMDBHelper @AssistedInject constructor(
it.name == currentConfig.table
}
val listResult = mutableListOf<Map<String, Any?>>()
val listResult = mutableListOf<Map<String, Any>>()
currentConfig?.let {
val list = FileIOUtils.readFile2List(txtFile, "UTF-8")
if (list != null) {
// 将list数据转换为map
for (line in list) {
val map = gson.fromJson<Map<String, Any?>>(line, object:TypeToken<Map<String, Any?>>(){}.getType())
val map = gson.fromJson<Map<String, Any>>(line, object:TypeToken<Map<String, Any>>(){}.getType())
.toMutableMap()
map["qi_table"] = currentConfig.table
map["qi_name"] = currentConfig.name
@@ -162,13 +162,13 @@ class ImportOMDBHelper @AssistedInject constructor(
renderEntity.geometry = map["geometry"].toString()
for ((key, value) in map) {
when (value) {
is String -> renderEntity.properties[key.toString()] = value
is Int -> renderEntity.properties[key.toString()] = value.toInt().toString()
is Double -> renderEntity.properties[key.toString()] = value.toDouble().toString()
else -> renderEntity.properties[key.toString()] = value.toString()
is String -> renderEntity.properties.put(key, value)
is Int -> renderEntity.properties.put(key, value.toInt().toString())
is Double -> renderEntity.properties.put(key, value.toDouble().toString())
else -> renderEntity.properties.put(key, value.toString())
}
}
Realm.getDefaultInstance().insert(renderEntity)
Realm.getDefaultInstance().copyToRealm(renderEntity)
}
// 1个文件发送一次flow流
emit("${index + 1}/${importConfig.tables.size}")

View File

@@ -1,9 +1,9 @@
package com.navinfo.omqs.db
import com.navinfo.omqs.bean.HadLinkDvoBean
import com.navinfo.collect.library.data.entity.HadLinkDvoBean
import com.navinfo.omqs.bean.TaskBean
import io.realm.annotations.RealmModule
@RealmModule(classes = [TaskBean::class, HadLinkDvoBean::class])
@RealmModule(classes = [TaskBean::class])
class MyRealmModule {
}

View File

@@ -1,7 +1,10 @@
package com.navinfo.omqs.db
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import com.navinfo.collect.library.data.entity.RenderEntity
import com.navinfo.collect.library.data.entity.RenderEntity.Companion.LinkTable
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.utils.GeometryTools
import com.navinfo.collect.library.utils.GeometryToolsKt
@@ -17,10 +20,11 @@ import org.oscim.core.MercatorProjection
import javax.inject.Inject
import kotlin.streams.toList
@RequiresApi(Build.VERSION_CODES.N)
class RealmOperateHelper() {
@Inject
lateinit var niMapController: NIMapController
/**
* 根据当前点位查询匹配的Link数据
* @param point 点位经纬度信息
@@ -28,7 +32,12 @@ class RealmOperateHelper() {
* @param bufferType 点位外扩距离的单位: 米-Meter像素-PIXEL
* @param sort 是否需要排序
* */
suspend fun queryLink(point: Point, buffer: Double = DEFAULT_BUFFER, bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE, sort: Boolean = false): MutableList<RenderEntity> {
suspend fun queryLink(
point: Point,
buffer: Double = DEFAULT_BUFFER,
bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE,
sort: Boolean = true
): MutableList<RenderEntity> {
val result = mutableListOf<RenderEntity>()
withContext(Dispatchers.IO) {
val polygon = getPolygonFromPoint(point, buffer, bufferType)
@@ -45,25 +54,47 @@ class RealmOperateHelper() {
val yStart = tileYSet.stream().min(Comparator.naturalOrder()).orElse(null)
val yEnd = tileYSet.stream().max(Comparator.naturalOrder()).orElse(null)
// 查询realm中对应tile号的数据
val realmList = Realm.getDefaultInstance().where(RenderEntity::class.java)
val realm = Realm.getDefaultInstance()
val realmList = realm.where(RenderEntity::class.java)
.equalTo("table", "OMDB_RD_LINK")
.and()
.rawPredicate("tileX>=$xStart and tileX<=$xEnd and tileY>=$yStart and tileY<=$yEnd")
.findAll()
// 将获取到的数据和查询的polygon做相交只返回相交的数据
val queryResult = realmList?.stream()?.filter {
val dataList = realm.copyFromRealm(realmList)
val queryResult = dataList?.stream()?.filter {
polygon.intersects(it.wkt)
}?.toList()
queryResult?.let {
result.addAll(queryResult)
}
if (sort) {
result.clear()
result.addAll(sortRenderEntity(point, result))
if (sort) {
result.addAll(sortRenderEntity(point, it))
} else {
result.addAll(it)
}
}
}
return result
}
suspend fun queryLink(linkPid: String): RenderEntity? {
var link: RenderEntity? = null
withContext(Dispatchers.IO) {
val realm = Realm.getDefaultInstance()
val realmR = realm.where(RenderEntity::class.java)
.equalTo("table", "OMDB_RD_LINK")
.and()
.equalTo("properties['${LinkTable.linkPid}']", linkPid)
.findFirst()
if (realmR != null) {
link = realm.copyFromRealm(realmR)
}
}
return link
}
/**
* 根据当前点位查询匹配的除Link外的其他要素数据
* @param point 点位经纬度信息
@@ -71,7 +102,12 @@ class RealmOperateHelper() {
* @param bufferType 点位外扩距离的单位: 米-Meter像素-PIXEL
* @param sort 是否需要排序
* */
suspend fun queryElement(point: Point, buffer: Double = DEFAULT_BUFFER, bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE, sort: Boolean = false): MutableList<RenderEntity> {
suspend fun queryElement(
point: Point,
buffer: Double = DEFAULT_BUFFER,
bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE,
sort: Boolean = true
): MutableList<RenderEntity> {
val result = mutableListOf<RenderEntity>()
withContext(Dispatchers.IO) {
val polygon = getPolygonFromPoint(point, buffer, bufferType)
@@ -121,7 +157,7 @@ class RealmOperateHelper() {
val realmList = Realm.getDefaultInstance().where(RenderEntity::class.java)
.notEqualTo("table", "OMDB_RD_LINK")
.and()
.equalTo("properties['LINK_PID']", linkPid)
.equalTo("properties['${LinkTable.linkPid}']", linkPid)
.findAll()
result.addAll(realmList)
}
@@ -134,15 +170,19 @@ class RealmOperateHelper() {
* @param unSortList 未排序的数据
* @return 排序后的数据
* */
fun sortRenderEntity(point: Point, unSortList: MutableList<RenderEntity>): List<RenderEntity> {
fun sortRenderEntity(point: Point, unSortList: List<RenderEntity>): List<RenderEntity> {
val sortList = unSortList.stream().sorted { renderEntity, renderEntity2 ->
val near = point.distance(renderEntity.wkt) - point.distance(renderEntity2.wkt)
if (near<0) -1 else 1
if (near < 0) -1 else 1
}.toList()
return sortList
}
private fun getPolygonFromPoint(point: Point, buffer: Double = DEFAULT_BUFFER, bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE): Polygon {
private fun getPolygonFromPoint(
point: Point,
buffer: Double = DEFAULT_BUFFER,
bufferType: BUFFER_TYPE = DEFAULT_BUFFER_TYPE
): Polygon {
// 首先计算当前点位的buffer组成的geometry
val wkt: Polygon = if (bufferType == BUFFER_TYPE.METER) { // 如果单位是米
val distanceDegrees = GeometryTools.convertDistanceToDegree(buffer, point.y)
@@ -151,14 +191,30 @@ class RealmOperateHelper() {
} else { // 如果单位是像素,需要根据当前屏幕像素计算出经纬度变化
val currentMapScale = niMapController.mMapView.vtmMap.mapPosition.scale
// 转换为屏幕坐标
val pixelPoint = MercatorProjection.getPixelWithScale(GeoPoint(point.y, point.x), currentMapScale)
val pixelPoint =
MercatorProjection.getPixelWithScale(
GeoPoint(point.y, point.x),
currentMapScale
)
// 将屏幕坐标外扩指定距离
// 计算外扩矩形
val envelope = Envelope(
MercatorProjection.pixelXToLongitudeWithScale(pixelPoint.x - buffer, currentMapScale),
MercatorProjection.pixelXToLongitudeWithScale(pixelPoint.x + buffer, currentMapScale),
MercatorProjection.pixelYToLatitudeWithScale(pixelPoint.y - buffer, currentMapScale),
MercatorProjection.pixelYToLatitudeWithScale(pixelPoint.y + buffer, currentMapScale),
MercatorProjection.pixelXToLongitudeWithScale(
pixelPoint.x - buffer,
currentMapScale
),
MercatorProjection.pixelXToLongitudeWithScale(
pixelPoint.x + buffer,
currentMapScale
),
MercatorProjection.pixelYToLatitudeWithScale(
pixelPoint.y - buffer,
currentMapScale
),
MercatorProjection.pixelYToLatitudeWithScale(
pixelPoint.y + buffer,
currentMapScale
),
)
// 将Envelope对象转换为Polygon对象
val geometryFactory = GeometryFactory()
@@ -178,7 +234,8 @@ class RealmOperateHelper() {
enum class BUFFER_TYPE(val index: Int) {
METER(0)/*米*/, PIXEL(1)/*像素*/;
fun getBufferTypeByIndex(index: Int): BUFFER_TYPE{
fun getBufferTypeByIndex(index: Int): BUFFER_TYPE {
for (item in BUFFER_TYPE.values()) {
if (item.index == index) {
return item;

View File

@@ -6,6 +6,7 @@ import androidx.room.Room
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import com.navinfo.collect.library.data.dao.impl.TraceDataBase
import com.navinfo.omqs.Constant
import com.navinfo.omqs.OMQSApplication
import com.navinfo.omqs.db.RoomAppDatabase
@@ -90,7 +91,7 @@ class GlobalModule {
@Provides
@Singleton
fun provideGson(): Gson = GsonBuilder()
// 解决解析Json时将int类型自动转换为Double的问题
// 解决解析Json时将int类型自动转换为Double的问题
.registerTypeAdapter(object : TypeToken<Map<String, Any?>>() {}.getType(), IntTypeAdapter())
.registerTypeAdapter(object : TypeToken<Map<String, Any>>() {}.getType(), IntTypeAdapter())
.registerTypeAdapter(object : TypeToken<Map<Any, Any>>() {}.getType(), IntTypeAdapter())
@@ -137,6 +138,15 @@ class GlobalModule {
.build();
}
@Singleton
@Provides
fun provideTraceDatabase(context: Application): TraceDataBase {
return TraceDataBase.getDatabase(
context,
Constant.USER_DATA_PATH + "/trace.sqlite"
)
}
// /**
// * realm 注册
// */

View File

@@ -10,6 +10,7 @@ import androidx.annotation.RequiresApi
import androidx.core.view.WindowCompat
import androidx.databinding.DataBindingUtil
import androidx.navigation.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.blankj.utilcode.util.ToastUtils
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.map.handler.NiLocationListener
@@ -37,6 +38,7 @@ class MainActivity : BaseActivity() {
@Inject
lateinit var offlineMapDownloadManager: OfflineMapDownloadManager
private val signAdapter by lazy { SignAdapter() }
override fun onCreate(savedInstanceState: Bundle?) {
WindowCompat.setDecorFitsSystemWindows(window, false)
@@ -48,7 +50,7 @@ class MainActivity : BaseActivity() {
binding.mainActivityMap,
null,
Constant.MAP_PATH,
Constant.USER_DATA_PATH+"/trace.sqlite"
Constant.USER_DATA_PATH + "/trace.sqlite"
)
//关联生命周期
binding.lifecycleOwner = this
@@ -81,7 +83,11 @@ class MainActivity : BaseActivity() {
//处理页面跳转
viewModel.navigation(this, it)
}
binding.mainActivitySignRecyclerview.layoutManager = LinearLayoutManager(this)
binding.mainActivitySignRecyclerview.adapter = signAdapter
viewModel.liveDataSignList.observe(this) {
signAdapter.refreshData(it)
}
}
override fun onStart() {
@@ -89,15 +95,10 @@ class MainActivity : BaseActivity() {
//开启定位
mapController.locationLayerHandler.startLocation()
//启动轨迹存储
mapController.locationLayerHandler.setNiLocationListener(NiLocationListener {
//ToastUtils.showLong("定位${it.longitude}")
binding!!.viewModel!!.addSaveTrace(it)
})
binding!!.viewModel!!.startSaveTraceThread(this)
//显示轨迹图层
// mapController.layerManagerHandler.showNiLocationLayer(Constant.DATA_PATH+ SystemConstant.USER_ID+"/trace.sqlite")
mapController.layerManagerHandler.showNiLocationLayer()
// viewModel.startSaveTraceThread(this)
}
override fun onPause() {
@@ -128,7 +129,7 @@ class MainActivity : BaseActivity() {
*/
fun openCamera() {
//显示轨迹图层
binding!!.viewModel!!.onClickCameraButton(this)
viewModel.onClickCameraButton(this)
}
/**

View File

@@ -6,6 +6,7 @@ import android.content.DialogInterface
import android.graphics.drawable.AnimationDrawable
import android.graphics.drawable.BitmapDrawable
import android.os.Build
import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
@@ -15,25 +16,33 @@ import android.view.ViewGroup
import android.widget.ImageView
import android.widget.PopupWindow
import androidx.annotation.RequiresApi
import androidx.annotation.RequiresApi
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.navigation.findNavController
import com.blankj.utilcode.util.ToastUtils
import com.navinfo.collect.library.data.dao.impl.TraceDataBase
import com.navinfo.collect.library.data.entity.NiLocation
import com.navinfo.collect.library.data.entity.RenderEntity
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.map.handler.NiLocationListener
import com.navinfo.collect.library.map.handler.OnQsRecordItemClickListener
import com.navinfo.collect.library.utils.GeometryTools
import com.navinfo.collect.library.utils.GeometryToolsKt
import com.navinfo.omqs.Constant
import com.navinfo.omqs.R
import com.navinfo.omqs.db.RealmOperateHelper
import com.navinfo.omqs.ui.dialog.CommonDialog
import com.navinfo.omqs.ui.manager.TakePhotoManager
import com.navinfo.omqs.util.DateTimeUtil
import com.navinfo.omqs.util.SoundMeter
import com.navinfo.omqs.util.SpeakMode
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ActivityContext
import dagger.hilt.android.qualifiers.ApplicationContext
import io.realm.RealmSet
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.oscim.core.GeoPoint
import org.videolan.libvlc.LibVlcUtil
import java.io.File
@@ -43,14 +52,25 @@ import javax.inject.Inject
/**
* 创建Activity全局viewmode
*/
@HiltViewModel
class MainViewModel @Inject constructor(
private val mapController: NIMapController
private val mapController: NIMapController,
private val traceDataBase: TraceDataBase,
private val realmOperateHelper: RealmOperateHelper
) : ViewModel() {
val liveDataQsRecordIdList = MutableLiveData<List<String>>()
private var mCameraDialog: CommonDialog? = null
//地图点击捕捉到的质检数据ID列表
val liveDataQsRecordIdList = MutableLiveData<List<String>>()
//看板数据
val liveDataSignList = MutableLiveData<List<SignBean>>()
// private var niLocationList: MutableList<NiLocation> = ArrayList<NiLocation>()
var testPoint = GeoPoint(0, 0)
//语音窗体
private var pop: PopupWindow? = null
@@ -69,6 +89,93 @@ class MainViewModel @Inject constructor(
liveDataQsRecordIdList.value = list
}
})
initLocation()
viewModelScope.launch {
mapController.onMapClickFlow.collect {
testPoint = it
}
}
}
private fun initLocation() {
// mapController.locationLayerHandler.setNiLocationListener(NiLocationListener {
// addSaveTrace(it)
//
// })
//用于定位点存储到数据库
viewModelScope.launch(Dispatchers.Default) {
mapController.locationLayerHandler.niLocationFlow.collect { location ->
location.longitude = testPoint.longitude
location.latitude = testPoint.latitude
val geometry = GeometryTools.createGeometry(
GeoPoint(
location.latitude,
location.longitude
)
)
val tileX = RealmSet<Int>()
GeometryToolsKt.getTileXByGeometry(geometry.toString(), tileX)
val tileY = RealmSet<Int>()
GeometryToolsKt.getTileYByGeometry(geometry.toString(), tileY)
//遍历存储tile对应的x与y的值
tileX.forEach { x ->
tileY.forEach { y ->
location.tilex = x
location.tiley = y
}
}
Log.e("jingo", "定位点插入 ${Thread.currentThread().name}")
traceDataBase.niLocationDao.insert(location)
}
}
//用于定位点捕捉道路
viewModelScope.launch(Dispatchers.Default) {
mapController.locationLayerHandler.niLocationFlow.collect { location ->
Log.e("jingo", "定位点绑定道路 ${Thread.currentThread().name}")
location.longitude = testPoint.longitude
location.latitude = testPoint.latitude
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val linkList = realmOperateHelper.queryLink(
point = GeometryTools.createPoint(
location.longitude,
location.latitude
),
)
//看板数据
val signList = mutableListOf<SignBean>()
if (linkList.isNotEmpty()) {
val link = linkList[0]
val linkId = link.properties[RenderEntity.Companion.LinkTable.linkPid]
mapController.lineHandler.showLine(link.geometry)
linkId?.let {
var elementList = realmOperateHelper.queryLinkByLinkPid(it)
for (element in elementList) {
val distance = GeometryTools.distanceToDouble(
GeoPoint(
location.latitude, location.longitude,
),
GeometryTools.createGeoPoint(element.geometry)
)
signList.add(
SignBean(
iconId = R.drawable.icon_speed_limit,
iconText = element.name,
distance = distance.toInt(),
)
)
}
liveDataSignList.postValue(signList)
Log.e("jingo", "自动捕捉数据 共${elementList.size}")
}
}
}
}
}
//显示轨迹图层
mapController.layerManagerHandler.showNiLocationLayer()
}
@@ -121,144 +228,61 @@ class MainViewModel @Inject constructor(
})
}
fun startSaveTraceThread(context: Context) {
Thread(Runnable {
try {
while (true) {
if (niLocationList != null && niLocationList.size > 0) {
var niLocation = niLocationList[0]
val geometry = GeometryTools.createGeometry(
GeoPoint(
niLocation.latitude,
niLocation.longitude
)
)
val tileX = RealmSet<Int>()
GeometryToolsKt.getTileXByGeometry(geometry.toString(), tileX)
val tileY = RealmSet<Int>()
GeometryToolsKt.getTileYByGeometry(geometry.toString(), tileY)
//遍历存储tile对应的x与y的值
tileX.forEach { x ->
tileY.forEach { y ->
niLocation.tilex = x
niLocation.tiley = y
}
}
TraceDataBase.getDatabase(
context,
Constant.USER_DATA_PATH + "/trace.sqlite"
).niLocationDao.insert(niLocation)
val list = TraceDataBase.getDatabase(
context,
Constant.USER_DATA_PATH + "/trace.sqlite"
).niLocationDao.findAll()
niLocationList.remove(niLocation)
Log.e("qj", "saveTrace==${niLocationList.size}===${list.size}")
}
Thread.sleep(30)
}
} catch (e: InterruptedException) {
e.printStackTrace()
Log.e("qj", "异常==${e.message}")
}
}).start()
}
//增加轨迹存储
fun addSaveTrace(niLocation: NiLocation) {
if (niLocation != null && niLocationList != null) {
niLocationList.add(niLocation)
}
}
fun startSoundMetter(context: Context, niLocation: NiLocation?, v: View) {
if (niLocation == null) {
ToastUtils.showLong("未获取到GPS信息请检查GPS是否正常")
//停止录音动画
if (pop != null && pop!!.isShowing())
pop!!.dismiss();
return;
}
if(mSpeakMode==null){
mSpeakMode = SpeakMode(context as Activity?)
}
//语音识别动画
if (pop == null) {
pop = PopupWindow()
pop!!.width = ViewGroup.LayoutParams.MATCH_PARENT
pop!!.height = ViewGroup.LayoutParams.WRAP_CONTENT
pop!!.setBackgroundDrawable(BitmapDrawable())
val view = View.inflate(context, R.layout.cv_card_voice_rcd_hint_window, null)
pop!!.contentView = view
volume = view.findViewById(R.id.volume)
}
pop!!.update()
Constant.IS_VIDEO_SPEED = true
//录音动画
//录音动画
if (pop != null) {
pop!!.showAtLocation(v, Gravity.CENTER, 0, 0)
}
volume!!.setBackgroundResource(R.drawable.pop_voice_img)
val animation = volume!!.background as AnimationDrawable
animation.start()
val name: String = DateTimeUtil.getTimeSSS().toString() + ".m4a"
if (mSoundMeter == null) {
mSoundMeter = SoundMeter()
}
mSoundMeter!!.setmListener(object : SoundMeter.OnSoundMeterListener {
@RequiresApi(Build.VERSION_CODES.Q)
override fun onSuccess(filePath: String?) {
if (!TextUtils.isEmpty(filePath) && File(filePath).exists()) {
if (File(filePath) == null || File(filePath).length() < 1600) {
ToastUtils.showLong("语音时间太短,无效!")
mSpeakMode!!.speakText("语音时间太短,无效")
stopSoundMeter()
return
}
}
mSpeakMode!!.speakText("结束录音")
//获取右侧fragment容器
val naviController = (context as Activity).findNavController(R.id.main_activity_right_fragment)
val bundle = Bundle()
bundle.putString("filePath", filePath)
naviController.navigate(R.id.EvaluationResultFragment, bundle)
}
@RequiresApi(api = Build.VERSION_CODES.Q)
override fun onfaild(message: String?) {
ToastUtils.showLong("录制失败!")
mSpeakMode!!.speakText("录制失败")
stopSoundMeter()
}
})
mSoundMeter!!.start(Constant.USER_DATA_ATTACHEMNT_PATH + name)
ToastUtils.showLong("开始录音")
mSpeakMode!!.speakText("开始录音")
}
//停止语音录制
@RequiresApi(api = Build.VERSION_CODES.Q)
fun stopSoundMeter() {
//先重置标识,防止按钮抬起时触发语音结束
Constant.IS_VIDEO_SPEED = false
if (mSoundMeter != null && mSoundMeter!!.isStartSound()) {
mSoundMeter!!.stop()
}
if (pop != null && pop!!.isShowing) pop!!.dismiss()
}
// fun startSaveTraceThread(context: Context) {
// Thread(Runnable {
// try {
// while (true) {
//
// if (niLocationList != null && niLocationList.size > 0) {
//
// var niLocation = niLocationList[0]
// val geometry = GeometryTools.createGeometry(
// GeoPoint(
// niLocation.latitude,
// niLocation.longitude
// )
// )
// val tileX = RealmSet<Int>()
// GeometryToolsKt.getTileXByGeometry(geometry.toString(), tileX)
// val tileY = RealmSet<Int>()
// GeometryToolsKt.getTileYByGeometry(geometry.toString(), tileY)
//
// //遍历存储tile对应的x与y的值
// tileX.forEach { x ->
// tileY.forEach { y ->
// niLocation.tilex = x
// niLocation.tiley = y
// }
// }
//
// TraceDataBase.getDatabase(
// context,
// Constant.USER_DATA_PATH + "/trace.sqlite"
// ).niLocationDao.insert(niLocation)
// niLocationList.remove(niLocation)
//
// Log.e("qj", "saveTrace==${niLocationList.size}")
// }
// Thread.sleep(30)
// }
// } catch (e: InterruptedException) {
// e.printStackTrace()
// Log.e("qj", "异常==${e.message}")
// }
// }).start()
// }
// //增加轨迹存储
// fun addSaveTrace(niLocation: NiLocation) {
// if (niLocation != null && niLocationList != null) {
// niLocationList.add(niLocation)
// }
// }
/**
* 处理页面调转
*/
fun navigation(activity: MainActivity, list: List<String>) {
//获取右侧fragment容器
val naviController = activity.findNavController(R.id.main_activity_right_fragment)

View File

@@ -0,0 +1,28 @@
package com.navinfo.omqs.ui.activity.map
import android.view.LayoutInflater
import android.view.ViewGroup
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.AdapterSignBinding
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
import com.navinfo.omqs.ui.other.BaseViewHolder
class SignAdapter : BaseRecyclerViewAdapter<SignBean>() {
override fun getItemViewRes(position: Int): Int {
return R.layout.adapter_sign
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
val viewBinding =
AdapterSignBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return BaseViewHolder(viewBinding)
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
val bd = holder.viewBinding as AdapterSignBinding
val item = data[position]
bd.signMainIcon.background = holder.viewBinding.root.context.getDrawable(item.iconId)
bd.signMainIcon.text = item.iconText
}
}

View File

@@ -0,0 +1,8 @@
package com.navinfo.omqs.ui.activity.map
data class SignBean(
//图标ID
val iconId: Int,
val distance: Int = 0,
val iconText: String = ""
)

View File

@@ -72,7 +72,7 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener {
if (arguments != null) {
val id = requireArguments().getString("QsId")
if (id != null) {
viewModel.loadData(id)
viewModel.initData(id)
} else {
viewModel.initNewData()
}

View File

@@ -7,6 +7,7 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.navinfo.collect.library.data.entity.QsRecordBean
import com.navinfo.collect.library.data.entity.RenderEntity.Companion.LinkTable
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.utils.GeometryTools
import com.navinfo.omqs.Constant
@@ -19,6 +20,7 @@ import io.realm.Realm
import io.realm.kotlin.where
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.oscim.core.GeoPoint
import java.util.*
import javax.inject.Inject
@@ -62,31 +64,24 @@ class EvaluationResultViewModel @Inject constructor(
init {
liveDataQsRecordBean.value = QsRecordBean(id = UUID.randomUUID().toString())
Log.e("jingo", "EvaluationResultViewModel 创建了 ${hashCode()}")
mapController.markerHandle.run {
setOnMapClickListener {
liveDataQsRecordBean.value!!.geometry = it.toGeometry()
addMarker(it, markerTitle)
viewModelScope.launch {
mapController.onMapClickFlow.collect {
liveDataQsRecordBean.value!!.geometry = GeometryTools.createGeometry(it).toText()
mapController.markerHandle.addMarker(it, markerTitle)
viewModelScope.launch {
val linkList = realmOperateHelper.queryLink(
point = GeometryTools.createPoint(
it.longitude,
it.latitude
), sort = true
)
if (linkList.isNotEmpty()) {
liveDataQsRecordBean.value!!.linkId = linkList[0].id
}
captureLink(it.longitude, it.latitude)
}
}
}
}
override fun onCleared() {
super.onCleared()
Log.e("jingo", "EvaluationResultViewModel 销毁了 ${hashCode()}")
mapController.markerHandle.removeMarker(markerTitle)
mapController.markerHandle.removeOnMapClickListener()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mapController.lineHandler.removeLine()
}
}
@@ -100,17 +95,34 @@ class EvaluationResultViewModel @Inject constructor(
}
val geoPoint = mapController.locationLayerHandler.getCurrentGeoPoint()
geoPoint?.let {
liveDataQsRecordBean.value!!.geometry = it.toGeometry()
liveDataQsRecordBean.value!!.geometry = GeometryTools.createGeometry(it).toText()
mapController.markerHandle.addMarker(geoPoint, markerTitle)
viewModelScope.launch {
val linkList = realmOperateHelper.queryLink(
GeometryTools.createPoint(
geoPoint.longitude,
geoPoint.latitude
)
)
captureLink(geoPoint.longitude, geoPoint.latitude)
}
}
}
/**
* 捕捉到路
*/
private suspend fun captureLink(longitude: Double, latitude: Double) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val linkList = realmOperateHelper.queryLink(
point = GeometryTools.createPoint(
longitude,
latitude
),
)
liveDataQsRecordBean.value?.let {
if (linkList.isNotEmpty()) {
liveDataQsRecordBean.value!!.linkId = linkList[0].id
it.linkId =
linkList[0].properties[LinkTable.linkPid] ?: ""
mapController.lineHandler.showLine(linkList[0].geometry)
} else {
it.linkId = ""
mapController.lineHandler.removeLine()
}
}
}
@@ -270,14 +282,31 @@ class EvaluationResultViewModel @Inject constructor(
/**
* 根据数据id查询数据
*/
fun loadData(id: String) {
viewModelScope.launch(Dispatchers.IO) {
val realm = Realm.getDefaultInstance()
val objects = realm.where<QsRecordBean>().equalTo("id", id).findFirst()
if (objects != null) {
oldBean = realm.copyFromRealm(objects)
liveDataQsRecordBean.postValue(oldBean!!.copy())
fun initData(id: String) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
viewModelScope.launch(Dispatchers.IO) {
val realm = Realm.getDefaultInstance()
val objects = realm.where<QsRecordBean>().equalTo("id", id).findFirst()
if (objects != null) {
oldBean = realm.copyFromRealm(objects)
oldBean?.let {
liveDataQsRecordBean.postValue(it.copy())
val p = GeometryTools.createGeoPoint(it.geometry)
mapController.markerHandle.addMarker(
GeoPoint(p.latitude, p.longitude),
markerTitle
)
if (it.linkId.isNotEmpty()) {
val link = realmOperateHelper.queryLink(it.linkId)
link?.let { l ->
mapController.lineHandler.showLine(l.geometry)
}
}
}
}
}
}
}

View File

@@ -1,7 +1,9 @@
package com.navinfo.omqs.ui.fragment.evaluationresult
import android.os.Build
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.annotation.RequiresApi
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.TextItemSelectBinding
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
@@ -21,6 +23,7 @@ class MiddleAdapter(private var itemListener: ((Int, String) -> Unit?)? = null)
return BaseViewHolder(viewBinding)
}
@RequiresApi(Build.VERSION_CODES.M)
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
val bd = holder.viewBinding as TextItemSelectBinding
val title = data[position]

View File

@@ -109,8 +109,7 @@ class PersonalCenterFragment : BaseFragment(), FSAFActivityCallbacks {
R.id.personal_center_menu_test -> {
viewModel.readRealmData()
// 定位到指定位置
niMapController.mMapView.vtmMap.animator()
.animateTo(GeoPoint(30.270367985798032, 113.83513667119433))
niMapController.mMapView.vtmMap.animator().animateTo(GeoPoint(30.226256855699773, 113.84660523913344))
}
R.id.personal_center_menu_task_list -> {
findNavController().navigate(R.id.TaskListFragment)

View File

@@ -1,11 +1,16 @@
package com.navinfo.omqs.ui.fragment.tasklist
import android.content.Context
import android.graphics.Color
import android.os.Build
import android.util.Log
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.core.graphics.toColor
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.omqs.bean.TaskBean
import com.navinfo.omqs.http.NetResult
import com.navinfo.omqs.http.NetworkService
@@ -19,7 +24,8 @@ import javax.inject.Inject
@HiltViewModel
class TaskListViewModel @Inject constructor(
private val networkService: NetworkService
private val networkService: NetworkService,
private val niMapController: NIMapController
) : ViewModel() {
val liveDataTaskList = MutableLiveData<List<TaskBean>>()
@@ -70,6 +76,11 @@ class TaskListViewModel @Inject constructor(
for (item in taskList) {
FileManager.checkOMDBFileInfo(item)
}
// niMapController.lineHandler.omdbTaskLinkLayer.setLineColor(Color.rgb(0, 255, 0).toColor())
// taskList.forEach {
// niMapController.lineHandler.omdbTaskLinkLayer.addLineList(it.hadLinkDvoList)
// }
// niMapController.lineHandler.omdbTaskLinkLayer.update()
liveDataTaskList.postValue(taskList)
}

View File

@@ -0,0 +1,12 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
android:useLevel="false">
<stroke
android:width="1.33dp"
android:color="#DB4646" />
<size
android:width="24dp"
android:height="24dp" />
<solid android:color="@color/white" />
</shape>

View File

@@ -35,6 +35,7 @@
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/main_activity_person_center"
android:layout_width="48dp"
@@ -46,6 +47,14 @@
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/main_activity_sign_recyclerview"
android:layout_width="150dp"
android:layout_height="350dp"
android:layout_marginTop="10dp"
app:layout_constraintLeft_toLeftOf="@id/main_activity_person_center"
app:layout_constraintTop_toBottomOf="@id/main_activity_person_center" />
<ImageButton
android:id="@+id/main_activity_location"
android:layout_width="48dp"
@@ -67,6 +76,16 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<ImageButton
android:id="@+id/main_activity_line"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginBottom="10dp"
android:onClick="@{()->mainActivity.voiceOnclick()}"
android:src="@drawable/baseline_keyboard_voice_24"
app:layout_constraintBottom_toTopOf="@id/main_activity_voice"
app:layout_constraintRight_toRightOf="@id/main_activity_voice" />
<fragment
android:id="@+id/main_activity_middle_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
@@ -106,11 +125,11 @@
android:id="@+id/main_activity_camera2"
android:layout_width="48dp"
android:layout_height="48dp"
android:visibility="gone"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:onClick="@{()->mainActivity.openCamera()}"
android:src="@drawable/baseline_person_24"
android:visibility="gone"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

View File

@@ -0,0 +1,20 @@
<RelativeLayout 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="wrap_content"
android:layout_height="wrap_content"
android:background="@mipmap/bg_sign"
tools:context="com.navinfo.omqs.ui.activity.map.SignAdapter">
<TextView
android:id="@+id/sign_main_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="19dp"
android:layout_marginTop="4dp"
android:background="@drawable/icon_speed_limit"
android:gravity="center"
android:text="80"
android:textColor="#2F2F2F"
android:textSize="14.67sp" />
</RelativeLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB