调整道路属性面板
This commit is contained in:
squallzhjch 2023-05-26 10:06:58 +08:00
parent 4e997b8632
commit b6bbcad634
9 changed files with 219 additions and 168 deletions

View File

@ -121,6 +121,11 @@
"code": 4006,
"name": "普通交限"
},
"4022":{
"table": "OMDB_TRAFFICLIGHT",
"code": 4022,
"name": "交通灯"
},
"5001":{
"table": "OMDB_LANE_LINK_LG",
"code": 5001,

View File

@ -1,10 +1,15 @@
package com.navinfo.omqs.ui.activity.map
import android.app.Activity
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.os.PersistableBundle
import android.speech.tts.TextToSpeech
import android.util.Log
import android.view.MotionEvent
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import androidx.core.view.WindowCompat
@ -29,7 +34,10 @@ import com.navinfo.omqs.util.FlowEventBus
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import com.navinfo.omqs.ui.widget.RecyclerViewSpacesItemDecoration
import com.navinfo.omqs.util.SpeakMode
import org.videolan.vlc.Util
import java.math.BigDecimal
import java.math.RoundingMode
import javax.inject.Inject
/**
@ -43,6 +51,17 @@ class MainActivity : BaseActivity() {
var switchFragment = false
private val someActivityResultLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val data: Intent? = result.data
Log.e("jingo", "MainActivity someActivityResultLauncher RESULT_OK")
} else {
Log.e("jingo", "MainActivity someActivityResultLauncher ${result.resultCode}")
}
}
//注入地图控制器
@Inject
lateinit var mapController: NIMapController
@ -88,6 +107,13 @@ class MainActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
WindowCompat.setDecorFitsSystemWindows(window, false)
super.onCreate(savedInstanceState)
val checkIntent = Intent()
checkIntent.action = TextToSpeech.Engine.ACTION_CHECK_TTS_DATA
someActivityResultLauncher.launch(checkIntent)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
//初始化地图
@ -98,6 +124,7 @@ class MainActivity : BaseActivity() {
Constant.MAP_PATH,
Constant.USER_DATA_PATH + "/trace.sqlite"
)
viewModel.speakMode = SpeakMode(this)
// 在mapController初始化前获取当前OMDB图层显隐
viewModel.refreshOMDBLayer(LayerConfigUtils.getLayerConfigList())
mapController.mMapView.vtmMap.viewport().maxZoomLevel = 25
@ -144,8 +171,7 @@ class MainActivity : BaseActivity() {
//道路属性面板
binding.mainActivityTopSignRecyclerview.layoutManager = LinearLayoutManager(
this,
RecyclerView.HORIZONTAL, false
this, RecyclerView.HORIZONTAL, false
)
// binding.mainActivityTopSignRecyclerview.addItemDecoration(
// RecycleViewDivider(this, LinearLayoutManager.HORIZONTAL)
@ -164,19 +190,28 @@ class MainActivity : BaseActivity() {
)
)
)
//监听要素面板变化
viewModel.liveDataSignList.observe(this) {
signAdapter.refreshData(it)
}
//监听道路信息变化
viewModel.liveDataTopSignList.observe(this) {
topSignAdapter.refreshData(it)
}
//监听地图中点变化
viewModel.liveDataCenterPoint.observe(this) {
binding.mainActivityGeometry.text = "经纬度:${
BigDecimal(it.longitude).setScale(
6,
RoundingMode.HALF_UP
)
},${BigDecimal(it.latitude).setScale(6, RoundingMode.HALF_UP)}"
}
lifecycleScope.launch {
// 初始化地图图层控制接收器
FlowEventBus.subscribe<List<ImportConfig>>(
lifecycle,
Constant.EVENT_LAYER_MANAGER_CHANGE
lifecycle, Constant.EVENT_LAYER_MANAGER_CHANGE
) {
viewModel.refreshOMDBLayer(it)
}
@ -201,6 +236,7 @@ class MainActivity : BaseActivity() {
override fun onDestroy() {
super.onDestroy()
viewModel.speakMode?.shutdown()
mapController.mMapView.onDestroy()
mapController.locationLayerHandler.stopLocation()
}

View File

@ -45,7 +45,10 @@ import io.realm.RealmSet
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.oscim.core.GeoPoint
import org.oscim.core.MapPosition
import org.oscim.map.Map
import org.videolan.libvlc.LibVlcUtil
import java.io.File
import java.util.*
@ -59,7 +62,7 @@ import javax.inject.Inject
class MainViewModel @Inject constructor(
private val mapController: NIMapController,
private val traceDataBase: TraceDataBase,
private val realmOperateHelper: RealmOperateHelper
private val realmOperateHelper: RealmOperateHelper,
) : ViewModel() {
private var mCameraDialog: CommonDialog? = null
@ -78,7 +81,7 @@ class MainViewModel @Inject constructor(
//语音窗体
private var pop: PopupWindow? = null
private var mSpeakMode: SpeakMode? = null
var speakMode: SpeakMode? = null
//录音图标
var volume: ImageView? = null
@ -88,12 +91,28 @@ class MainViewModel @Inject constructor(
val liveDataMenuState = MutableLiveData<Boolean>()
val liveDataCenterPoint = MutableLiveData<MapPosition>()
/**
* 是不是线选择模式
*/
private var bSelectRoad = false
init {
mapController.mMapView.vtmMap.events.bind(Map.UpdateListener { e, mapPosition ->
when (e) {
Map.SCALE_EVENT, Map.MOVE_EVENT, Map.ROTATE_EVENT ->
if (liveDataCenterPoint.value == null
|| liveDataCenterPoint.value!!.x != mapPosition.x
|| liveDataCenterPoint.value!!.y != mapPosition.y
) {
liveDataCenterPoint.value = mapPosition
}
}
})
//处理质检数据点击事件
mapController.markerHandle.setOnQsRecordItemClickListener(object :
OnQsRecordItemClickListener {
override fun onQsRecordList(list: MutableList<String>) {
@ -101,9 +120,11 @@ class MainViewModel @Inject constructor(
}
})
initLocation()
//处理地图点击操作
viewModelScope.launch {
mapController.onMapClickFlow.collectLatest {
// testPoint = it
//线选择状态
if (bSelectRoad) {
captureLink(it)
}
@ -223,10 +244,10 @@ class MainViewModel @Inject constructor(
)
when (element.code) {
2041, 2008, 2010 -> topSignList.add(
2002, 2008, 2010, 2041 -> topSignList.add(
signBean
)
else -> signList.add(
4002, 4003, 4004, 4006, 4022 -> signList.add(
signBean
)
}
@ -237,6 +258,10 @@ class MainViewModel @Inject constructor(
}
liveDataTopSignList.postValue(topSignList.distinctBy { it.elementCode })
liveDataSignList.postValue(signList.distinctBy { it.elementCode })
val speechText = SignUtil.getRoadSpeechText(topSignList)
withContext(Dispatchers.Main) {
speakMode?.speakText(speechText)
}
Log.e("jingo", "自动捕捉数据 共${signList.size}")
}
}
@ -303,10 +328,6 @@ class MainViewModel @Inject constructor(
fun startSoundMetter(context: Context, v: View) {
if (mSpeakMode == null) {
mSpeakMode = SpeakMode(context as Activity?)
}
//语音识别动画
if (pop == null) {
pop = PopupWindow()
@ -340,12 +361,12 @@ class MainViewModel @Inject constructor(
if (!TextUtils.isEmpty(filePath) && File(filePath).exists()) {
if (File(filePath) == null || File(filePath).length() < 1600) {
ToastUtils.showLong("语音时间太短,无效!")
mSpeakMode!!.speakText("语音时间太短,无效")
speakMode?.speakText("语音时间太短,无效")
stopSoundMeter()
return
}
}
mSpeakMode!!.speakText("结束录音")
speakMode?.speakText("结束录音")
//获取右侧fragment容器
val naviController =
(context as Activity).findNavController(R.id.main_activity_right_fragment)
@ -357,14 +378,14 @@ class MainViewModel @Inject constructor(
@RequiresApi(api = Build.VERSION_CODES.Q)
override fun onfaild(message: String?) {
ToastUtils.showLong("录制失败!")
mSpeakMode!!.speakText("录制失败")
speakMode?.speakText("录制失败")
stopSoundMeter()
}
})
mSoundMeter!!.start(Constant.USER_DATA_ATTACHEMNT_PATH + name)
ToastUtils.showLong("开始录音")
mSpeakMode!!.speakText("开始录音")
speakMode?.speakText("开始录音")
}
//停止语音录制

View File

@ -40,7 +40,6 @@ class LeftAdapter(private var itemListener: ((Int, String) -> Unit?)? = null) :
override fun refreshData(newData: List<String>) {
data = newData
selectTitle = newData[0]
notifyDataSetChanged()
}

View File

@ -83,7 +83,7 @@ class PhenomenonFragment :
}
//右侧菜单查询数据监听
viewModel.liveDataRightTypeList.observe(viewLifecycleOwner) {
rightAdapter.setSelectTitle(viewModel.liveDataQsRecordBean.value!!.classType)
rightAdapter.setSelectTitle(viewModel.liveDataQsRecordBean.value!!.phenomenon)
rightAdapter.refreshData(it)
}

View File

@ -3,6 +3,7 @@ package com.navinfo.omqs.ui.widget
import android.util.Log
import com.navinfo.collect.library.data.entity.RenderEntity
import com.navinfo.omqs.R
import com.navinfo.omqs.bean.SignBean
class SignUtil {
companion object {
@ -73,6 +74,10 @@ class SignUtil {
4003 -> "条件点限速"
//可变点限速
4004 -> "可变点限速"
//普通交限
4006 -> "普通交限"
//交通灯
4022 -> "交通灯"
else -> ""
}
}
@ -209,6 +214,8 @@ class SignUtil {
4003 -> getConditionalSpeedLimitIcon(data)
//可变点限速
4004 -> R.drawable.icon_change_limit
//交通灯
4022 -> R.drawable.icon_traffic_light
else -> 0
}
@ -285,5 +292,24 @@ class SignUtil {
}
return R.drawable.icon_road_direction
}
/**
* 获取道路播报语音文字
*/
fun getRoadSpeechText(topSignList: MutableList<SignBean>): String {
if (topSignList.size == 0)
return ""
val stringBuffer = StringBuffer()
stringBuffer.append("当前道路")
for (item in topSignList) {
when (item.elementCode) {
2002 -> stringBuffer.append("功能等级${item.iconText.substring(2)}级,")
2008 -> stringBuffer.append("种别${item.iconText},")
2010 -> stringBuffer.append("${item.iconText},")
2041 -> stringBuffer.append("${item.iconText.substringBefore("|")}车道")
}
}
return stringBuffer.toString()
}
}
}

View File

@ -1,149 +0,0 @@
package com.navinfo.omqs.util;
import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.speech.tts.TextToSpeech;
import android.util.Log;
import android.view.View;
import com.navinfo.omqs.ui.dialog.FirstDialog;
import java.util.HashMap;
import java.util.Locale;
//语音类
public class SpeakMode extends Activity implements TextToSpeech.OnInitListener{
private Activity mActivity;
private TextToSpeech mTextToSpeech;//TTS对象
private int status;
private int MY_DATA_CHECK_CODE = 0;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0x11:
try {
HashMap<String, String> params = new HashMap<String, String>();
params.put(TextToSpeech.Engine.KEY_PARAM_STREAM, "STREAM_NOTIFICATION");//设置播放类型音频流类型
mTextToSpeech.speak(msg.obj + "", TextToSpeech.QUEUE_ADD, params);//将这个发音任务添加当前任务之后
//BaseToast.makeText(mActivity,msg.obj+"",Toast.LENGTH_LONG).show();
mTextToSpeech.playSilence(100, TextToSpeech.QUEUE_ADD, params);//间隔多长时间
} catch (Exception e) {
}
break;
}
}
};
public SpeakMode(Activity activity) {
mActivity = activity;
if (mActivity != null && !mActivity.isFinishing())
this.mTextToSpeech = new TextToSpeech(this.mActivity, this);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent checkIntent = new Intent();
checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkIntent, MY_DATA_CHECK_CODE);
}
public void setData(String json) {
}
@Override
public void onInit(int status) {
this.status = status;
if (this.mTextToSpeech != null) {
int result = this.mTextToSpeech.setLanguage(Locale.CHINESE);
if (result == TextToSpeech.LANG_MISSING_DATA
|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
if (mActivity != null && !mActivity.isFinishing()) {
FirstDialog firstDialog = new FirstDialog(mActivity);
firstDialog.setTitle("提示");
firstDialog.setMessage("设备不支持语音播报,请先下载语音助手。");
firstDialog.setConfirmListener(new FirstDialog.OnClickListener() {
@Override
public void onClick(Dialog dialog, int which) {
dialog.dismiss();
}
});
firstDialog.setNegativeView(View.GONE);
firstDialog.show();
}
}
}
Log.i("TextToSpeechDemo", String.valueOf(status));
}
//读语音处理
public void speakText(final String message) {
new Thread(new Runnable() {
@Override
public void run() {
if (mTextToSpeech != null) {
int result = mTextToSpeech.setLanguage(Locale.CHINESE);
if (result == TextToSpeech.LANG_MISSING_DATA
|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
} else {
if (mTextToSpeech != null && mTextToSpeech.isSpeaking()) {
while (mTextToSpeech.isSpeaking()) {
try {
//增加播报停止解决不能播报最新内容问题
mTextToSpeech.stop();
Thread.sleep(100);
} catch (Exception e) {
}
}
}
Message msg = new Message();
msg.what = 0x11;
msg.obj = message;
mHandler.sendMessage(msg);
}
}
}
}).start();
}
public void stopSpeek() {
try {
if (this.mTextToSpeech != null && this.mTextToSpeech.isSpeaking()) {
this.mTextToSpeech.stop();
}
} catch (Exception e) {
}
}
}

