Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
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 collect-library/src/main/java/com/navinfo/collect/library/map/handler/MarkHandler.kt
This commit is contained in:
commit
6c386505d6
@ -59,6 +59,11 @@ class Constant {
|
||||
|
||||
const val DEBUG = true
|
||||
|
||||
/**
|
||||
* 是否自动定位
|
||||
*/
|
||||
var AUTO_LOCATION = false
|
||||
|
||||
var IS_VIDEO_SPEED by kotlin.properties.Delegates.notNull<Boolean>()
|
||||
|
||||
const val message_status_late = "预约,待发送"
|
||||
|
@ -0,0 +1,8 @@
|
||||
package com.navinfo.omqs.bean
|
||||
|
||||
data class TraceVideoBean(
|
||||
var userid: String = "",
|
||||
var playMode: String = "",
|
||||
var time: String = "",
|
||||
var command: String = "",
|
||||
)
|
@ -6,8 +6,7 @@ import com.navinfo.omqs.bean.IndoorConnectionInfoBean
|
||||
import com.navinfo.omqs.bean.LoginUserBean
|
||||
import com.navinfo.omqs.bean.QRCodeBean
|
||||
import com.navinfo.omqs.bean.SysUserBean
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.Response
|
||||
import com.navinfo.omqs.bean.TraceVideoBean
|
||||
|
||||
|
||||
/**
|
||||
@ -38,4 +37,9 @@ interface NetworkService {
|
||||
* 更新用户信息
|
||||
*/
|
||||
suspend fun updateServerInfo(url: String,indoorConnectionInfoBean: IndoorConnectionInfoBean): NetResult<QRCodeBean>
|
||||
|
||||
/**
|
||||
* 设置轨迹对应的视频
|
||||
*/
|
||||
suspend fun sendServerCommand(url: String,traceVideoBean: TraceVideoBean): NetResult<QRCodeBean>
|
||||
}
|
@ -6,6 +6,7 @@ import com.navinfo.omqs.bean.IndoorConnectionInfoBean
|
||||
import com.navinfo.omqs.bean.LoginUserBean
|
||||
import com.navinfo.omqs.bean.QRCodeBean
|
||||
import com.navinfo.omqs.bean.SysUserBean
|
||||
import com.navinfo.omqs.bean.TraceVideoBean
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.ResponseBody
|
||||
@ -110,6 +111,33 @@ class NetworkServiceImpl @Inject constructor(
|
||||
map["baseurl"] = indoorConnectionInfoBean.baseurl
|
||||
map["platform"] = indoorConnectionInfoBean.platform
|
||||
|
||||
val result = netApi.retrofitUpdateServerInfo(url,map)
|
||||
if (result.isSuccessful) {
|
||||
if (result.code() == 200) {
|
||||
NetResult.Success(result.body())
|
||||
} else {
|
||||
NetResult.Failure<Any>(result.code(), result.message())
|
||||
}
|
||||
} else {
|
||||
NetResult.Failure<Any>(result.code(), result.message())
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
NetResult.Error<Any>(e)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun sendServerCommand(
|
||||
url: String,
|
||||
traceVideoBean: TraceVideoBean
|
||||
): NetResult<QRCodeBean> =
|
||||
//在IO线程中运行
|
||||
withContext(Dispatchers.IO) {
|
||||
return@withContext try {
|
||||
val map: MutableMap<String, String> = HashMap()
|
||||
map["userid"] = traceVideoBean.userid
|
||||
map["playMode"] = traceVideoBean.playMode
|
||||
map["time"] = traceVideoBean.time
|
||||
|
||||
val result = netApi.retrofitUpdateServerInfo(url,map)
|
||||
if (result.isSuccessful) {
|
||||
if (result.code() == 200) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.navinfo.omqs.ui.activity.login
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
@ -16,11 +17,11 @@ import com.navinfo.omqs.http.DefaultResponse
|
||||
import com.navinfo.omqs.http.NetResult
|
||||
import com.navinfo.omqs.http.NetworkService
|
||||
import com.navinfo.omqs.tools.FileManager
|
||||
import com.navinfo.omqs.util.NetUtils
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmConfiguration
|
||||
import kotlinx.coroutines.*
|
||||
import retrofit2.Response
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import javax.inject.Inject
|
||||
@ -73,7 +74,9 @@ class LoginViewModel @Inject constructor(
|
||||
//是不是登录成功
|
||||
val loginStatus: MutableLiveData<LoginStatus> = MutableLiveData()
|
||||
|
||||
var jobLogin: Job? = null;
|
||||
var jobLogin: Job? = null
|
||||
|
||||
var sharedPreferences: SharedPreferences? = null
|
||||
|
||||
init {
|
||||
loginUser.value = LoginUserBean(userCode = "haofuyue00213", passWord = "123456")
|
||||
@ -98,10 +101,26 @@ class LoginViewModel @Inject constructor(
|
||||
if (password.isEmpty()) {
|
||||
Toast.makeText(context, "请输入密码", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
sharedPreferences =
|
||||
context.getSharedPreferences("USER_SHAREDPREFERENCES", Context.MODE_PRIVATE)
|
||||
val userNameCache = sharedPreferences?.getString("userName", null)
|
||||
val passwordCache = sharedPreferences?.getString("passWord", null)
|
||||
val userCodeCache = sharedPreferences?.getString("userCode", null)
|
||||
//增加缓存记录,不用每次连接网络登录
|
||||
if (userNameCache != null && passwordCache != null && userCodeCache != null) {
|
||||
if (userNameCache == userName && passwordCache == password) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
createUserFolder(context, userCodeCache)
|
||||
loginStatus.postValue(LoginStatus.LOGIN_STATUS_SUCCESS)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
//不指定IO,会在主线程里运行
|
||||
jobLogin = viewModelScope.launch(Dispatchers.IO) {
|
||||
loginCheck(context, userName, password)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -115,25 +134,33 @@ class LoginViewModel @Inject constructor(
|
||||
loginStatus.postValue(LoginStatus.LOGIN_STATUS_NET_LOADING)
|
||||
var userCode = "99999";
|
||||
//登录访问
|
||||
when (val result = networkService.loginUser(LoginUserBean(userName,password))) {
|
||||
is NetResult.Success<*> ->{
|
||||
if (result.data!=null) {
|
||||
when (val result = networkService.loginUser(LoginUserBean(userName, password))) {
|
||||
is NetResult.Success<*> -> {
|
||||
if (result.data != null) {
|
||||
try {
|
||||
val defaultUserResponse = result.data as DefaultResponse<SysUserBean>
|
||||
if(defaultUserResponse.success){
|
||||
if(defaultUserResponse.obj==null|| defaultUserResponse.obj!!.userCode==null){
|
||||
if (defaultUserResponse.success) {
|
||||
if (defaultUserResponse.obj == null || defaultUserResponse.obj!!.userCode == null) {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(context, "服务返回用户Code信息错误", Toast.LENGTH_SHORT)
|
||||
Toast.makeText(
|
||||
context,
|
||||
"服务返回用户Code信息错误",
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
.show()
|
||||
}
|
||||
loginStatus.postValue(LoginStatus.LOGIN_STATUS_CANCEL)
|
||||
return
|
||||
}else{
|
||||
} else {
|
||||
userCode = defaultUserResponse.obj?.userCode.toString()
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(context, "${defaultUserResponse.msg}", Toast.LENGTH_SHORT)
|
||||
Toast.makeText(
|
||||
context,
|
||||
"${defaultUserResponse.msg}",
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
.show()
|
||||
}
|
||||
loginStatus.postValue(LoginStatus.LOGIN_STATUS_CANCEL)
|
||||
@ -145,7 +172,8 @@ class LoginViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
is NetResult.Error<*> ->{
|
||||
|
||||
is NetResult.Error<*> -> {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(context, "${result.exception.message}", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
@ -153,7 +181,8 @@ class LoginViewModel @Inject constructor(
|
||||
loginStatus.postValue(LoginStatus.LOGIN_STATUS_CANCEL)
|
||||
return
|
||||
}
|
||||
is NetResult.Failure<*> ->{
|
||||
|
||||
is NetResult.Failure<*> -> {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(context, "${result.code}:${result.msg}", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
@ -161,12 +190,16 @@ class LoginViewModel @Inject constructor(
|
||||
loginStatus.postValue(LoginStatus.LOGIN_STATUS_CANCEL)
|
||||
return
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
|
||||
//文件夹初始化
|
||||
try {
|
||||
loginStatus.postValue(LoginStatus.LOGIN_STATUS_FOLDER_INIT)
|
||||
sharedPreferences?.edit()?.putString("userName", userName)?.commit()
|
||||
sharedPreferences?.edit()?.putString("passWord", password)?.commit()
|
||||
sharedPreferences?.edit()?.putString("userCode", userCode)?.commit()
|
||||
createUserFolder(context, userCode)
|
||||
} catch (e: IOException) {
|
||||
loginStatus.postValue(LoginStatus.LOGIN_STATUS_FOLDER_FAILURE)
|
||||
@ -185,18 +218,21 @@ class LoginViewModel @Inject constructor(
|
||||
roomAppDatabase.getOfflineMapDao().insertOrUpdate(result.data)
|
||||
}
|
||||
}
|
||||
|
||||
is NetResult.Error<*> -> {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(context, "${result.exception.message}", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
is NetResult.Failure<*> -> {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(context, "${result.code}:${result.msg}", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
is NetResult.Loading -> {}
|
||||
else -> {}
|
||||
}
|
||||
@ -234,7 +270,7 @@ class LoginViewModel @Inject constructor(
|
||||
// 拷贝配置文件到用户目录下
|
||||
val omdbConfigFile = File(userFolder.absolutePath, Constant.OMDB_CONFIG);
|
||||
// if (!omdbConfigFile.exists()) {
|
||||
ResourceUtils.copyFileFromAssets(Constant.OMDB_CONFIG, omdbConfigFile.absolutePath)
|
||||
ResourceUtils.copyFileFromAssets(Constant.OMDB_CONFIG, omdbConfigFile.absolutePath)
|
||||
// }
|
||||
}
|
||||
|
||||
|
@ -20,11 +20,13 @@ import androidx.navigation.findNavController
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.navinfo.collect.library.data.entity.NiLocation
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import com.navinfo.omqs.Constant
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.bean.ImportConfig
|
||||
import com.navinfo.omqs.bean.SignBean
|
||||
import com.navinfo.omqs.bean.TraceVideoBean
|
||||
import com.navinfo.omqs.databinding.ActivityMainBinding
|
||||
import com.navinfo.omqs.http.offlinemapdownload.OfflineMapDownloadManager
|
||||
import com.navinfo.omqs.tools.LayerConfigUtils
|
||||
@ -34,12 +36,14 @@ import com.navinfo.omqs.ui.fragment.offlinemap.OfflineMapFragment
|
||||
import com.navinfo.omqs.ui.fragment.qsrecordlist.QsRecordListFragment
|
||||
import com.navinfo.omqs.ui.fragment.signMoreInfo.SignMoreInfoFragment
|
||||
import com.navinfo.omqs.ui.fragment.tasklist.TaskManagerFragment
|
||||
import com.navinfo.omqs.ui.other.BaseToast
|
||||
import com.navinfo.omqs.ui.widget.RecyclerViewSpacesItemDecoration
|
||||
import com.navinfo.omqs.util.FlowEventBus
|
||||
import com.navinfo.omqs.util.SpeakMode
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
import org.oscim.core.GeoPoint
|
||||
import org.oscim.layers.marker.MarkerItem
|
||||
import org.oscim.renderer.GLViewport
|
||||
import org.videolan.vlc.Util
|
||||
import java.math.BigDecimal
|
||||
@ -179,6 +183,7 @@ class MainActivity : BaseActivity() {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
voiceOnTouchStart()//Do Something
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_UP -> {
|
||||
voiceOnTouchStop()//Do Something
|
||||
}
|
||||
@ -228,10 +233,18 @@ class MainActivity : BaseActivity() {
|
||||
)
|
||||
}
|
||||
|
||||
//捕捉列表变化回调
|
||||
//捕捉轨迹点
|
||||
viewModel.liveDataNILocationList.observe(this) {
|
||||
if (viewModel.isSelectTrace()) {
|
||||
Toast.makeText(this, "轨迹被点击了", Toast.LENGTH_LONG).show()
|
||||
//Toast.makeText(this,"轨迹被点击了",Toast.LENGTH_LONG).show()
|
||||
viewModel.showMarker(this, it)
|
||||
viewModel.setCurrentIndexNiLocation(it)
|
||||
val traceVideoBean = TraceVideoBean(
|
||||
command = "videotime?",
|
||||
userid = Constant.USER_ID,
|
||||
time = "${it.time}:000"
|
||||
)
|
||||
viewModel.sendServerCommand(this, traceVideoBean, IndoorToolsCommand.SELECT_POINT)
|
||||
}
|
||||
}
|
||||
|
||||
@ -311,6 +324,55 @@ class MainActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.liveIndoorToolsResp.observe(this) {
|
||||
when (it) {
|
||||
IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_SUCCESS -> {
|
||||
|
||||
if (viewModel.indoorToolsCommand == IndoorToolsCommand.SELECT_POINT) {
|
||||
selectPointFinish(true)
|
||||
}
|
||||
//启动自动播放
|
||||
if (viewModel.indoorToolsCommand == IndoorToolsCommand.PLAY) {
|
||||
viewModel.startTimer()
|
||||
}
|
||||
}
|
||||
|
||||
IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_FAILURE -> {
|
||||
if (viewModel.indoorToolsCommand == IndoorToolsCommand.SELECT_POINT) {
|
||||
selectPointFinish(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//室内整理工具反向控制
|
||||
viewModel.liveIndoorToolsCommand.observe(this) {
|
||||
when (it) {
|
||||
IndoorToolsCommand.PLAY -> {
|
||||
setPlayStatus()
|
||||
}
|
||||
|
||||
IndoorToolsCommand.INDEXING -> {
|
||||
pausePlayTrace()
|
||||
}
|
||||
|
||||
IndoorToolsCommand.SELECT_POINT -> {
|
||||
|
||||
}
|
||||
|
||||
IndoorToolsCommand.NEXT -> {
|
||||
}
|
||||
|
||||
IndoorToolsCommand.REWIND -> {
|
||||
}
|
||||
|
||||
IndoorToolsCommand.STOP -> {
|
||||
//切换为暂停状态
|
||||
pausePlayTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lifecycleScope.launch {
|
||||
// 初始化地图图层控制接收器
|
||||
FlowEventBus.subscribe<List<ImportConfig>>(
|
||||
@ -330,8 +392,13 @@ class MainActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
supportFragmentManager.beginTransaction()
|
||||
.add(R.id.console_fragment_layout, ConsoleFragment()).commit()
|
||||
//自动连接相机
|
||||
if (viewModel.isAutoCamera()) {
|
||||
viewModel.autoCamera()
|
||||
} else {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.add(R.id.console_fragment_layout, ConsoleFragment()).commit()
|
||||
}
|
||||
}
|
||||
|
||||
//根据输入的经纬度跳转坐标
|
||||
@ -534,10 +601,14 @@ class MainActivity : BaseActivity() {
|
||||
*/
|
||||
fun tracePointsOnclick() {
|
||||
viewModel.setSelectTrace(!viewModel.isSelectTrace())
|
||||
binding.mainActivityTraceSnapshotPoints.isSelected = viewModel.isSelectTrace()
|
||||
|
||||
if (viewModel.isSelectTrace()) {
|
||||
Toast.makeText(this, "请选择轨迹点!", Toast.LENGTH_LONG).show()
|
||||
//调用撤销自动播放
|
||||
setViewEnable(false)
|
||||
viewModel.cancelTrace()
|
||||
}
|
||||
binding.mainActivityTraceSnapshotPoints.isSelected = viewModel.isSelectTrace()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -548,8 +619,9 @@ class MainActivity : BaseActivity() {
|
||||
viewModel.setSelectTrace(false)
|
||||
viewModel.setMediaFlag(false)
|
||||
viewModel.setSelectPauseTrace(false)
|
||||
binding.mainActivityMenuIndoorGroup.visibility = View.GONE
|
||||
binding.mainActivityTraceSnapshotPoints.isSelected = viewModel.isSelectTrace()
|
||||
binding.mainActivitySnapshotMediaFlag.isSelected = viewModel.isMediaFlag()
|
||||
//binding.mainActivitySnapshotMediaFlag.isSelected = viewModel.isMediaFlag()
|
||||
binding.mainActivitySnapshotPause.isSelected = viewModel.isSelectPauseTrace()
|
||||
}
|
||||
|
||||
@ -557,15 +629,29 @@ class MainActivity : BaseActivity() {
|
||||
* 点击结束轨迹操作
|
||||
*/
|
||||
fun mediaFlagOnclick() {
|
||||
viewModel.setMediaFlag(!viewModel.isMediaFlag())
|
||||
binding.mainActivitySnapshotMediaFlag.isSelected = viewModel.isMediaFlag()
|
||||
/* viewModel.setMediaFlag(!viewModel.isMediaFlag())
|
||||
binding.mainActivitySnapshotMediaFlag.isSelected = viewModel.isMediaFlag()*/
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击上一个轨迹点播放操作
|
||||
*/
|
||||
fun rewindTraceOnclick() {
|
||||
pasePlayTrace()
|
||||
pausePlayTrace()
|
||||
val item =
|
||||
mapController.markerHandle.getNILocation(viewModel.getCurrentNiLocationIndex() - 1)
|
||||
if (item != null) {
|
||||
viewModel.setCurrentIndexLoction(viewModel.getCurrentNiLocationIndex() - 1)
|
||||
viewModel.showMarker(this, item)
|
||||
val traceVideoBean = TraceVideoBean(
|
||||
command = "videotime?",
|
||||
userid = Constant.USER_ID,
|
||||
time = "${item.time}:000"
|
||||
)
|
||||
viewModel.sendServerCommand(this, traceVideoBean, IndoorToolsCommand.REWIND)
|
||||
} else {
|
||||
dealNoData()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -576,13 +662,74 @@ class MainActivity : BaseActivity() {
|
||||
binding.mainActivitySnapshotPause.isSelected = viewModel.isSelectPauseTrace()
|
||||
viewModel.setSelectTrace(false)
|
||||
binding.mainActivityTraceSnapshotPoints.isSelected = viewModel.isSelectTrace()
|
||||
if (viewModel.isSelectPauseTrace()) {
|
||||
playVideo()
|
||||
} else {
|
||||
pauseVideo()
|
||||
viewModel.cancelTrace()
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
fun playVideo() {
|
||||
if (mapController.markerHandle.getCurrentMark() == null) {
|
||||
BaseToast.makeText(this, "请先选择轨迹点!", BaseToast.LENGTH_SHORT).show()
|
||||
return
|
||||
}
|
||||
viewModel.setSelectTrace(false)
|
||||
binding.mainActivityTraceSnapshotPoints.isSelected = viewModel.isSelectTrace()
|
||||
val traceVideoBean = TraceVideoBean(command = "playVideo?", userid = Constant.USER_ID)
|
||||
viewModel.sendServerCommand(this, traceVideoBean, IndoorToolsCommand.PLAY)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置为播放状态
|
||||
*/
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
fun setPlayStatus() {
|
||||
//切换为播放
|
||||
viewModel.setSelectPauseTrace(true)
|
||||
binding.mainActivitySnapshotPause.isSelected = viewModel.isSelectPauseTrace()
|
||||
playVideo()
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
fun pauseVideo() {
|
||||
val traceVideoBean = TraceVideoBean(command = "pauseVideo?", userid = Constant.USER_ID)
|
||||
viewModel.sendServerCommand(this, traceVideoBean, IndoorToolsCommand.STOP)
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击下一个轨迹点
|
||||
*/
|
||||
fun nextTraceOnclick() {
|
||||
pasePlayTrace()
|
||||
pausePlayTrace()
|
||||
val item =
|
||||
mapController.markerHandle.getNILocation(viewModel.getCurrentNiLocationIndex() + 1)
|
||||
if (item != null) {
|
||||
viewModel.setCurrentIndexLoction(viewModel.getCurrentNiLocationIndex() + 1)
|
||||
viewModel.showMarker(this, item)
|
||||
val traceVideoBean = TraceVideoBean(
|
||||
command = "videotime?",
|
||||
userid = Constant.USER_ID,
|
||||
time = "${item.time}:000"
|
||||
)
|
||||
viewModel.sendServerCommand(this, traceVideoBean, IndoorToolsCommand.NEXT)
|
||||
} else {
|
||||
dealNoData()
|
||||
}
|
||||
}
|
||||
|
||||
private fun dealNoData() {
|
||||
BaseToast.makeText(this, "无数据了!", Toast.LENGTH_SHORT).show()
|
||||
|
||||
//无数据时自动暂停播放,并停止轨迹
|
||||
if (viewModel.isSelectPauseTrace()) {
|
||||
pauseVideo()
|
||||
viewModel.cancelTrace()
|
||||
viewModel.setSelectPauseTrace(false)
|
||||
binding.mainActivitySnapshotPause.isSelected = viewModel.isSelectPauseTrace()
|
||||
}
|
||||
}
|
||||
|
||||
fun pasePlayTrace() {
|
||||
@ -590,6 +737,27 @@ class MainActivity : BaseActivity() {
|
||||
binding.mainActivityTraceSnapshotPoints.isSelected = viewModel.isSelectTrace()
|
||||
viewModel.setSelectPauseTrace(false)
|
||||
binding.mainActivitySnapshotPause.isSelected = viewModel.isSelectPauseTrace()
|
||||
viewModel.cancelTrace()
|
||||
}
|
||||
|
||||
/**
|
||||
* 选点结束
|
||||
* @param value true 选点成功 false 选点失败
|
||||
*/
|
||||
private fun selectPointFinish(value: Boolean) {
|
||||
if (value) {
|
||||
setViewEnable(true)
|
||||
viewModel.setSelectPauseTrace(false)
|
||||
binding.mainActivitySnapshotPause.isSelected = viewModel.isSelectPauseTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setViewEnable(value: Boolean) {
|
||||
binding.mainActivitySnapshotRewind.isEnabled = value
|
||||
binding.mainActivitySnapshotNext.isEnabled = value
|
||||
binding.mainActivitySnapshotPause.isEnabled = value
|
||||
binding.mainActivitySnapshotFinish.isEnabled = value
|
||||
viewModel.cancelTrace()
|
||||
}
|
||||
|
||||
|
||||
@ -686,7 +854,7 @@ class MainActivity : BaseActivity() {
|
||||
private fun setIndoorGroupEnable(enable: Boolean) {
|
||||
binding.mainActivitySnapshotFinish.isEnabled = enable
|
||||
binding.mainActivityTraceSnapshotPoints.isEnabled = enable
|
||||
binding.mainActivitySnapshotMediaFlag.isEnabled = enable
|
||||
//binding.mainActivitySnapshotMediaFlag.isEnabled = enable
|
||||
binding.mainActivitySnapshotRewind.isEnabled = enable
|
||||
binding.mainActivitySnapshotPause.isEnabled = enable
|
||||
binding.mainActivitySnapshotNext.isEnabled = enable
|
||||
|
@ -15,31 +15,39 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.PopupWindow
|
||||
import android.widget.Toast
|
||||
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.blankj.utilcode.util.ViewUtils.runOnUiThread
|
||||
import com.navinfo.collect.library.data.dao.impl.TraceDataBase
|
||||
import com.navinfo.collect.library.data.entity.*
|
||||
import com.navinfo.collect.library.garminvirbxe.HostBean
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import com.navinfo.collect.library.map.OnGeoPointClickListener
|
||||
import com.navinfo.collect.library.map.handler.ONNoteItemClickListener
|
||||
import com.navinfo.collect.library.map.handler.OnNiLocationItemListener
|
||||
import com.navinfo.collect.library.map.handler.OnQsRecordItemClickListener
|
||||
import com.navinfo.collect.library.map.handler.OnTaskLinkItemClickListener
|
||||
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.bean.ImportConfig
|
||||
import com.navinfo.omqs.bean.QRCodeBean
|
||||
import com.navinfo.omqs.bean.SignBean
|
||||
import com.navinfo.omqs.bean.TraceVideoBean
|
||||
import com.navinfo.omqs.db.RealmOperateHelper
|
||||
import com.navinfo.omqs.http.NetResult
|
||||
import com.navinfo.omqs.http.NetworkService
|
||||
import com.navinfo.omqs.ui.dialog.CommonDialog
|
||||
import com.navinfo.omqs.ui.manager.TakePhotoManager
|
||||
import com.navinfo.omqs.ui.other.BaseToast
|
||||
import com.navinfo.omqs.ui.widget.SignUtil
|
||||
import com.navinfo.omqs.util.DateTimeUtil
|
||||
import com.navinfo.omqs.util.ShareUtil
|
||||
import com.navinfo.omqs.util.SoundMeter
|
||||
import com.navinfo.omqs.util.SpeakMode
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
@ -52,11 +60,14 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.oscim.core.GeoPoint
|
||||
import org.oscim.core.MapPosition
|
||||
import org.oscim.layers.marker.MarkerItem
|
||||
import org.oscim.map.Map
|
||||
import org.videolan.libvlc.LibVlcUtil
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import kotlin.concurrent.fixedRateTimer
|
||||
|
||||
/**
|
||||
* 创建Activity全局viewmode
|
||||
@ -67,8 +78,9 @@ class MainViewModel @Inject constructor(
|
||||
private val mapController: NIMapController,
|
||||
private val traceDataBase: TraceDataBase,
|
||||
private val realmOperateHelper: RealmOperateHelper,
|
||||
private val networkService: NetworkService,
|
||||
private val sharedPreferences: SharedPreferences
|
||||
) : ViewModel(), SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
) : ViewModel(), SocketServer.OnConnectSinsListener, SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
private val TAG = "MainViewModel"
|
||||
|
||||
@ -100,6 +112,8 @@ class MainViewModel @Inject constructor(
|
||||
*/
|
||||
val liveDataSignMoreInfo = MutableLiveData<RenderEntity>()
|
||||
|
||||
private var traceTag: String = "TRACE_TAG"
|
||||
|
||||
/**
|
||||
* 右上角菜单状态
|
||||
*/
|
||||
@ -131,6 +145,12 @@ class MainViewModel @Inject constructor(
|
||||
|
||||
var currentTaskBean: TaskBean? = null
|
||||
|
||||
//状态
|
||||
val liveIndoorToolsResp: MutableLiveData<IndoorToolsResp> = MutableLiveData()
|
||||
|
||||
//状态
|
||||
val liveIndoorToolsCommand: MutableLiveData<IndoorToolsCommand> = MutableLiveData()
|
||||
|
||||
/**
|
||||
* 是不是线选择模式
|
||||
*/
|
||||
@ -155,6 +175,18 @@ class MainViewModel @Inject constructor(
|
||||
|
||||
private var lastNiLocaion: NiLocation? = null
|
||||
|
||||
private var currentIndexNiLocation: Int = 0
|
||||
|
||||
private var socketServer: SocketServer? = null
|
||||
|
||||
var indoorToolsCommand: IndoorToolsCommand? = null
|
||||
|
||||
private var shareUtil: ShareUtil? = null
|
||||
|
||||
private var timer: Timer? = null
|
||||
|
||||
private var disTime :Long = 1000
|
||||
|
||||
init {
|
||||
|
||||
mapController.mMapView.vtmMap.events.bind(Map.UpdateListener { e, mapPosition ->
|
||||
@ -164,6 +196,9 @@ class MainViewModel @Inject constructor(
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
shareUtil = ShareUtil(mapController.mMapView.context, 1)
|
||||
|
||||
initLocation()
|
||||
/**
|
||||
* 处理点击道路捕捉回调功能
|
||||
@ -231,6 +266,7 @@ class MainViewModel @Inject constructor(
|
||||
initNILocationData()
|
||||
}
|
||||
sharedPreferences.registerOnSharedPreferenceChangeListener(this)
|
||||
socketServer = SocketServer(mapController, traceDataBase, sharedPreferences)
|
||||
}
|
||||
|
||||
|
||||
@ -310,21 +346,10 @@ class MainViewModel @Inject constructor(
|
||||
* 初始化定位信息
|
||||
*/
|
||||
private fun initLocation() {
|
||||
|
||||
//用于定位点存储到数据库
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
//用于定位点捕捉道路
|
||||
mapController.locationLayerHandler.niLocationFlow.collectLatest { location ->
|
||||
if (!isSelectRoad() && !GeometryTools.isCheckError(
|
||||
location.longitude, location.latitude
|
||||
)
|
||||
) {
|
||||
captureLink(
|
||||
GeoPoint(
|
||||
location.latitude, location.longitude
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
mapController.locationLayerHandler.niLocationFlow.collect { location ->
|
||||
|
||||
//过滤掉无效点
|
||||
@ -354,34 +379,52 @@ class MainViewModel @Inject constructor(
|
||||
}
|
||||
val id = sharedPreferences.getInt(Constant.SELECT_TASK_ID, -1)
|
||||
location.taskId = id.toString()
|
||||
if (shareUtil?.connectstate == true) {
|
||||
location.media = 1
|
||||
}
|
||||
var disance = 0.0
|
||||
//增加间距判断
|
||||
if (lastNiLocaion != null) {
|
||||
val disance = GeometryTools.getDistance(
|
||||
location.latitude,
|
||||
location.longitude,
|
||||
lastNiLocaion!!.latitude,
|
||||
lastNiLocaion!!.longitude
|
||||
disance = GeometryTools.getDistance(
|
||||
location.latitude, location.longitude,
|
||||
lastNiLocaion!!.latitude, lastNiLocaion!!.longitude
|
||||
)
|
||||
//相距差距大于2.5米以上进行存储
|
||||
if (disance > 2.5) {
|
||||
traceDataBase.niLocationDao.insert(location)
|
||||
mapController.markerHandle.addNiLocationMarkerItem(location)
|
||||
mapController.mMapView.vtmMap.updateMap(true)
|
||||
lastNiLocaion = location
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
//室内整理工具时不能进行轨迹存储,判断轨迹间隔要超过2.5并小于60米
|
||||
if (Constant.INDOOR_IP.isEmpty() && (disance == 0.0 || (disance > 2.5 && disance < 60))) {
|
||||
traceDataBase.niLocationDao.insert(location)
|
||||
/* mapController.markerHandle.addNiLocationMarkerItem(location)
|
||||
mapController.mMapView.vtmMap.updateMap(true)*/
|
||||
mapController.markerHandle.addNiLocationMarkerItem(location)
|
||||
mapController.mMapView.vtmMap.updateMap(true)
|
||||
lastNiLocaion = location
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
//用于定位点捕捉道路
|
||||
mapController.locationLayerHandler.niLocationFlow.collectLatest { location ->
|
||||
if (!isSelectRoad() && !GeometryTools.isCheckError(
|
||||
location.longitude, location.latitude
|
||||
)
|
||||
) {
|
||||
captureLink(
|
||||
GeoPoint(
|
||||
location.latitude, location.longitude
|
||||
)
|
||||
)
|
||||
}
|
||||
withContext(Dispatchers.Main){
|
||||
if(Constant.AUTO_LOCATION){
|
||||
mapController.mMapView.vtmMap.animator()
|
||||
.animateTo(GeoPoint( location.longitude, location.latitude))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//显示轨迹图层
|
||||
mapController.layerManagerHandler.showNiLocationLayer()
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -528,17 +571,8 @@ class MainViewModel @Inject constructor(
|
||||
|
||||
Log.e("qj", LibVlcUtil.hasCompatibleCPU(context).toString())
|
||||
|
||||
if (mCameraDialog == null) {
|
||||
mCameraDialog = CommonDialog(
|
||||
context,
|
||||
context.resources.getDimension(R.dimen.head_img_width)
|
||||
.toInt() * 3 + context.resources.getDimension(R.dimen.ten)
|
||||
.toInt() + context.resources.getDimension(R.dimen.twenty_four).toInt(),
|
||||
context.resources.getDimension(R.dimen.head_img_width).toInt() + 10,
|
||||
1
|
||||
)
|
||||
mCameraDialog!!.setCancelable(true)
|
||||
}
|
||||
initCameraDialog(context)
|
||||
|
||||
mCameraDialog!!.openCamear(mCameraDialog!!.getmShareUtil().continusTakePhotoState)
|
||||
mCameraDialog!!.show()
|
||||
mCameraDialog!!.setOnDismissListener(DialogInterface.OnDismissListener {
|
||||
@ -563,6 +597,20 @@ class MainViewModel @Inject constructor(
|
||||
})
|
||||
}
|
||||
|
||||
private fun initCameraDialog(context:Context){
|
||||
if (mCameraDialog == null) {
|
||||
mCameraDialog = CommonDialog(
|
||||
context,
|
||||
context.resources.getDimension(R.dimen.head_img_width)
|
||||
.toInt() * 3 + context.resources.getDimension(R.dimen.ten)
|
||||
.toInt() + context.resources.getDimension(R.dimen.twenty_four).toInt(),
|
||||
context.resources.getDimension(R.dimen.head_img_width).toInt() + 10,
|
||||
1
|
||||
)
|
||||
mCameraDialog!!.setCancelable(true)
|
||||
}
|
||||
}
|
||||
|
||||
fun startSoundMetter(context: Context, v: View) {
|
||||
|
||||
//语音识别动画
|
||||
@ -727,5 +775,246 @@ class MainViewModel @Inject constructor(
|
||||
liveDataSignMoreInfo.value = data
|
||||
}
|
||||
|
||||
fun sendServerCommand(
|
||||
context: Context,
|
||||
traceVideoBean: TraceVideoBean,
|
||||
indoorToolsCommand: IndoorToolsCommand
|
||||
) {
|
||||
|
||||
if (TextUtils.isEmpty(Constant.INDOOR_IP)) {
|
||||
Toast.makeText(context, "获取ip失败!", Toast.LENGTH_LONG).show()
|
||||
return
|
||||
}
|
||||
|
||||
this.indoorToolsCommand = indoorToolsCommand
|
||||
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
val url = "http://${Constant.INDOOR_IP}:8080/sensor/service/${traceVideoBean.command}?"
|
||||
|
||||
when (val result = networkService.sendServerCommand(
|
||||
url = url,
|
||||
traceVideoBean = traceVideoBean
|
||||
)) {
|
||||
is NetResult.Success<*> -> {
|
||||
|
||||
if (result.data != null) {
|
||||
try {
|
||||
|
||||
val defaultUserResponse = result.data as QRCodeBean
|
||||
|
||||
if (defaultUserResponse.errcode == 0) {
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
"命令成功。",
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
|
||||
liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_SUCCESS)
|
||||
|
||||
//启动双向控制服务
|
||||
|
||||
//启动双向控制服务
|
||||
if (socketServer != null && socketServer!!.isServerClose) {
|
||||
socketServer!!.connect(
|
||||
Constant.INDOOR_IP,
|
||||
this@MainViewModel
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
"命令无效${defaultUserResponse.errmsg}",
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
.show()
|
||||
}
|
||||
liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_FAILURE)
|
||||
}
|
||||
|
||||
} catch (e: IOException) {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
"${e.message}",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is NetResult.Error<*> -> {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
"${result.exception.message}",
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
.show()
|
||||
}
|
||||
liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_FAILURE)
|
||||
}
|
||||
|
||||
is NetResult.Failure<*> -> {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
"${result.code}:${result.msg}",
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
.show()
|
||||
}
|
||||
liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_FAILURE)
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示marker
|
||||
* @param trackCollection 轨迹点
|
||||
* @param type 1 提示最后一个轨迹点 非1提示第一个轨迹点
|
||||
*/
|
||||
fun showMarker(context: Context, niLocation: NiLocation) {
|
||||
if (mapController.markerHandle != null) {
|
||||
mapController.markerHandle.removeMarker(traceTag)
|
||||
if (niLocation != null) {
|
||||
mapController.markerHandle.addMarker(
|
||||
GeoPoint(
|
||||
niLocation.latitude,
|
||||
niLocation.longitude
|
||||
), traceTag, "", niLocation as java.lang.Object
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示索引位置
|
||||
* @param niLocation 轨迹点
|
||||
*/
|
||||
fun setCurrentIndexNiLocation(niLocation: NiLocation) {
|
||||
viewModelScope.launch ( Dispatchers.IO ){
|
||||
Log.e("qj","开始$currentIndexNiLocation")
|
||||
currentIndexNiLocation = mapController.markerHandle.getNILocationIndex(niLocation)!!
|
||||
Log.e("qj","结束$currentIndexNiLocation")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置索引位置
|
||||
* @param index 索引
|
||||
*/
|
||||
fun setCurrentIndexLoction(index: Int) {
|
||||
currentIndexNiLocation = index
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return index 索引
|
||||
*/
|
||||
fun getCurrentNiLocationIndex(): Int {
|
||||
return currentIndexNiLocation
|
||||
}
|
||||
|
||||
override fun onConnect(success: Boolean) {
|
||||
if (!success && socketServer != null) {
|
||||
BaseToast.makeText(
|
||||
mapController.mMapView.context,
|
||||
"轨迹反向控制服务失败,请确认连接是否正常!",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onIndexing() {
|
||||
//切换为暂停状态
|
||||
liveIndoorToolsCommand.postValue(IndoorToolsCommand.INDEXING)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
liveIndoorToolsCommand.postValue(IndoorToolsCommand.STOP)
|
||||
}
|
||||
|
||||
override fun onPlay() {
|
||||
liveIndoorToolsCommand.postValue(IndoorToolsCommand.PLAY)
|
||||
}
|
||||
|
||||
override fun onParseEnd() {
|
||||
|
||||
}
|
||||
|
||||
override fun onReceiveLocation(mNiLocation: NiLocation?) {
|
||||
if (mNiLocation != null) {
|
||||
setCurrentIndexNiLocation(mNiLocation)
|
||||
showMarker(mapController.mMapView.context, mNiLocation)
|
||||
Log.e("qj","反向控制$currentIndexNiLocation")
|
||||
} else {
|
||||
BaseToast.makeText(
|
||||
mapController.mMapView.context,
|
||||
"没有找到对应轨迹点!",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
fun isAutoCamera():Boolean{
|
||||
|
||||
return shareUtil?.connectstate == true
|
||||
}
|
||||
|
||||
fun autoCamera(){
|
||||
if (shareUtil?.connectstate == true) {
|
||||
val hostBean1 = HostBean()
|
||||
hostBean1.ipAddress = shareUtil!!.takeCameraIP
|
||||
hostBean1.hardwareAddress = shareUtil!!.takeCameraMac
|
||||
onClickCameraButton(mapController.mMapView.context)
|
||||
mCameraDialog?.connection(hostBean1)
|
||||
}
|
||||
}
|
||||
|
||||
fun startTimer() {
|
||||
if(timer!=null){
|
||||
cancelTrace()
|
||||
}
|
||||
timer = fixedRateTimer("", false, disTime, disTime) {
|
||||
if(currentIndexNiLocation<mapController.markerHandle.getNILocationItemizedLayerSize()){
|
||||
Log.e("qj","定时器")
|
||||
val niLocation = mapController.markerHandle.getNILocation(currentIndexNiLocation)
|
||||
val nextNiLocation = mapController.markerHandle.getNILocation(currentIndexNiLocation+1)
|
||||
if(nextNiLocation!=null&&niLocation!=null){
|
||||
var nilocationDisTime = nextNiLocation.timeStamp.toLong() - niLocation.timeStamp.toLong()
|
||||
disTime = if(nilocationDisTime<1000){
|
||||
1000
|
||||
}else{
|
||||
nilocationDisTime
|
||||
}
|
||||
showMarker(mapController.mMapView.context,nextNiLocation)
|
||||
currentIndexNiLocation += 1
|
||||
//再次启动
|
||||
startTimer()
|
||||
}
|
||||
}else{
|
||||
Toast.makeText(mapController.mMapView.context,"无数据了!",Toast.LENGTH_LONG).show()
|
||||
cancelTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束自动播放
|
||||
*/
|
||||
fun cancelTrace() {
|
||||
timer?.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,606 @@
|
||||
package com.navinfo.omqs.ui.activity.map
|
||||
|
||||
import android.app.Service
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Binder
|
||||
import android.os.Handler
|
||||
import android.os.IBinder
|
||||
import android.os.Message
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import com.navinfo.collect.library.data.dao.impl.TraceDataBase
|
||||
import com.navinfo.collect.library.data.entity.NiLocation
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import com.navinfo.omqs.Constant
|
||||
import com.navinfo.omqs.util.DateTimeUtil
|
||||
import org.json.JSONObject
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.io.Serializable
|
||||
import java.net.Socket
|
||||
import java.util.Collections
|
||||
import kotlin.math.abs
|
||||
|
||||
|
||||
enum class IndoorToolsCommand {
|
||||
PLAY,
|
||||
SELECT_POINT,
|
||||
INDEXING,
|
||||
NEXT,
|
||||
REWIND,
|
||||
STOP
|
||||
}
|
||||
|
||||
enum class IndoorToolsResp{
|
||||
/**
|
||||
* 信息更新轨迹成功
|
||||
*/
|
||||
QR_CODE_STATUS_UPDATE_VIDEO_INFO_SUCCESS,
|
||||
|
||||
/**
|
||||
* 信息更新轨迹失败
|
||||
*/
|
||||
QR_CODE_STATUS_UPDATE_VIDEO_INFO_FAILURE,
|
||||
}
|
||||
|
||||
/**
|
||||
* @author qj
|
||||
* @version V1.0
|
||||
* @Date 2018/4/18.
|
||||
* @Description: 轨迹反向控制服务
|
||||
*/
|
||||
class SocketServer(
|
||||
private val mapController: NIMapController,
|
||||
private val traceDataBase: TraceDataBase,
|
||||
private val sharedPreferences: SharedPreferences
|
||||
) : Service() {
|
||||
//类标识
|
||||
private val TAG = "SocketServer"
|
||||
|
||||
//线程池
|
||||
private val threadConnect = ThreadLocal<Socket>()
|
||||
|
||||
//读的线程
|
||||
private var tRecv: RecvThread? = null
|
||||
|
||||
//解析线程
|
||||
private var tParse: ParseThread? = null
|
||||
|
||||
//输出流
|
||||
private var outStr: OutputStream? = null
|
||||
|
||||
//输入流
|
||||
private var inStr: InputStream? = null
|
||||
|
||||
//状态
|
||||
var connectstatus = false
|
||||
|
||||
//socket
|
||||
private var client: Socket? = null
|
||||
|
||||
//接收缓存
|
||||
private val sData = ByteArray(512)
|
||||
|
||||
//反馈接口
|
||||
private var mListener: OnConnectSinsListener? = null
|
||||
|
||||
//服务
|
||||
private val mBinder: MyBinder = MyBinder()
|
||||
|
||||
//接收集合
|
||||
private val mTaskList = Collections.synchronizedList(ArrayList<String>())
|
||||
|
||||
//连接线程
|
||||
private var connectThread: Thread? = null
|
||||
|
||||
//缓存ip
|
||||
private var lastIp = ""
|
||||
private val mHandler: Handler = object : Handler() {
|
||||
override fun handleMessage(msg: Message) {
|
||||
when (msg.what) {
|
||||
0x11 -> if (mListener != null) {
|
||||
if (msg.obj != null && msg.obj is NiLocation) {
|
||||
mListener!!.onReceiveLocation(msg.obj as NiLocation)
|
||||
} else {
|
||||
mListener!!.onReceiveLocation(null)
|
||||
}
|
||||
}
|
||||
|
||||
0x22 -> //索引定位中
|
||||
if (mListener != null) {
|
||||
mListener!!.onIndexing()
|
||||
}
|
||||
|
||||
0x33 -> if (mListener != null) {
|
||||
mListener!!.onConnect(true)
|
||||
}
|
||||
|
||||
0x44 -> if (mListener != null) {
|
||||
mListener!!.onConnect(false)
|
||||
}
|
||||
|
||||
0x55 -> if (mListener != null) {
|
||||
mListener!!.onPlay()
|
||||
}
|
||||
|
||||
0x66 -> if (mListener != null) {
|
||||
mListener!!.onStop()
|
||||
}
|
||||
|
||||
0x99 -> if (mListener != null) {
|
||||
mListener!!.onParseEnd()
|
||||
}
|
||||
|
||||
0x999 -> if (mListener != null) {
|
||||
mListener!!.onConnect(false)
|
||||
disconnect()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
|
||||
return super.onStartCommand(intent, flags, startId)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent): IBinder? {
|
||||
return mBinder
|
||||
}
|
||||
|
||||
inner class MyBinder : Binder() {
|
||||
// 返回Activity所关联的Service对象,这样在Activity里,就可调用Service里的一些公用方法 和公用属性
|
||||
val service: SocketServer
|
||||
get() =// 返回Activity所关联的Service对象,这样在Activity里,就可调用Service里的一些公用方法 和公用属性
|
||||
this@SocketServer
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动sock连接
|
||||
*
|
||||
* @param ip
|
||||
* @param listener 结果回调
|
||||
*/
|
||||
fun connect(ip: String, listener: OnConnectSinsListener?) {
|
||||
if (connectThread != null && connectThread!!.isAlive && TextUtils.equals(lastIp, ip)) {
|
||||
return
|
||||
}
|
||||
mListener = listener
|
||||
lastIp = ip
|
||||
connectThread = object : Thread() {
|
||||
override fun run() {
|
||||
try {
|
||||
client = threadConnect.get()
|
||||
if (client == null) {
|
||||
client = Socket(ip, 8010)
|
||||
client!!.soTimeout = 3000000
|
||||
client!!.keepAlive = true
|
||||
threadConnect.set(client)
|
||||
}
|
||||
outStr = client!!.getOutputStream()
|
||||
inStr = client!!.getInputStream()
|
||||
if (tRecv != null) {
|
||||
tRecv!!.cancel()
|
||||
}
|
||||
tRecv = RecvThread()
|
||||
val thread = Thread(tRecv)
|
||||
thread.start()
|
||||
|
||||
//解析线程
|
||||
if (tParse != null) {
|
||||
tParse!!.cancel()
|
||||
}
|
||||
tParse = ParseThread()
|
||||
val parsethread = Thread(tParse)
|
||||
parsethread.start()
|
||||
|
||||
//socket启动成功
|
||||
val msg = Message()
|
||||
msg.what = 0x33
|
||||
mHandler.sendMessage(msg)
|
||||
if (!connectstatus) {
|
||||
connectstatus = true // 更改连接状态
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
//启动失败
|
||||
val msg = Message()
|
||||
msg.what = 0x44
|
||||
mHandler.sendMessage(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
(connectThread as Thread).start()
|
||||
}
|
||||
|
||||
/**
|
||||
* sock是否启动
|
||||
*
|
||||
* @return true 启动 false停止
|
||||
*/
|
||||
val isStart: Boolean
|
||||
get() = if (connectThread != null && connectThread!!.isAlive) {
|
||||
true
|
||||
} else false
|
||||
|
||||
/**
|
||||
* 销毁连接
|
||||
*/
|
||||
fun disconnect() {
|
||||
try {
|
||||
|
||||
//销毁线程
|
||||
if (tRecv != null) {
|
||||
tRecv!!.cancel()
|
||||
}
|
||||
|
||||
//销毁线程
|
||||
if (tParse != null) {
|
||||
tParse!!.cancel()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
try {
|
||||
if (outStr != null) outStr!!.close()
|
||||
if (inStr != null) inStr!!.close()
|
||||
if (client != null) client!!.close()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析接收到得线程
|
||||
*/
|
||||
private inner class ParseThread : Runnable {
|
||||
private var runFlag = true
|
||||
|
||||
//轨迹时间buffer
|
||||
private val traceTimeBuffer = 1500
|
||||
private var timeIndex = 0
|
||||
fun cancel() {
|
||||
runFlag = false
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
try {
|
||||
while (runFlag) {
|
||||
if (mTaskList.size > 0) {
|
||||
timeIndex = mTaskList.size - 1
|
||||
val result = parseResult(mTaskList[timeIndex])
|
||||
var resultNiLocation: NiLocation? = null
|
||||
var index: Int = -1
|
||||
if (result != null) {
|
||||
when (result.type) {
|
||||
1 -> {
|
||||
//先暂停播放
|
||||
val msg = Message()
|
||||
msg.what = 0x22
|
||||
mHandler.sendMessage(msg)
|
||||
val currentTime: Long = DateTimeUtil.getTimePointSSS(
|
||||
result.data
|
||||
)
|
||||
val currentTimeStr: String = DateTimeUtil.TimePointSSSToTime(
|
||||
result.data
|
||||
)
|
||||
|
||||
Log.e(TAG, "反向"+result.data)
|
||||
|
||||
val startTime = currentTime - traceTimeBuffer
|
||||
val endTme = currentTime + traceTimeBuffer
|
||||
|
||||
//转换为数据库时间
|
||||
val startTimeStr: String =
|
||||
DateTimeUtil.getDateSimpleTime(startTime)
|
||||
|
||||
//转换为数据库时间
|
||||
val endTimeStr: String =
|
||||
DateTimeUtil.getDateSimpleTime(endTme)
|
||||
if (!TextUtils.isEmpty(startTimeStr) && !TextUtils.isEmpty(
|
||||
endTimeStr
|
||||
)
|
||||
) {
|
||||
|
||||
Log.e(TAG, "getTraceData开始")
|
||||
|
||||
val list: List<NiLocation>? = getTrackList(startTimeStr, endTimeStr, currentTimeStr)
|
||||
|
||||
Log.e(TAG, "getTraceData结束")
|
||||
|
||||
if (list != null && list.size > 0) {
|
||||
|
||||
var disTime: Long = 0
|
||||
//只有一个点不进行判断直接返回结果
|
||||
if (list.size == 1) {
|
||||
resultNiLocation = list[0]
|
||||
} else {
|
||||
//遍历集合取最近时间的轨迹点
|
||||
b@ for (nilocation in list) {
|
||||
|
||||
if (!TextUtils.isEmpty(nilocation.time)) {
|
||||
|
||||
//只获取到秒的常量
|
||||
val time: Long =
|
||||
nilocation.timeStamp.toLong()
|
||||
|
||||
val disTimeTemp = abs(time - currentTime)
|
||||
|
||||
//如果时间相同直接返回该点
|
||||
if (disTimeTemp == 0L) {
|
||||
resultNiLocation = nilocation
|
||||
break@b
|
||||
} else {
|
||||
|
||||
//第一次不对比,取当前值
|
||||
if (disTime == 0L) {
|
||||
disTime = disTimeTemp
|
||||
resultNiLocation = nilocation
|
||||
} else {
|
||||
|
||||
//前一个差值大于当前差值则取当前相对小的值
|
||||
if (disTime - disTimeTemp > 0) {
|
||||
disTime = disTimeTemp
|
||||
resultNiLocation = nilocation
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val msg1 = Message()
|
||||
msg1.what = 0x11
|
||||
msg1.obj = resultNiLocation
|
||||
if (resultNiLocation != null) {
|
||||
Log.e(TAG, "反向app"+resultNiLocation.time)
|
||||
}
|
||||
mHandler.sendMessage(msg1)
|
||||
}
|
||||
|
||||
2 -> {
|
||||
val msg4 = Message()
|
||||
msg4.what = 0x55
|
||||
mHandler.sendMessage(msg4)
|
||||
}
|
||||
|
||||
3 -> {
|
||||
val msg5 = Message()
|
||||
msg5.what = 0x66
|
||||
mHandler.sendMessage(msg5)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//解析时索引与集合索引对比,如果不相同代表有新命令,需要继续解析最后一条,否则清空集合不在解析
|
||||
try {
|
||||
if (timeIndex == mTaskList.size - 1) {
|
||||
mTaskList.clear()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
val msg2 = Message()
|
||||
msg2.what = 0x99
|
||||
mHandler.sendMessage(msg2)
|
||||
}
|
||||
}
|
||||
Thread.sleep(10)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
val msg = Message()
|
||||
msg.what = 0x99
|
||||
mHandler.sendMessage(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取轨迹数据
|
||||
*
|
||||
* @param startTimeStr 起始时间
|
||||
* @param endTimeStr 结束时间
|
||||
* @param currentTimeStr 当前点时间,如果存在便直接获取一个点
|
||||
* @return list 数据集合
|
||||
*/
|
||||
private fun getTrackList(
|
||||
startTimeStr: String,
|
||||
endTimeStr: String,
|
||||
currentTimeStr: String
|
||||
): List<NiLocation>? {
|
||||
if (!TextUtils.isEmpty(startTimeStr) && !TextUtils.isEmpty(endTimeStr)) {
|
||||
var startTime: Long = 0
|
||||
var endTime: Long = 0
|
||||
try {
|
||||
startTime = startTimeStr.toLong()
|
||||
endTime = endTimeStr.toLong()
|
||||
} catch (e: java.lang.Exception) {
|
||||
}
|
||||
if (startTime != 0L && endTime != 0L) {
|
||||
|
||||
val id = sharedPreferences.getInt(Constant.SELECT_TASK_ID, -1)
|
||||
|
||||
val list: MutableList<NiLocation> = traceDataBase.niLocationDao.findToTaskIdAll(id.toString())
|
||||
|
||||
if (list.size > 0) return list
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* 接收管道数据
|
||||
*/
|
||||
private inner class RecvThread : Runnable {
|
||||
private var runFlag = true
|
||||
fun cancel() {
|
||||
runFlag = false
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
var rlRead: Int
|
||||
try {
|
||||
while (runFlag) {
|
||||
var line: String = ""
|
||||
if (!isServerClose) {
|
||||
rlRead = inStr!!.read(sData) //对方断开返回-1
|
||||
if (rlRead > 0) {
|
||||
Log.e(TAG, sData.toString() + "")
|
||||
line = String(sData, 0, rlRead)
|
||||
mTaskList.add(line)
|
||||
} else {
|
||||
connectFaild("连接断开")
|
||||
}
|
||||
} else {
|
||||
connectFaild("连接断开")
|
||||
}
|
||||
}
|
||||
Thread.sleep(10)
|
||||
} catch (e: IOException) {
|
||||
connectFaild(e.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接失败
|
||||
* @param e 原因
|
||||
*/
|
||||
private fun connectFaild(e: String) {
|
||||
val msg2 = Message()
|
||||
msg2.what = 0x999
|
||||
mHandler.sendMessage(msg2)
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否断开连接,断开返回true,没有返回false
|
||||
* @return
|
||||
*/
|
||||
val isServerClose: Boolean
|
||||
get() {
|
||||
return try {
|
||||
client!!.sendUrgentData(0) //发送1个字节的紧急数据,默认情况下,服务器端没有开启紧急数据处理,不影响正常通信
|
||||
false
|
||||
} catch (se: Exception) {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止接收管道数据
|
||||
*/
|
||||
fun stop() {
|
||||
Log.e(TAG, "stop!")
|
||||
connectstatus = false
|
||||
if (tRecv != null) {
|
||||
tRecv!!.cancel()
|
||||
}
|
||||
if (tParse != null) {
|
||||
tParse!!.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始接收管道数据
|
||||
*/
|
||||
fun start() {
|
||||
Log.e(TAG, "start!")
|
||||
if (tRecv != null) {
|
||||
tRecv!!.cancel()
|
||||
}
|
||||
tRecv = RecvThread()
|
||||
val thread = Thread(tRecv)
|
||||
thread.start()
|
||||
|
||||
//解析线程
|
||||
if (tParse != null) {
|
||||
tParse!!.cancel()
|
||||
}
|
||||
tParse = ParseThread()
|
||||
val parsethread = Thread(tParse)
|
||||
parsethread.start()
|
||||
}
|
||||
|
||||
fun setTraceMap() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 轨迹反向控制回调接口
|
||||
*/
|
||||
interface OnConnectSinsListener {
|
||||
/**
|
||||
* 连接状态
|
||||
*
|
||||
* @param success true 连接成功 false 连接失败
|
||||
*/
|
||||
fun onConnect(success: Boolean)
|
||||
|
||||
/**
|
||||
* 索引中
|
||||
*/
|
||||
fun onIndexing()
|
||||
|
||||
/**
|
||||
* 暂停
|
||||
*/
|
||||
fun onStop()
|
||||
|
||||
/**
|
||||
* 播放
|
||||
*/
|
||||
fun onPlay()
|
||||
|
||||
/**
|
||||
* 结束完成
|
||||
*/
|
||||
fun onParseEnd()
|
||||
|
||||
/**
|
||||
* 轨迹点
|
||||
*
|
||||
* @param mNiLocation
|
||||
*/
|
||||
fun onReceiveLocation(mNiLocation: NiLocation?)
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析返回值
|
||||
*
|
||||
* @return 时间信息
|
||||
*/
|
||||
private fun parseResult(data: String): Result? {
|
||||
var data = data
|
||||
if (!TextUtils.isEmpty(data)) {
|
||||
try {
|
||||
data = data.replace("\n".toRegex(), "")
|
||||
val json = JSONObject(data)
|
||||
val type = json.optInt("type")
|
||||
val mResult: Result = Result()
|
||||
mResult.type = type
|
||||
if (type == 1) {
|
||||
mResult.data = json.optString("data", "")
|
||||
}
|
||||
return mResult
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
//结果类对象
|
||||
internal inner class Result : Serializable {
|
||||
var type = 0
|
||||
var data: String? = null
|
||||
}
|
||||
}
|
@ -33,6 +33,7 @@ enum class QrCodeStatus {
|
||||
* 信息更新成功
|
||||
*/
|
||||
QR_CODE_STATUS_SERVER_INFO_SUCCESS,
|
||||
|
||||
}
|
||||
|
||||
@HiltViewModel
|
||||
|
@ -676,6 +676,7 @@ public class CommonDialog extends Dialog implements SurfaceHolder.Callback, IVid
|
||||
|
||||
//当前为连接时启动已有的状态
|
||||
if (connectstate) {
|
||||
|
||||
mOneBtConnect.setPressed(true);
|
||||
|
||||
mOneBtConnect.setBackgroundResource(R.drawable.shape_btn_red_disconnect_bg);
|
||||
@ -1525,7 +1526,7 @@ public class CommonDialog extends Dialog implements SurfaceHolder.Callback, IVid
|
||||
}
|
||||
|
||||
//连接
|
||||
private void connection(HostBean hostBean) {
|
||||
public void connection(HostBean hostBean) {
|
||||
if (hostBean != null) {
|
||||
SensorParams params = new SensorParams();
|
||||
|
||||
|
@ -257,6 +257,7 @@ class EvaluationResultViewModel @Inject constructor(
|
||||
if (classType2 != null) {
|
||||
classType = classType2
|
||||
}
|
||||
classCode = bean.renderEntity.code.toString()
|
||||
}
|
||||
//如果右侧栏没数据,给个默认值
|
||||
if (liveDataQsRecordBean.value!!.classType.isEmpty()) {
|
||||
@ -343,11 +344,12 @@ class EvaluationResultViewModel @Inject constructor(
|
||||
/**
|
||||
* 查询问题类型列表
|
||||
*/
|
||||
fun getProblemTypeList(classType: String) {
|
||||
fun getProblemTypeList(scProblemTypeBean: ScProblemTypeBean) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
getProblemList(classType)
|
||||
getProblemList(scProblemTypeBean.classType)
|
||||
}
|
||||
classTypeTemp = classType
|
||||
classTypeTemp = scProblemTypeBean.classType
|
||||
classCodeTemp = scProblemTypeBean.elementCode
|
||||
}
|
||||
|
||||
/**
|
||||
@ -464,7 +466,7 @@ class EvaluationResultViewModel @Inject constructor(
|
||||
mapController.markerHandle.addMarker(
|
||||
GeoPoint(
|
||||
p.latitude, p.longitude
|
||||
), TAG
|
||||
), TAG, "", null
|
||||
)
|
||||
|
||||
//获取linkid
|
||||
@ -484,163 +486,163 @@ class EvaluationResultViewModel @Inject constructor(
|
||||
liveDataQsRecordBean.value?.attachmentBeanList = it.attachmentBeanList
|
||||
// 显示语音数据到界面
|
||||
getChatMsgEntityList()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
liveDataToastMessage.postValue("数据读取失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询问题类型列表
|
||||
*/
|
||||
/**
|
||||
* 查询问题类型列表
|
||||
*/
|
||||
private suspend fun getChatMsgEntityList() {
|
||||
val chatMsgEntityList: MutableList<ChatMsgEntity> = ArrayList()
|
||||
liveDataQsRecordBean.value?.attachmentBeanList?.forEach {
|
||||
//1 录音
|
||||
if (it.type == 1) {
|
||||
val chatMsgEntity = ChatMsgEntity()
|
||||
chatMsgEntity.name = it.name
|
||||
chatMsgEntity.voiceUri = Constant.USER_DATA_ATTACHEMNT_PATH
|
||||
chatMsgEntityList.add(chatMsgEntity)
|
||||
}
|
||||
}
|
||||
listDataChatMsgEntityList.postValue(chatMsgEntityList)
|
||||
}
|
||||
|
||||
fun addChatMsgEntity(filePath: String) {
|
||||
|
||||
if (filePath.isNotEmpty()) {
|
||||
var chatMsgEntityList: MutableList<ChatMsgEntity> = ArrayList()
|
||||
if (listDataChatMsgEntityList.value?.isEmpty() == false) {
|
||||
chatMsgEntityList = listDataChatMsgEntityList.value!!
|
||||
}
|
||||
val chatMsgEntityList: MutableList<ChatMsgEntity> = ArrayList()
|
||||
liveDataQsRecordBean.value?.attachmentBeanList?.forEach {
|
||||
//1 录音
|
||||
if (it.type == 1) {
|
||||
val chatMsgEntity = ChatMsgEntity()
|
||||
chatMsgEntity.name = filePath.replace(Constant.USER_DATA_ATTACHEMNT_PATH, "").toString()
|
||||
chatMsgEntity.name = it.name
|
||||
chatMsgEntity.voiceUri = Constant.USER_DATA_ATTACHEMNT_PATH
|
||||
chatMsgEntityList.add(chatMsgEntity)
|
||||
|
||||
|
||||
var attachmentList: RealmList<AttachmentBean> = RealmList()
|
||||
|
||||
//赋值处理
|
||||
if (liveDataQsRecordBean.value?.attachmentBeanList?.isEmpty() == false) {
|
||||
attachmentList = liveDataQsRecordBean.value?.attachmentBeanList!!
|
||||
}
|
||||
|
||||
val attachmentBean = AttachmentBean()
|
||||
attachmentBean.name = chatMsgEntity.name!!
|
||||
attachmentBean.type = 1
|
||||
attachmentList.add(attachmentBean)
|
||||
liveDataQsRecordBean.value?.attachmentBeanList = attachmentList
|
||||
|
||||
listDataChatMsgEntityList.postValue(chatMsgEntityList)
|
||||
}
|
||||
}
|
||||
listDataChatMsgEntityList.postValue(chatMsgEntityList)
|
||||
}
|
||||
|
||||
fun startSoundMetter(activity: Activity, v: View) {
|
||||
fun addChatMsgEntity(filePath: String) {
|
||||
|
||||
if (mSpeakMode == null) {
|
||||
mSpeakMode = SpeakMode(activity)
|
||||
if (filePath.isNotEmpty()) {
|
||||
var chatMsgEntityList: MutableList<ChatMsgEntity> = ArrayList()
|
||||
if (listDataChatMsgEntityList.value?.isEmpty() == false) {
|
||||
chatMsgEntityList = listDataChatMsgEntityList.value!!
|
||||
}
|
||||
val chatMsgEntity = ChatMsgEntity()
|
||||
chatMsgEntity.name = filePath.replace(Constant.USER_DATA_ATTACHEMNT_PATH, "").toString()
|
||||
chatMsgEntity.voiceUri = Constant.USER_DATA_ATTACHEMNT_PATH
|
||||
chatMsgEntityList.add(chatMsgEntity)
|
||||
|
||||
|
||||
var attachmentList: RealmList<AttachmentBean> = RealmList()
|
||||
|
||||
//赋值处理
|
||||
if (liveDataQsRecordBean.value?.attachmentBeanList?.isEmpty() == false) {
|
||||
attachmentList = liveDataQsRecordBean.value?.attachmentBeanList!!
|
||||
}
|
||||
|
||||
//语音识别动画
|
||||
if (pop == null) {
|
||||
pop = PopupWindow()
|
||||
pop!!.width = ViewGroup.LayoutParams.MATCH_PARENT
|
||||
pop!!.height = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
pop!!.setBackgroundDrawable(BitmapDrawable())
|
||||
val view =
|
||||
View.inflate(activity as Context, R.layout.cv_card_voice_rcd_hint_window, null)
|
||||
pop!!.contentView = view
|
||||
volume = view.findViewById(R.id.volume)
|
||||
}
|
||||
val attachmentBean = AttachmentBean()
|
||||
attachmentBean.name = chatMsgEntity.name!!
|
||||
attachmentBean.type = 1
|
||||
attachmentList.add(attachmentBean)
|
||||
liveDataQsRecordBean.value?.attachmentBeanList = attachmentList
|
||||
|
||||
pop!!.update()
|
||||
listDataChatMsgEntityList.postValue(chatMsgEntityList)
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
fun startSoundMetter(activity: Activity, v: View) {
|
||||
|
||||
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
|
||||
}
|
||||
if (mSpeakMode == null) {
|
||||
mSpeakMode = SpeakMode(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(activity as 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("结束录音")
|
||||
|
||||
addChatMsgEntity(filePath!!)
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.Q)
|
||||
override fun onfaild(message: String?) {
|
||||
ToastUtils.showLong("录制失败!")
|
||||
mSpeakMode!!.speakText("录制失败")
|
||||
stopSoundMeter()
|
||||
}
|
||||
})
|
||||
mSpeakMode!!.speakText("结束录音")
|
||||
|
||||
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()
|
||||
addChatMsgEntity(filePath!!)
|
||||
}
|
||||
pop?.let {
|
||||
if (it.isShowing) {
|
||||
it.dismiss()
|
||||
}
|
||||
|
||||
@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()
|
||||
}
|
||||
pop?.let {
|
||||
if (it.isShowing) {
|
||||
it.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun savePhoto(bitmap: Bitmap) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
// 创建一个名为 "MyApp" 的文件夹
|
||||
val myAppDir = File(Constant.USER_DATA_ATTACHEMNT_PATH)
|
||||
fun savePhoto(bitmap: Bitmap) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
// 创建一个名为 "MyApp" 的文件夹
|
||||
val myAppDir = File(Constant.USER_DATA_ATTACHEMNT_PATH)
|
||||
if (!myAppDir.exists()) myAppDir.mkdirs() // 确保文件夹已创建
|
||||
|
||||
// 创建一个名为 fileName 的文件
|
||||
val file = File(myAppDir, "${UUID.randomUUID()}.png")
|
||||
file.createNewFile() // 创建文件
|
||||
// 创建一个名为 fileName 的文件
|
||||
val file = File(myAppDir, "${UUID.randomUUID()}.png")
|
||||
file.createNewFile() // 创建文件
|
||||
|
||||
// 将 Bitmap 压缩为 JPEG 格式,并将其写入文件中
|
||||
val out = FileOutputStream(file)
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out)
|
||||
out.flush()
|
||||
out.close()
|
||||
var picList = mutableListOf<String>()
|
||||
if (liveDataPictureList.value == null) {
|
||||
picList.add(file.absolutePath)
|
||||
} else {
|
||||
picList.addAll(liveDataPictureList.value!!)
|
||||
picList.add(file.absolutePath)
|
||||
}
|
||||
liveDataPictureList.postValue(picList)
|
||||
// 将 Bitmap 压缩为 JPEG 格式,并将其写入文件中
|
||||
val out = FileOutputStream(file)
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out)
|
||||
out.flush()
|
||||
out.close()
|
||||
var picList = mutableListOf<String>()
|
||||
if (liveDataPictureList.value == null) {
|
||||
picList.add(file.absolutePath)
|
||||
} else {
|
||||
picList.addAll(liveDataPictureList.value!!)
|
||||
picList.add(file.absolutePath)
|
||||
}
|
||||
liveDataPictureList.postValue(picList)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -658,5 +660,5 @@ class EvaluationResultViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@ import com.navinfo.omqs.databinding.TextItemSelectBinding
|
||||
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
|
||||
import com.navinfo.omqs.ui.other.BaseViewHolder
|
||||
|
||||
class LeftAdapter(private var itemListener: ((Int, String) -> Unit?)? = null) :
|
||||
class LeftAdapter(private var itemListener: ((Int, ScProblemTypeBean) -> Unit?)? = null) :
|
||||
BaseRecyclerViewAdapter<ScProblemTypeBean>() {
|
||||
private var selectTitle = ""
|
||||
|
||||
@ -28,7 +28,7 @@ class LeftAdapter(private var itemListener: ((Int, String) -> Unit?)? = null) :
|
||||
selectTitle = title.classType
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
itemListener?.invoke(position, title.classType)
|
||||
itemListener?.invoke(position, title)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ import com.github.k1rakishou.fsaf.callback.FSAFActivityCallbacks
|
||||
import com.github.k1rakishou.fsaf.callback.FileChooserCallback
|
||||
import com.navinfo.collect.library.data.entity.TaskBean
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import com.navinfo.omqs.Constant
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.databinding.FragmentPersonalCenterBinding
|
||||
import com.navinfo.omqs.db.ImportOMDBHelper
|
||||
@ -114,12 +115,18 @@ class PersonalCenterFragment(private var indoorDataListener: ((Boolean) -> Unit?
|
||||
}
|
||||
})
|
||||
}
|
||||
R.id.personal_center_menu_open_auto_location -> {
|
||||
Constant.AUTO_LOCATION = true
|
||||
}
|
||||
R.id.personal_center_menu_close_auto_location -> {
|
||||
Constant.AUTO_LOCATION = false
|
||||
}
|
||||
R.id.personal_center_menu_test -> {
|
||||
viewModel.readRealmData()
|
||||
//108.91056000267433 34.29635901721207
|
||||
//108.90107116103331 34.29568928574205
|
||||
// 定位到指定位置
|
||||
niMapController.mMapView.vtmMap.animator()
|
||||
.animateTo(GeoPoint( 34.29635901721207, 108.91056000267433))
|
||||
.animateTo(GeoPoint( 34.29568928574205, 108.90107116103331))
|
||||
}
|
||||
// R.id.personal_center_menu_task_list -> {
|
||||
// findNavController().navigate(R.id.TaskManagerFragment)
|
||||
|
@ -370,4 +370,5 @@ public class ShareUtil {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -345,7 +345,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
app:constraint_referenced_ids="main_activity_snapshot_finish,main_activity_trace_snapshot_points,main_activity_snapshot_media_flag,main_activity_snapshot_rewind,main_activity_snapshot_pause,main_activity_snapshot_next" />
|
||||
app:constraint_referenced_ids="main_activity_snapshot_finish,main_activity_trace_snapshot_points,main_activity_snapshot_rewind,main_activity_snapshot_pause,main_activity_snapshot_next" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/main_activity_snapshot_finish"
|
||||
@ -359,11 +359,12 @@
|
||||
android:onClick="@{()->mainActivity.tracePointsOnclick()}"
|
||||
android:src="@drawable/map_trace_select_point" />
|
||||
|
||||
<ImageButton
|
||||
<!-- <ImageButton
|
||||
android:id="@+id/main_activity_snapshot_media_flag"
|
||||
style="@style/top_right_drawer_btns_style"
|
||||
android:visibility="gone"
|
||||
android:onClick="@{()->mainActivity.mediaFlagOnclick()}"
|
||||
android:src="@drawable/map_trace_mediaflag" />
|
||||
android:src="@drawable/map_trace_mediaflag" />-->
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/main_activity_snapshot_rewind"
|
||||
@ -380,6 +381,7 @@
|
||||
<ImageButton
|
||||
android:id="@+id/main_activity_snapshot_next"
|
||||
style="@style/top_right_drawer_btns_style"
|
||||
android:onClick="@{()->mainActivity.nextTraceOnclick()}"
|
||||
android:src="@drawable/map_trace_next" />
|
||||
|
||||
<View
|
||||
|
@ -56,6 +56,18 @@
|
||||
<!-- android:icon="@drawable/ic_baseline_layers_24"-->
|
||||
<!-- android:title="图层管理" />-->
|
||||
|
||||
<item
|
||||
android:id="@+id/personal_center_menu_open_auto_location"
|
||||
android:icon="@drawable/baseline_person_24"
|
||||
android:visible="true"
|
||||
android:title="开启自动定位" />
|
||||
|
||||
<item
|
||||
android:id="@+id/personal_center_menu_close_auto_location"
|
||||
android:icon="@drawable/baseline_person_24"
|
||||
android:visible="true"
|
||||
android:title="关闭自动定位" />
|
||||
|
||||
<item
|
||||
android:id="@+id/personal_center_menu_test"
|
||||
android:icon="@drawable/baseline_person_24"
|
||||
|
@ -1707,48 +1707,56 @@
|
||||
</m>0
|
||||
<!-- 道路边界类型 -->
|
||||
<m v="OMDB_RDBOUND_BOUNDARYTYPE">
|
||||
<outline-layer id="boundaryType" stroke="#fcba5a" width="0.2" />
|
||||
<outline-layer id="boundaryType" stroke="#8e44ad" width="0.2" />
|
||||
<m k="boundaryType" v="0|2|3|4|5|6|7|8|9">
|
||||
<line stroke="#ffffff" use="boundaryType" width="0.2"/>
|
||||
</m>
|
||||
<m k="boundaryType" v="1">
|
||||
<!--无标线无可区分边界-->
|
||||
<line dasharray="20,8" repeat-start="0" stroke="#ffffff" width="0.2"/>
|
||||
</m>
|
||||
<!-- <outline-layer id="boundaryType" stroke="#fcba5a" width="0.2" />
|
||||
<m k="boundaryType" v="0">
|
||||
<!--不应用-->
|
||||
<!–不应用–>
|
||||
<line stroke="#fcba5a" use="boundaryType"/>
|
||||
<lineSymbol repeat-gap="12" repeat-start="12" symbol-height="16" symbol-width="16" src="assets:omdb/icon_2083_0.svg" />
|
||||
</m>
|
||||
<m k="boundaryType" v="1">
|
||||
<!--无标线无可区分边界-->
|
||||
<!–无标线无可区分边界–>
|
||||
<line dasharray="10,2,2,2,2,2,2,2" repeat-start="0" stroke="#fcba5a" width="0.2" />
|
||||
</m>
|
||||
<m k="boundaryType" v="2">
|
||||
<!--标线-->
|
||||
<!–标线–>
|
||||
<line stroke="#fcba5a" use="boundaryType"/>
|
||||
</m>
|
||||
<m k="boundaryType" v="3">
|
||||
<!--路牙-->
|
||||
<!–路牙–>
|
||||
<line dasharray="10,4" repeat-start="0" stroke="#fcba5a" width="0.2" />
|
||||
</m>
|
||||
<m k="boundaryType" v="4">
|
||||
<!--护栏-->
|
||||
<!–护栏–>
|
||||
<line dasharray="10,2,2,2" repeat-start="0" stroke="#fcba5a" width="0.2"/>
|
||||
</m>
|
||||
<m k="boundaryType" v="5">
|
||||
<!--墙-->
|
||||
<!–墙–>
|
||||
<line stroke="#fcba5a" use="boundaryType"/>
|
||||
<line dasharray="10,5" stroke="#fcba5a" width="0.5" />
|
||||
</m>
|
||||
<m k="boundaryType" v="6">
|
||||
<!--道路面铺设边缘-->
|
||||
<!–道路面铺设边缘–>
|
||||
<line stroke="#fcba5a" use="boundaryType"/>
|
||||
<lineSymbol repeat-gap="32" repeat-start="0" symbol-height="32" src="assets:omdb/icon_2083_6.svg" />
|
||||
</m>
|
||||
<m k="boundaryType" v="7">
|
||||
<!--虚拟三角岛-->
|
||||
<!–虚拟三角岛–>
|
||||
<line stroke="#fcba5a" use="boundaryType"/>
|
||||
<line src="assets:omdb/icon_2083_7_1.svg" symbol-height="12" symbol-width="12" symbol-percent="20" width="1" />
|
||||
</m>
|
||||
<m k="boundaryType" v="9">
|
||||
<!--杆状障碍物-->
|
||||
<!–杆状障碍物–>
|
||||
<line stroke="#fcba5a" use="boundaryType"/>
|
||||
<lineSymbol repeat-gap="16" repeat-start="12" symbol-height="24" symbol-width="8" src="assets:omdb/icon_2083_9.svg" />
|
||||
</m>
|
||||
</m>-->
|
||||
</m>
|
||||
<!-- 车道边界类型 -->
|
||||
<m v="OMDB_LANE_MARK_BOUNDARYTYPE">
|
||||
@ -1758,13 +1766,13 @@
|
||||
<m v="2">
|
||||
<m k="markType">
|
||||
<!--其他|实线-->
|
||||
<m v="0|1">
|
||||
<m v="0|1|2|3|4|5|6|7|8">
|
||||
<m k="markColor">
|
||||
<m v="0|1">
|
||||
<m v="1">
|
||||
<line stroke="#ffffff" use="boundaryType" />
|
||||
</m>
|
||||
<m v="2">
|
||||
<line stroke="#eccc68" use="boundaryType" />
|
||||
<line dasharray="10,2,2,2,2,2,2,2" repeat-start="0" stroke="#eccc68" use="boundaryType" />
|
||||
</m>
|
||||
<m v="6">
|
||||
<line stroke="#0000ff" use="boundaryType" />
|
||||
@ -1772,12 +1780,12 @@
|
||||
<m v="7">
|
||||
<line stroke="#00ff00" use="boundaryType" />
|
||||
</m>
|
||||
<m v="9">
|
||||
<m v="0|9">
|
||||
<line stroke="#8e44ad" use="boundaryType" />
|
||||
</m>
|
||||
</m>
|
||||
</m>
|
||||
<!--虚线-->
|
||||
<!-- <!–虚线–>
|
||||
<m v="2">
|
||||
<m k="markColor">
|
||||
<m v="0|1">
|
||||
@ -1802,18 +1810,21 @@
|
||||
</m>
|
||||
</m>
|
||||
</m>
|
||||
<!--导流区边线-->
|
||||
<!–导流区边线–>
|
||||
<m v="4">
|
||||
<line outline="boundary" stroke="#545D6C"></line>
|
||||
<lineSymbol repeat-gap="0.5" repeat-start="0"
|
||||
src="assets:omdb/icon_right.png" />
|
||||
</m>
|
||||
<!-- <!–铺设路面边缘–>-->
|
||||
<!-- <m v="5">-->
|
||||
<!-- <line outline="#ffffff" fix="true" src="assets:omdb/icon_close.png" stroke="#ffffffff" use="boundaryType"/>-->
|
||||
<!-- </m>-->
|
||||
</m>-->
|
||||
</m>
|
||||
</m>
|
||||
<m v="0|3|4|5|6|7|8|9">
|
||||
<line stroke="#ffffff" use="boundaryType" />
|
||||
</m>
|
||||
<!--只区分虚线与实线-->
|
||||
<m v="1">
|
||||
<line dasharray="20,8" repeat-start="0" stroke="#ffffff" width="0.2"/>
|
||||
</m>
|
||||
</m>
|
||||
</m>
|
||||
|
||||
|
@ -47,6 +47,9 @@ public interface INiLocationDao {
|
||||
@Query("SELECT * FROM niLocation")
|
||||
List<NiLocation> findAll();
|
||||
|
||||
@Query("SELECT * FROM niLocation where time>=:startTime and time<=:endTime and taskId=:taskId")
|
||||
List<NiLocation> taskIdAndTimeTofindList(String taskId,long startTime,long endTime);
|
||||
|
||||
@Query("SELECT * FROM niLocation where taskId =:taskId")
|
||||
List<NiLocation> findToTaskIdAll(String taskId);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import java.util.UUID;
|
||||
* @Date 2022/4/14
|
||||
* @Description: ${TODO}(数据基类)
|
||||
*/
|
||||
public class Feature implements Serializable, Cloneable {
|
||||
public class Feature extends Object implements Serializable, Cloneable {
|
||||
// //主键
|
||||
// @PrimaryKey(autoGenerate = true)
|
||||
// public int rowId;
|
||||
|
@ -30,7 +30,7 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
//
|
||||
// }
|
||||
|
||||
val niLocationFlow = MutableSharedFlow<NiLocation>(3)
|
||||
val niLocationFlow = MutableSharedFlow<NiLocation>(5)
|
||||
|
||||
init {
|
||||
///添加定位图层到地图,[NIMapView.LAYER_GROUPS.NAVIGATION] 是最上层layer组
|
||||
@ -67,18 +67,12 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
val errorCode = it.locType
|
||||
mCurrentLocation = it
|
||||
mLocationLayer.setPosition(it.latitude, it.longitude, it.radius)
|
||||
// Log.e(
|
||||
// "qj",
|
||||
// "location==${it.longitude}==errorCode===$errorCode===${it.locTypeDescription}"
|
||||
// )
|
||||
Log.e("qj", "location==${it.longitude}==errorCode===$errorCode===${it.locTypeDescription}")
|
||||
|
||||
// if (niLocationListener != null) {
|
||||
getCurrentNiLocation()?.let { it1 ->
|
||||
mContext.lifecycleScope.launch(Dispatchers.Default) {
|
||||
mContext.lifecycleScope.launch {
|
||||
niLocationFlow.emit(it1)
|
||||
}
|
||||
|
||||
// }// niLocationListener.call(it1) }
|
||||
}
|
||||
//第一次定位成功显示当前位置
|
||||
if (this.bFirst) {
|
||||
|
@ -4,7 +4,6 @@ import android.content.Context
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.util.Log
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import com.navinfo.collect.library.R
|
||||
@ -197,6 +196,7 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
if (listener is OnNiLocationItemListener) {
|
||||
listener.onNiLocation(
|
||||
tag,
|
||||
index,
|
||||
(niLocationItemizedLayer.itemList[index] as MarkerItem).uid as NiLocation
|
||||
)
|
||||
break
|
||||
@ -211,6 +211,7 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
addLayer(layer, NIMapView.LAYER_GROUPS.OPERATE_MARKER)
|
||||
layer
|
||||
}
|
||||
@ -287,7 +288,8 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
fun addMarker(
|
||||
geoPoint: GeoPoint,
|
||||
title: String?,
|
||||
description: String? = ""
|
||||
description: String? = "",
|
||||
uid: java.lang.Object? = null,
|
||||
) {
|
||||
var marker: MarkerItem? = null
|
||||
for (e in mDefaultMarkerLayer.itemList) {
|
||||
@ -302,6 +304,7 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
tempTitle = StringUtil.createUUID()
|
||||
}
|
||||
val marker = MarkerItem(
|
||||
uid,
|
||||
tempTitle,
|
||||
description,
|
||||
geoPoint
|
||||
@ -317,6 +320,14 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
}
|
||||
}
|
||||
|
||||
fun getCurrentMark(): MarkerInterface? {
|
||||
|
||||
if (mDefaultMarkerLayer != null) {
|
||||
return mDefaultMarkerLayer.itemList[mDefaultMarkerLayer.itemList.size - 1]
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除marker
|
||||
*/
|
||||
@ -484,70 +495,61 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
/**
|
||||
* 添加质检数据marker
|
||||
*/
|
||||
public suspend fun addNiLocationMarkerItem(niLocation: NiLocation) {
|
||||
fun addNiLocationMarkerItem(niLocation: NiLocation) {
|
||||
synchronized(this) {
|
||||
Log.e("jingo", "插入定位点0 ")
|
||||
|
||||
var itemizedLayer: ItemizedLayer? = null
|
||||
|
||||
val direction: Double = niLocation.direction
|
||||
|
||||
val geoMarkerItem: MarkerItem = ClusterMarkerItem(
|
||||
niLocation,
|
||||
niLocation.id,
|
||||
niLocation.time,
|
||||
GeoPoint(niLocation.latitude, niLocation.longitude)
|
||||
)
|
||||
|
||||
//角度
|
||||
when (niLocation.media) {
|
||||
0 -> {
|
||||
//角度不为0时需要预先设置marker样式并进行角度设置,否则使用图层默认的sym即可
|
||||
//角度不为0时需要预先设置marker样式并进行角度设置,否则使用图层默认的sym即可
|
||||
if (direction != 0.0) {
|
||||
val symbolGpsTemp =
|
||||
MarkerSymbol(niLocationBitmap, MarkerSymbol.HotspotPlace.CENTER, false)
|
||||
geoMarkerItem.marker = symbolGpsTemp
|
||||
geoMarkerItem.setRotation(direction.toFloat())
|
||||
} else {
|
||||
val symbolGpsTemp =
|
||||
MarkerSymbol(niLocationBitmap2, MarkerSymbol.HotspotPlace.CENTER, false)
|
||||
geoMarkerItem.marker = symbolGpsTemp
|
||||
}
|
||||
Log.e(
|
||||
"jingo",
|
||||
"插入定位点1 ${geoMarkerItem.geoPoint.longitude} ${geoMarkerItem.geoPoint.latitude}"
|
||||
)
|
||||
niLocationItemizedLayer.addItem(geoMarkerItem)
|
||||
itemizedLayer = niLocationItemizedLayer
|
||||
}
|
||||
|
||||
1 -> {
|
||||
//角度不为0时需要预先设置marker样式并进行角度设置,否则使用图层默认的sym即可
|
||||
//角度不为0时需要预先设置marker样式并进行角度设置,否则使用图层默认的sym即可
|
||||
if (direction != 0.0) {
|
||||
val symbolLidarTemp =
|
||||
MarkerSymbol(niLocationBitmap1, MarkerSymbol.HotspotPlace.CENTER, false)
|
||||
geoMarkerItem.marker = symbolLidarTemp
|
||||
geoMarkerItem.setRotation(direction.toFloat())
|
||||
} else {
|
||||
val symbolGpsTemp =
|
||||
MarkerSymbol(niLocationBitmap3, MarkerSymbol.HotspotPlace.CENTER, false)
|
||||
geoMarkerItem.marker = symbolGpsTemp
|
||||
}
|
||||
Log.e(
|
||||
"jingo",
|
||||
"插入定位点2 ${geoMarkerItem.geoPoint.longitude} ${geoMarkerItem.geoPoint.latitude}"
|
||||
)
|
||||
niLocationItemizedLayer.addItem(geoMarkerItem)
|
||||
itemizedLayer = niLocationItemizedLayer
|
||||
}
|
||||
|
||||
}
|
||||
itemizedLayer?.update()
|
||||
var geoMarkerItem = createNILocationBitmap(niLocation)
|
||||
niLocationItemizedLayer.addItem(geoMarkerItem)
|
||||
niLocationItemizedLayer.update()
|
||||
}
|
||||
}
|
||||
|
||||
private fun createNILocationBitmap(niLocation: NiLocation): MarkerItem {
|
||||
|
||||
val direction: Double = niLocation.direction
|
||||
|
||||
val geoMarkerItem: MarkerItem = ClusterMarkerItem(
|
||||
niLocation,
|
||||
niLocation.id,
|
||||
niLocation.time,
|
||||
GeoPoint(niLocation.latitude, niLocation.longitude)
|
||||
)
|
||||
|
||||
//角度
|
||||
when (niLocation.media) {
|
||||
0 -> {
|
||||
//角度不为0时需要预先设置marker样式并进行角度设置,否则使用图层默认的sym即可
|
||||
//角度不为0时需要预先设置marker样式并进行角度设置,否则使用图层默认的sym即可
|
||||
if (direction > 0.0) {
|
||||
val symbolGpsTemp =
|
||||
MarkerSymbol(niLocationBitmap, MarkerSymbol.HotspotPlace.CENTER, false)
|
||||
geoMarkerItem.marker = symbolGpsTemp
|
||||
geoMarkerItem.setRotation(direction.toFloat())
|
||||
} else {
|
||||
val symbolGpsTemp =
|
||||
MarkerSymbol(niLocationBitmap2, MarkerSymbol.HotspotPlace.CENTER, false)
|
||||
geoMarkerItem.marker = symbolGpsTemp
|
||||
}
|
||||
}
|
||||
|
||||
1 -> {
|
||||
//角度不为0时需要预先设置marker样式并进行角度设置,否则使用图层默认的sym即可
|
||||
//角度不为0时需要预先设置marker样式并进行角度设置,否则使用图层默认的sym即可
|
||||
if (direction > 0.0) {
|
||||
val symbolLidarTemp =
|
||||
MarkerSymbol(niLocationBitmap1, MarkerSymbol.HotspotPlace.CENTER, false)
|
||||
geoMarkerItem.marker = symbolLidarTemp
|
||||
geoMarkerItem.setRotation(direction.toFloat())
|
||||
} else {
|
||||
val symbolGpsTemp =
|
||||
MarkerSymbol(niLocationBitmap3, MarkerSymbol.HotspotPlace.CENTER, false)
|
||||
geoMarkerItem.marker = symbolGpsTemp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return geoMarkerItem
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 文字和图片拼装,文字换行
|
||||
@ -775,6 +777,38 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
mMapView.updateMap(true)
|
||||
}
|
||||
|
||||
fun getNILocationItemizedLayerSize(): Int {
|
||||
return niLocationItemizedLayer.itemList.size
|
||||
}
|
||||
|
||||
fun getNILocation(index: Int): NiLocation? {
|
||||
return if (index > -1 && index < getNILocationItemizedLayerSize()) {
|
||||
((niLocationItemizedLayer.itemList[index]) as MarkerItem).uid as NiLocation
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun getNILocationIndex(niLocation: NiLocation): Int? {
|
||||
|
||||
var list = niLocationItemizedLayer.itemList
|
||||
|
||||
if (niLocation != null && list.isNotEmpty()) {
|
||||
|
||||
var index = -1
|
||||
|
||||
list.forEach {
|
||||
|
||||
index += 1
|
||||
|
||||
if (((it as MarkerItem).uid as NiLocation).id.equals(niLocation.id)) {
|
||||
return index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
interface OnQsRecordItemClickListener : BaseClickListener {
|
||||
@ -786,5 +820,5 @@ interface ONNoteItemClickListener : BaseClickListener {
|
||||
}
|
||||
|
||||
interface OnNiLocationItemListener : BaseClickListener {
|
||||
fun onNiLocation(tag: String, it: NiLocation)
|
||||
fun onNiLocation(tag: String, index: Int, it: NiLocation)
|
||||
}
|
2
vtm
2
vtm
@ -1 +1 @@
|
||||
Subproject commit 1ee201a41f78f169873848209a3f3bdac36f185a
|
||||
Subproject commit dd13e533c38b5738ab404c2737d7ccadeff01323
|
Loading…
x
Reference in New Issue
Block a user