View File

@ -0,0 +1,110 @@
package com.navinfo.omqs.util
import android.content.Context
import android.os.Handler
import android.os.Message
import android.speech.tts.TextToSpeech
import android.util.Log
import android.view.View
import com.navinfo.omqs.ui.dialog.FirstDialog
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.util.*
import javax.inject.Inject
//语音类
class SpeakMode(private val context: Context) : TextToSpeech.OnInitListener {
private var mTextToSpeech: TextToSpeech = TextToSpeech(context, this)
private var status = 0
private val MY_DATA_CHECK_CODE = 0
private val mHandler: Handler = object : Handler() {
override fun handleMessage(msg: Message) {
when (msg.what) {
0x11 -> try {
val params = HashMap<String, String>()
params[TextToSpeech.Engine.KEY_PARAM_STREAM] =
"STREAM_NOTIFICATION" //设置播放类型(音频流类型)
mTextToSpeech.speak(
msg.obj.toString() + "",
TextToSpeech.QUEUE_ADD,
params
) //将这个发音任务添加当前任务之后
//BaseToast.makeText(mActivity,msg.obj+"",Toast.LENGTH_LONG).show();
mTextToSpeech.playSilence(100, TextToSpeech.QUEUE_ADD, params) //间隔多长时间
} catch (e: Exception) {
}
}
}
}
init {
// if (mActivity != null && !mActivity.isFinishing) mTextToSpeech = TextToSpeech(
// mActivity, this
// )
}
// override fun onCreate(savedInstanceState: Bundle?) {
// super.onCreate(savedInstanceState)
// val checkIntent = Intent()
// checkIntent.action = TextToSpeech.Engine.ACTION_CHECK_TTS_DATA
// startActivityForResult(checkIntent, MY_DATA_CHECK_CODE)
// }
fun setData(json: String?) {}
override fun onInit(status: Int) {
this.status = status
val result = mTextToSpeech.setLanguage(Locale.CHINESE)
if (result == TextToSpeech.LANG_MISSING_DATA
|| result == TextToSpeech.LANG_NOT_SUPPORTED
) {
if (context != null) {
val firstDialog = FirstDialog(context)
firstDialog.setTitle("提示")
firstDialog.setMessage("设备不支持语音播报,请先下载语音助手。")
firstDialog.setConfirmListener { dialog, _ -> dialog.dismiss() }
firstDialog.setNegativeView(View.GONE)
firstDialog.show()
}
}
Log.i("TextToSpeechDemo", status.toString())
}
//读语音处理
fun speakText(message: String) {
mTextToSpeech.speak(message, TextToSpeech.QUEUE_FLUSH, null, "")
// val result = mTextToSpeech.setLanguage(Locale.CHINESE)
// if (result == TextToSpeech.LANG_MISSING_DATA
// || result == TextToSpeech.LANG_NOT_SUPPORTED
// ) {
// } else {
// while (mTextToSpeech.isSpeaking) {
// try {
// //增加播报停止,解决不能播报最新内容问题
// mTextToSpeech.stop()
// } catch (e: Exception) {
//
// }
// }
// val msg = Message()
// msg.what = 0x11
// msg.obj = message
// mHandler.sendMessage(msg)
// }
}
fun stopSpeech() {
try {
if (mTextToSpeech.isSpeaking) {
mTextToSpeech.stop()
}
} catch (e: Exception) {
}
}
fun shutdown() {
stopSpeech()
mTextToSpeech.shutdown()
}
}

View File

@ -42,6 +42,9 @@
<item name="android:gravity">center_vertical</item>
<item name="android:paddingRight">6dp</item>
<item name="android:paddingLeft">10dp</item>
<item name="autoSizeMaxTextSize">14sp</item>
<item name="autoSizeMinTextSize">8sp</item>
<item name="autoSizeTextType">uniform</item>
<item name="android:drawableRight">@drawable/baseline_keyboard_arrow_down_12</item>
<item name="android:background">@drawable/shape_rect_white_2dp_bg</item>
<item name="android:layout_width">match_parent</item>