[Opt]全览模式View和业务分离

This commit is contained in:
chenfufeng
2023-02-06 18:45:30 +08:00
parent 2ce02f2a5b
commit 2c6684b617
23 changed files with 206 additions and 1107 deletions

View File

@@ -57,6 +57,9 @@ dependencies {
kapt rootProject.ext.dependencies.aroutercompiler
implementation rootProject.ext.dependencies.rxandroid
implementation rootProject.ext.dependencies.androidxroomruntime
kapt rootProject.ext.dependencies.androidxroomcompiler
implementation rootProject.ext.dependencies.androidxroomktx
implementation project(':foudations:mogo-commons')
implementation project(':core:mogo-core-data')

View File

@@ -2,6 +2,7 @@ package com.mogo.eagle.function.biz
import android.content.Context
import com.alibaba.android.arouter.facade.annotation.Route
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.camera.CameraEntity
import com.mogo.eagle.core.data.constants.MogoServicePaths
import com.mogo.eagle.core.function.api.biz.IMoGoFuncBizProvider
@@ -10,6 +11,8 @@ import com.mogo.eagle.function.biz.dispatch.DispatchAutoPilotManager.Companion.d
import com.mogo.eagle.function.biz.monitoring.CronTaskManager.Companion.cronTaskManager
import com.mogo.eagle.function.biz.notice.NoticeSocketManager.Companion.noticeSocketManager
import com.mogo.eagle.function.biz.notice.network.NoticeNetWorkManager
import com.mogo.eagle.function.biz.v2x.overview.OverViewDataManager
import com.mogo.eagle.function.biz.v2x.overview.db.OverviewDb
import com.mogo.eagle.function.biz.v2x.speedlimit.SpeedLimitDispatcher
import com.mogo.eagle.function.biz.v2x.trafficlight.core.MogoTrafficLightManager
import com.mogo.eagle.function.biz.v2x.trafficlight.core.TrafficLightDispatcher
@@ -68,6 +71,18 @@ class FuncBizProvider : IMoGoFuncBizProvider {
cronTaskManager.clear()
}
override fun fetchInfStructures() {
OverViewDataManager.fetchInfStructures()
}
override fun getAllV2XEvents() {
OverViewDataManager.getAllV2XEventsByLineId(MoGoAiCloudClientConfig.getInstance().sn)
}
override fun initOverViewDb(context: Context) {
OverviewDb.getDb(context)
}
override fun onDestroy() {
noticeSocketManager.release()
dispatchAutoPilotManager.release()

View File

@@ -1,21 +1,23 @@
package com.mogo.eagle.core.function.overview
package com.mogo.eagle.function.biz.v2x.overview
import androidx.lifecycle.*
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.constants.HostConst
import com.mogo.eagle.core.data.map.Infrastructure
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.overview.db.OverviewDb
import com.mogo.eagle.core.function.overview.remote.OverViewServiceApi
import com.mogo.eagle.core.function.overview.remote.V2XEvent
import com.mogo.eagle.core.function.call.biz.CallerFuncBizListenerManager
import com.mogo.eagle.core.network.MoGoRetrofitFactory
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.function.biz.v2x.overview.db.OverviewDb
import com.mogo.eagle.function.biz.v2x.overview.remote.OverViewServiceApi
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.concurrent.TimeUnit
object OverViewDataManager {
@@ -26,37 +28,8 @@ object OverViewDataManager {
OverviewDb.getDb(AbsMogoApplication.getApp()).overviewDao()
}
private val _infStructures = MutableLiveData<List<Infrastructure>>()
private val _V2XEvents = MutableLiveData<List<V2XEvent>>()
private var disposable: Disposable? = null
val infStructures
get() = _infStructures
private val _infStructuresMap = _infStructures
.switchMap { infStructures ->
liveData {
val map = HashMap<String, ArrayList<Infrastructure>>()
infStructures.forEach {
val geoHash = it.geoHash
if (geoHash == null) {
return@forEach
} else {
if (!map.containsKey(geoHash)) {
val list = ArrayList<Infrastructure>()
list.add(it)
map[geoHash] = list
} else {
map[geoHash]?.add(it)
}
}
}
emit(map)
}
}
val infStructuresMap
get() = _infStructuresMap
fun fetchInfStructures() {
ProcessLifecycleOwner.get().lifecycleScope.launch {
val data = try {
@@ -67,8 +40,27 @@ object OverViewDataManager {
e.printStackTrace()
null
}
data?.let {
_infStructures.value = it
data?.let { infStructures ->
withContext(Dispatchers.Default) {
val map = HashMap<String, ArrayList<Infrastructure>>()
infStructures.forEach {
val geoHash = it.geoHash
if (geoHash == null) {
return@forEach
} else {
if (!map.containsKey(geoHash)) {
val list = ArrayList<Infrastructure>()
list.add(it)
map[geoHash] = list
} else {
map[geoHash]?.add(it)
}
}
}
withContext(Dispatchers.Main) {
CallerFuncBizListenerManager.invokeInfStructures(map)
}
}
}
}
}
@@ -113,13 +105,11 @@ object OverViewDataManager {
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
it?.apply {
_V2XEvents.value = this
CallerFuncBizListenerManager.invokeV2XEvents(this)
}
}
}
fun getV2XEventLiveData() = _V2XEvents
fun stopQueryV2XEvents() {
disposable?.dispose()
}

View File

@@ -1,4 +1,4 @@
package com.mogo.eagle.core.function.overview.db
package com.mogo.eagle.function.biz.v2x.overview.db
import androidx.room.Dao
import androidx.room.Query

View File

@@ -1,4 +1,4 @@
package com.mogo.eagle.core.function.overview.db
package com.mogo.eagle.function.biz.v2x.overview.db
import android.content.Context
import androidx.room.Database

View File

@@ -1,4 +1,4 @@
package com.mogo.eagle.core.function.overview.remote
package com.mogo.eagle.function.biz.v2x.overview.remote
import io.reactivex.Observable
import retrofit2.http.GET

View File

@@ -0,0 +1,20 @@
package com.mogo.eagle.function.biz.v2x.overview.remote
import androidx.annotation.Keep
import com.google.gson.annotations.SerializedName
import com.mogo.eagle.core.data.BaseData
import com.mogo.eagle.core.data.v2x.V2XEvent
@Keep
data class V2XEventResult (
@SerializedName("result")
var result: Result?
): BaseData()
@Keep
data class Result(
@SerializedName("eventList")
var v2XEventList: List<V2XEvent>?
)

View File

@@ -343,34 +343,34 @@ class MoGoHmiFragment : MvpFragment<MoGoHmiContract.View?, HmiPresenter?>(),
}
override fun showSmallFragment() {
// 加载全览模式图层
val fragmentOverview = ARouter.getInstance().build(MoGoFragmentPaths.PATH_FRAGMENT_OVERVIEW)
.navigation() as BaseFragment
activity?.supportFragmentManager?.beginTransaction()
?.setCustomAnimations(R.anim.slide_in, R.anim.fade_out)?.apply {
if (!fragmentOverview.isAdded) {
add(
R.id.module_main_id_smp_fragment,
fragmentOverview,
fragmentOverview.tagName
)
} else {
show(fragmentOverview)
}.commitAllowingStateLoss()
}
CallerDevaToolsManager.hideStatusBar()
// // 加载全览模式图层
// val fragmentOverview = ARouter.getInstance().build(MoGoFragmentPaths.PATH_FRAGMENT_OVERVIEW)
// .navigation() as BaseFragment
// activity?.supportFragmentManager?.beginTransaction()
// ?.setCustomAnimations(R.anim.slide_in, R.anim.fade_out)?.apply {
// if (!fragmentOverview.isAdded) {
// add(
// R.id.module_main_id_smp_fragment,
// fragmentOverview,
// fragmentOverview.tagName
// )
// } else {
// show(fragmentOverview)
// }.commitAllowingStateLoss()
// }
// CallerDevaToolsManager.hideStatusBar()
}
override fun hideSmallFragment() {
val fragmentOverview = ARouter.getInstance().build(MoGoFragmentPaths.PATH_FRAGMENT_OVERVIEW)
.navigation() as BaseFragment
activity?.supportFragmentManager?.beginTransaction()
?.setCustomAnimations(R.anim.slide_in, R.anim.fade_out)?.apply {
if (fragmentOverview.isVisible) {
hide(fragmentOverview)
}
}
?.commitAllowingStateLoss()
// val fragmentOverview = ARouter.getInstance().build(MoGoFragmentPaths.PATH_FRAGMENT_OVERVIEW)
// .navigation() as BaseFragment
// activity?.supportFragmentManager?.beginTransaction()
// ?.setCustomAnimations(R.anim.slide_in, R.anim.fade_out)?.apply {
// if (fragmentOverview.isVisible) {
// hide(fragmentOverview)
// }
// }
// ?.commitAllowingStateLoss()
}
}

View File

@@ -22,12 +22,12 @@ import com.mogo.eagle.core.data.constants.MoGoConfig;
import com.mogo.eagle.core.data.constants.MogoServicePaths;
import com.mogo.eagle.core.function.api.chat.biz.ChatConsts;
import com.mogo.eagle.core.function.api.devatools.IMogoDevaToolsUpgradeListener;
import com.mogo.eagle.core.function.call.biz.CallerFuncBizManager;
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager;
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsUpgradeListenerManager;
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager;
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager;
import com.mogo.eagle.core.function.msgbox.db.MsgBoxDb;
import com.mogo.eagle.core.function.overview.db.OverviewDb;
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils;
import com.mogo.eagle.core.utilcode.mogo.AppLaunchTimeUtils;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
@@ -194,7 +194,7 @@ public abstract class MainMoGoApplication extends AbsMogoApplication {
}
private void initOverviewDb() {
OverviewDb.Companion.getDb(this);
CallerFuncBizManager.getBizProvider().initOverViewDb(this);
}
/**

View File

@@ -11,7 +11,6 @@ import com.mogo.eagle.core.data.map.CenterLine
import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLamplightListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationWGS84Listener
import com.mogo.eagle.core.function.api.autopilot.IMoGoPlanningRottingListener
import com.mogo.eagle.core.function.api.map.hd.IMoGoMapFragmentProvider
import com.mogo.eagle.core.function.api.setting.IMoGoSkinModeChangeListener
import com.mogo.eagle.core.function.business.MapPointCloudSubscriber
@@ -20,20 +19,11 @@ import com.mogo.eagle.core.function.business.identify.MapIdentifySubscriber
import com.mogo.eagle.core.function.business.routeoverlay.MogoRouteOverlayManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLamplightListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager
import com.mogo.eagle.core.function.call.map.CallerHDMapManager
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
import com.mogo.eagle.core.function.call.setting.CallerSkinModeListenerManager
import com.mogo.eagle.core.function.overview.InfStructureManager
import com.mogo.eagle.core.function.overview.InfStructureManager.savePlanningData
import com.mogo.eagle.core.function.overview.obtainViewModel
import com.mogo.eagle.core.function.overview.vm.OverViewModel
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.e
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr
import com.mogo.eagle.core.utilcode.util.Utils
import com.mogo.map.IMogoMap
import com.mogo.map.MogoMapView
import com.mogo.map.uicontroller.IMogoMapUIController

View File

@@ -1,51 +0,0 @@
package com.mogo.eagle.core.function.overview
import com.mogo.eagle.core.data.map.Infrastructure
import mogo.telematics.pad.MessagePad
/**
* 本地数据库查询出来的红绿灯、摄像头等数据
*/
object InfStructureManager {
// 每个GeoHash网格对应的新基建Bean
private val _infMap by lazy {
HashMap<String, ArrayList<Infrastructure>>()
}
// 全局路径规划中所有点的GeoHash网格对应的新基建数据集合
private val _pathMap by lazy {
HashMap<String, ArrayList<Infrastructure>>()
}
private val _planningList by lazy {
ArrayList<MessagePad.Location>()
}
fun saveData(map: HashMap<String, java.util.ArrayList<Infrastructure>>) {
if (_infMap.isNotEmpty()) {
_infMap.clear()
}
_infMap.putAll(map)
}
fun getData(): Map<String, ArrayList<Infrastructure>> = _infMap
fun savePathData(map: HashMap<String, java.util.ArrayList<Infrastructure>>) {
if (_pathMap.isNotEmpty()) {
_pathMap.clear()
}
_pathMap.putAll(map)
}
fun getPathData(): Map<String, ArrayList<Infrastructure>> = _pathMap
fun savePlanningData(planningList: List<MessagePad.Location>) {
if (_planningList.isNotEmpty()) {
_planningList.clear()
}
_planningList.addAll(planningList)
}
fun getPlanningData() = _planningList
}

View File

@@ -1,13 +0,0 @@
package com.mogo.eagle.core.function.overview
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProviders
import com.mogo.commons.AbsMogoApplication
fun <T : ViewModel> AppCompatActivity.obtainViewModel(viewModelClass: Class<T>) =
ViewModelProviders.of(this, ViewModelFactory.getInstance(application)).get(viewModelClass)
fun <T : ViewModel> Fragment.obtainViewModel(viewModelClass: Class<T>) =
ViewModelProviders.of(this, ViewModelFactory.getInstance(AbsMogoApplication.getApp())).get(viewModelClass)

View File

@@ -1,41 +0,0 @@
package com.mogo.eagle.core.function.overview
import android.annotation.SuppressLint
import android.app.Application
import androidx.annotation.VisibleForTesting
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.mogo.eagle.core.function.overview.db.OverviewDao
import com.mogo.eagle.core.function.overview.db.OverviewDb
import com.mogo.eagle.core.function.overview.vm.OverViewModel
class ViewModelFactory private constructor(
private val overviewDao: OverviewDao
) : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>) =
with(modelClass) {
when {
isAssignableFrom(OverViewModel::class.java) ->
OverViewModel(overviewDao)
else ->
throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}")
}
} as T
companion object {
@SuppressLint("StaticFieldLeak")
@Volatile private var INSTANCE: ViewModelFactory? = null
fun getInstance(application: Application) =
INSTANCE ?: synchronized(ViewModelFactory::class.java) {
INSTANCE ?: ViewModelFactory(
OverviewDb.getDb(application).overviewDao())
.also { INSTANCE = it }
}
@VisibleForTesting fun destroyInstance() {
INSTANCE = null
}
}
}

View File

@@ -20,17 +20,16 @@ import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.map.Infrastructure
import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.data.v2x.V2XEvent
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
import com.mogo.eagle.core.function.api.autopilot.IMoGoPlanningRottingListener
import com.mogo.eagle.core.function.api.v2x.IFuncBizProvider
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager.getGlobalPath
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ20ListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager
import com.mogo.eagle.core.function.call.biz.CallerFuncBizListenerManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager.showVideoDialog
import com.mogo.eagle.core.function.map.R
import com.mogo.eagle.core.function.overview.InfStructureManager
import com.mogo.eagle.core.function.overview.InfStructureManager.getData
import com.mogo.eagle.core.function.overview.OverViewDataManager
import com.mogo.eagle.core.function.overview.remote.V2XEvent
import com.mogo.eagle.core.function.smp.MakerWithCount
import com.mogo.eagle.core.function.smp.MarkerDrawerManager
import com.mogo.eagle.core.function.smp.MarkerDrawerManager.callback
@@ -40,7 +39,6 @@ import com.mogo.eagle.core.function.smp.MarkerDrawerManager.planningPoints
import com.mogo.eagle.core.function.smp.MarkerDrawerManager.startLoopCalCarLocation
import com.mogo.eagle.core.function.smp.MarkerDrawerManager.updateRoutePoints
import com.mogo.eagle.core.function.smp.V2XMarkerView
import com.mogo.eagle.core.utilcode.kotlin.lifecycleOwner
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils.isTaxi
import com.mogo.eagle.core.utilcode.mogo.MapAssetStyleUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
@@ -69,6 +67,8 @@ class OverMapView @JvmOverloads constructor(
private val pathMap: MutableMap<String?, ArrayList<Infrastructure>?> = HashMap()
private val posInfMap: MutableMap<LatLng?, ArrayList<Infrastructure>?> = HashMap()
private var geoHashInfMap: HashMap<String, java.util.ArrayList<Infrastructure>>? = null
// =============绘制轨迹线相关=============
private var mCarMarker: Marker? = null
private var mCompassMarker: Marker? = null
@@ -189,18 +189,17 @@ class OverMapView @JvmOverloads constructor(
override fun onAttachedToWindow() {
super.onAttachedToWindow()
OverViewDataManager.infStructuresMap.observe(lifecycleOwner) { list ->
InfStructureManager.saveData(list)
}
// 查询本地数据库中的摄像头数据
OverViewDataManager.fetchInfStructures()
CallerFuncBizListenerManager.addListener(TAG, object : IFuncBizProvider {
override fun onInfStructures(map: HashMap<String, ArrayList<Infrastructure>>?) {
geoHashInfMap = map
}
override fun onV2XEvents(v2xEvents: List<V2XEvent>?) {
showV2XEventMarkers(v2xEvents)
}
})
// 主动查一次全局路径规划的数据
getGlobalPath()
// 定时查询V2X事件
OverViewDataManager.getV2XEventLiveData().observe(lifecycleOwner) {
showV2XEventMarkers(it)
}
OverViewDataManager.getAllV2XEventsByLineId(MoGoAiCloudClientConfig.getInstance().sn)
}
private fun setUpMap() {
@@ -297,32 +296,45 @@ class OverMapView @JvmOverloads constructor(
}
}
startLoopCalCarLocation()
UiThreadHandler.post { drawInfrastructureMarkers(locationList) }
UiThreadHandler.post {
if (geoHashInfMap.isNullOrEmpty()) {
UiThreadHandler.postDelayed({
drawInfrastructureMarkers(locationList)
}, 1000)
} else {
drawInfrastructureMarkers(locationList)
}
}
}
/**
* 显示V2X事件的Marker
*/
fun showV2XEventMarkers(v2XEvents: List<V2XEvent>?) {
private fun showV2XEventMarkers(v2XEvents: List<V2XEvent>?) {
if (v2XEvents == null || v2XEvents.isEmpty()) return
clearV2XMarkers()
val markerOptionsList = ArrayList<MarkerOptions>()
for ((_, _, _, center, _, _, poiType, coordinateType) in v2XEvents) {
for (v2xEvent in v2XEvents) {
val center = v2xEvent.center
if (center != null) {
center.lon
val markerOption = MarkerOptions()
var latLng: LatLng = if (coordinateType == null || coordinateType == 0) {
LatLng(center.lat, center.lon)
} else {
// wgs84坐标系需转成高德坐标系
coordinateConverterWgsToGcj(mContext!!, center.lat, center.lon)
}
var latLng: LatLng =
if (v2xEvent.coordinateType == null || v2xEvent.coordinateType == 0) {
LatLng(center.lat, center.lon)
} else {
// wgs84坐标系需转成高德坐标系
coordinateConverterWgsToGcj(
mContext!!,
center.lat,
center.lon
)
}
markerOption.position(latLng)
markerOption.anchor(0.13f, 1f)
markerOption.icon(
BitmapDescriptorFactory.fromBitmap(
getV2XBitmap(
poiType
v2xEvent.poiType
)
)
)
@@ -364,7 +376,6 @@ class OverMapView @JvmOverloads constructor(
// 注册定位监听
CallerChassisLocationGCJ20ListenerManager.removeListener(TAG)
CallerPlanningRottingListenerManager.removeListener(TAG)
OverViewDataManager.stopQueryV2XEvents()
}
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
@@ -386,7 +397,8 @@ class OverMapView @JvmOverloads constructor(
* @param locationList
*/
private fun drawInfrastructureMarkers(locationList: List<MessagePad.Location>?) {
if (locationList == null) return
val infMap = geoHashInfMap
if (locationList == null || infMap.isNullOrEmpty()) return
if (pathMap.isNotEmpty()) {
pathMap.clear()
}
@@ -399,7 +411,7 @@ class OverMapView @JvmOverloads constructor(
// 网格内的轨迹点只取一次s
if (!pathMap.containsKey(geoHash)) {
// 从缓存的新基建数据中去取对应geoHash的新基建数据集合
infList = getData()[geoHash]
infList = infMap[geoHash]
if (infList != null) {
pathMap[geoHash] = infList
}

View File

@@ -1,141 +0,0 @@
package com.mogo.eagle.core.function.overview.vm
import androidx.lifecycle.*
import com.mogo.commons.constants.HostConst
import com.mogo.eagle.core.data.map.Infrastructure
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfo
import com.mogo.eagle.core.function.overview.db.OverviewDao
import com.mogo.eagle.core.function.overview.remote.OverViewServiceApi
import com.mogo.eagle.core.function.overview.remote.V2XEvent
import com.mogo.eagle.core.network.MoGoRetrofitFactory
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.launch
import java.util.concurrent.TimeUnit
class OverViewModel(
private val overviewDao: OverviewDao
) : ViewModel() {
private val _infStructures = MutableLiveData<List<Infrastructure>>()
private val _V2XEvents = MutableLiveData<List<V2XEvent>>()
private var disposable: Disposable? = null
companion object {
const val TAG = "OverViewModel"
}
val infStructures
get() = _infStructures
private val _infStructuresMap = _infStructures
.switchMap { infStructures ->
liveData {
val map = HashMap<String, ArrayList<Infrastructure>>()
infStructures.forEach {
val geoHash = it.geoHash
if (geoHash == null) {
return@forEach
} else {
if (!map.containsKey(geoHash)) {
val list = ArrayList<Infrastructure>()
list.add(it)
map[geoHash] = list
} else {
map[geoHash]?.add(it)
}
}
}
emit(map)
}
}
val infStructuresMap
get() = _infStructuresMap
fun fetchInfStructures() {
viewModelScope.launch {
val data = try {
// 只查找摄像头
overviewDao.listInfStructures(0)
// overviewDao.listAllInfStructures()
} catch (e: Exception) {
e.printStackTrace()
null
}
data?.let {
_infStructures.value = it
}
}
}
fun updateGeoHash(id: Int, geoHash: String) {
viewModelScope.launch {
try {
overviewDao.updateGeoHash(id, geoHash)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
fun getAllV2XEventsByLineId(sn: String) {
if (disposable != null && !disposable!!.isDisposed) {
disposable!!.dispose()
}
// 1分钟查询一次
disposable = Observable.interval(2000, 60000, TimeUnit.MILLISECONDS)
.flatMap {
val lineId = getLineId()
if (lineId > 0) {
MoGoRetrofitFactory.getInstance(HostConst.getHost())
.create(OverViewServiceApi::class.java)
.queryAllV2XEventsByLineId(lineId.toString(), sn)
.map {
if (it.code == 200 || it.code == 0) {
CallerLogger.d(SceneConstant.M_MAP + TAG, "请求成功size为${it.result?.v2XEventList?.size}")
return@map it.result?.v2XEventList
} else {
CallerLogger.d(SceneConstant.M_MAP + TAG, "请求失败code为${it.code}")
return@map ArrayList()
}
}
} else {
Observable.just(ArrayList())
}
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
it?.apply {
_V2XEvents.value = this
}
}
}
fun getV2XEventLiveData() = _V2XEvents
fun stopQueryV2XEvents() {
disposable?.dispose()
}
private fun getLineId(): Long {
var lineId: Long = -1
val parameter = getAutoPilotStatusInfo()
.autopilotControlParameters
if (parameter != null) {
if (parameter.autoPilotLine != null) {
lineId = parameter.autoPilotLine!!.lineId
CallerLogger.d(SceneConstant.M_MAP + TAG, "lineId为:$lineId")
} else {
CallerLogger.d(SceneConstant.M_MAP + TAG, "parameter.autoPilotLine为null")
}
} else {
CallerLogger.d(SceneConstant.M_MAP + TAG, "parameter为null")
}
return lineId
}
}

View File

@@ -1,550 +0,0 @@
package com.mogo.eagle.core.function.smp;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.TextureMapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.CustomMapStyleOptions;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.Polyline;
import com.amap.api.maps.model.PolylineOptions;
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
import com.mogo.eagle.core.data.map.Infrastructure;
import com.mogo.eagle.core.data.map.MogoLocation;
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener;
import com.mogo.eagle.core.function.api.autopilot.IMoGoPlanningRottingListener;
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ20ListenerManager;
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager;
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager;
import com.mogo.eagle.core.function.map.R;
import com.mogo.eagle.core.function.overview.InfStructureManager;
import com.mogo.eagle.core.function.overview.remote.Center;
import com.mogo.eagle.core.function.overview.remote.V2XEvent;
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils;
import com.mogo.eagle.core.utilcode.mogo.MapAssetStyleUtils;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import ch.hsr.geohash.GeoHash;
import kotlin.Pair;
import me.jessyan.autosize.utils.AutoSizeUtils;
import mogo.telematics.pad.MessagePad;
/**
* 小地图的方向View
* 监听自动驾驶路径结束,结束高德地图导航
*
* @author donghongyu
* @date 12/14/20 4:40 PM
*/
public class AMapCustomView
extends RelativeLayout
implements IMoGoChassisLocationGCJ02Listener {
public static final String TAG = "AMapCustomView";
private TextureMapView mAMapView;
private AMap mAMap;
private int zoomLevel = 15;
private CameraUpdate mCameraUpdate;
private Context mContext;
private float mTilt = 60f;
private TextView overLayerView;
private boolean calculate = false;
// 全局路径规划中的GeoHash网格
private Map<String, ArrayList<Infrastructure>> pathMap = new HashMap();
private Map<LatLng, ArrayList<Infrastructure>> posInfMap = new HashMap();
// =============绘制轨迹线相关=============
private Marker mCarMarker;
private Marker mCompassMarker;
private Marker mStartMarker;
private Marker mEndMarker;
private Polyline mBottomPolyline;
private Polyline mCoveredPolyline;
// 计算索引并设置对应的Bitmap
BitmapDescriptor arrivedBitmap;
BitmapDescriptor unArrivedBitmap;
// 绘制轨迹线的集合
private List<BitmapDescriptor> textureList = new ArrayList<>();
private List<Integer> texIndexList = new ArrayList<>();
private MogoLocation mLocation;
private boolean isFirstLocation = true;
CustomMapStyleOptions mCustomMapStyleOptions;
ArrayList<Marker> currMarkerList;
public AMapCustomView(Context context) {
this(context, null);
}
public AMapCustomView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public AMapCustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
try {
initView(context);
} catch (Exception e) {
e.printStackTrace();
}
}
private void initView(Context context) {
mContext = context;
View smpView = LayoutInflater.from(context).inflate(R.layout.module_overview_map_view, this);
mAMapView = smpView.findViewById(R.id.aMapView);
overLayerView = findViewById(R.id.overLayer);
if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) {
overLayerView.setBackground(getResources().getDrawable(R.drawable.amap_reset));
arrivedBitmap = BitmapDescriptorFactory.fromResource(R.drawable.taxi_map_arrow_arrived);
unArrivedBitmap = BitmapDescriptorFactory.fromResource(R.drawable.taxi_map_arrow_un_arrive);
} else {
overLayerView.setBackground(getResources().getDrawable(R.drawable.amap_reset_bus));
arrivedBitmap = BitmapDescriptorFactory.fromResource(R.drawable.arrow_arrived_img);
unArrivedBitmap = BitmapDescriptorFactory.fromResource(R.drawable.amap_bus_smooth_route);
}
CallerPlanningRottingListenerManager.INSTANCE.addListener(TAG, moGoAutopilotPlanningListener);
initAMapView(context);
// 注册定位监听
CallerChassisLocationGCJ20ListenerManager.INSTANCE.addListener(TAG, this);
//设置全览模式
overLayerView.setOnClickListener(v -> {
displayCustomOverView();
});
}
private void initAMapView(Context context) {
Log.d(TAG, "initAMapView");
mCameraUpdate = CameraUpdateFactory.zoomTo(zoomLevel);
mAMap = mAMapView.getMap();
mCustomMapStyleOptions = new CustomMapStyleOptions();
if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) {
mCustomMapStyleOptions.setStyleData(MapAssetStyleUtils.getAssetsStyle(getContext(), "over_view_style.data"));
mCustomMapStyleOptions.setStyleExtraData(MapAssetStyleUtils.getAssetsExtraStyle(getContext(), "over_view_style_extra.data"));
} else {
mCustomMapStyleOptions.setStyleData(MapAssetStyleUtils.getAssetsStyle(getContext(), "over_view_style_bus.data"));
mCustomMapStyleOptions.setStyleExtraData(MapAssetStyleUtils.getAssetsExtraStyle(getContext(), "over_view_style_extra_bus.data"));
}
mAMap.setOnMapLoadedListener(() -> {
Log.d(TAG, "---onMapLoaded---");
if (mCustomMapStyleOptions != null) {
// 加载自定义样式
mCustomMapStyleOptions.setEnable(true);
// 设置自定义样式
mAMap.setCustomMapStyle(mCustomMapStyleOptions);
}
// 实时路况图层关闭必须添加在loaded结束之后,其他位置不生效
mAMap.setTrafficEnabled(false);
});
setUpMap();
customOptions();
}
private void setUpMap() {
// 地图文字标注
mAMap.showMapText(true);
//设置希望展示的地图缩放级别
mAMap.moveCamera(mCameraUpdate);
//设置地图的样式
UiSettings uiSettings = mAMap.getUiSettings();
//地图缩放级别的交换按钮
uiSettings.setZoomControlsEnabled(false);
//所有手势
uiSettings.setAllGesturesEnabled(true);
//隐藏指南针
uiSettings.setCompassEnabled(false);
//设置倾斜手势是否可用。
uiSettings.setTiltGesturesEnabled(true);
//隐藏默认的定位按钮
uiSettings.setMyLocationButtonEnabled(false);
//设置Logo下边界距离屏幕底部的边距,设置为负值即可
uiSettings.setLogoBottomMargin(-150);
Log.d(TAG, "before onMapLoaded");
}
/**
* 自定义导航View和路况状态
*/
private void customOptions() {
if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) {
mCarMarker = mAMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.map_car_icon))
.anchor(0.5f, 0.5f));
mCompassMarker = mAMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.amap_custom_corner))
.anchor(0.5f, 0.5f));
} else {
mCarMarker = mAMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.map_bus_icon))
.anchor(0.5f, 0.5f));
mCompassMarker = mAMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.amap_bus_corner))
.anchor(0.5f, 0.5f));
}
mStartMarker = mAMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_dir_start)));
mEndMarker = mAMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_dir_end)));
}
private final IMoGoPlanningRottingListener moGoAutopilotPlanningListener = new IMoGoPlanningRottingListener() {
/**
* 根据全路径获取起始点和经停点进行导航路线绘制
* 自动驾驶启动后获得数据,获取全路径的具体时间要进行路测
* 室内某个bag包自动驾驶启动8s后返回
*/
@Override
public void onAutopilotRotting(@org.jetbrains.annotations.Nullable MessagePad.GlobalPathResp globalPathResp) {
Log.d(TAG, "onAutopilotRotting");
if (globalPathResp != null) {
handlePlanningData(globalPathResp.getWayPointsList());
}
}
};
public void handlePlanningData(List<MessagePad.Location> locationList) {
if (locationList == null || locationList.size() == 0) return;
List list = locationList;
// 转成高德坐标系并存储
MarkerDrawerManager.INSTANCE.updateRoutePoints(list, mContext);
List<LatLng> planningPointList = MarkerDrawerManager.INSTANCE.getPlanningPoints();
UiThreadHandler.post(() -> {
displayCustomOverView();
drawStartAndEndMarker(planningPointList);
});
MarkerDrawerManager.INSTANCE.setCallback((points, locIndex) -> {
// 每1s刷新一下轨迹线
UiThreadHandler.post(() -> {
if (points.size() > 0) {
drawPolyline(points, locIndex);
}
});
});
MarkerDrawerManager.INSTANCE.startLoopCalCarLocation();
UiThreadHandler.post(() -> {
drawInfrastructureMarkers(locationList);
});
}
public void showV2XEventMarkers(List<V2XEvent> v2XEvents) {
if (v2XEvents == null || v2XEvents.size() <= 0) return;
clearV2XMarkers();
ArrayList<MarkerOptions> markerOptionsList = new ArrayList<>();
for (V2XEvent event : v2XEvents) {
Center center = event.getCenter();
if (center != null) {
center.getLon();
MarkerOptions markerOption = new MarkerOptions();
LatLng latLng;
if (event.getCoordinateType() == null || event.getCoordinateType() == 0) {
latLng = new LatLng(center.getLat(), center.getLon());
} else {
// wgs84坐标系需转成高德坐标系
latLng = MarkerDrawerManager.INSTANCE.coordinateConverterWgsToGcj(mContext, center.getLat(), center.getLon());
}
markerOption.position(latLng);
markerOption.anchor(0.13f, 1f);
markerOption.icon(BitmapDescriptorFactory.fromBitmap(getV2XBitmap(event.getPoiType())));
markerOptionsList.add(markerOption);
}
}
if (markerOptionsList.size() > 0) {
drawV2XMarkers(markerOptionsList);
}
}
public void drawV2XMarkers(ArrayList<MarkerOptions> markerOptionsList) {
currMarkerList = mAMap.addMarkers(markerOptionsList, false);
}
private Bitmap getV2XBitmap(String poiType) {
V2XMarkerView marker = new V2XMarkerView(getContext(), null, 0, poiType);
marker.measure(View.MeasureSpec.makeMeasureSpec(AutoSizeUtils.dp2px(mContext, 229), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(AutoSizeUtils.dp2px(mContext, 96), View.MeasureSpec.EXACTLY));
marker.layout(0, 0, marker.getMeasuredWidth(), marker.getMeasuredHeight());
Bitmap bitmap = Bitmap.createBitmap(marker.getWidth(), marker.getHeight(), Bitmap.Config.ARGB_8888);
marker.draw(new Canvas(bitmap));
return bitmap;
}
public void clearV2XMarkers() {
if (currMarkerList != null) {
for (Marker marker : currMarkerList) {
marker.destroy();
}
currMarkerList = null;
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
// 注册定位监听
CallerChassisLocationGCJ20ListenerManager.INSTANCE.removeListener(TAG);
CallerPlanningRottingListenerManager.INSTANCE.removeListener(TAG);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return false;
}
public void onCreateView(Bundle savedInstanceState) {
if (mAMapView != null) {
mAMapView.onCreate(savedInstanceState);
}
}
public void onResume() {
if (mAMapView != null) {
mAMapView.onResume();
}
}
public void onPause() {
if (mAMapView != null) {
mAMapView.onPause();
}
}
public void onDestroy() {
if (mAMapView != null) {
mAMapView.onDestroy();
}
if (mAMapView != null) {
mAMapView.onDestroy();
}
}
public void clearCustomPolyline() {
if (mBottomPolyline != null) {
mBottomPolyline.remove();
}
if (mCoveredPolyline != null) {
mCoveredPolyline.remove();
}
}
/**
* 绘制新基建Markers(比如:摄像头)
*
* @param locationList
*/
private void drawInfrastructureMarkers(List<MessagePad.Location> locationList) {
if (locationList == null) return;
if (!pathMap.isEmpty()) {
pathMap.clear();
}
String geoHash;
ArrayList<Infrastructure> infList;
for (int i = 0; i < locationList.size(); i++) {
LatLng latLng = MarkerDrawerManager.INSTANCE.coordinateConverterWgsToGcj(mContext, locationList.get(i));
geoHash = GeoHash.withCharacterPrecision(latLng.latitude, latLng.longitude, 7).toBase32();
// 网格内的轨迹点只取一次s
if (!pathMap.containsKey(geoHash)) {
// 从缓存的新基建数据中去取对应geoHash的新基建数据集合
infList = InfStructureManager.INSTANCE.getData().get(geoHash);
if (infList != null) {
pathMap.put(geoHash, infList);
}
}
}
drawInfMarkers(pathMap);
}
//todo 扶风 需重构此处,封装至 全览
public void drawInfMarkers(Map<String, ArrayList<Infrastructure>> infStruMap) {
// 绘制新基建数据
if (!posInfMap.isEmpty()) {
posInfMap.clear();
}
ArrayList<MarkerOptions> markerOptionsList = new ArrayList();
for (ArrayList<Infrastructure> structureList : infStruMap.values()) {
// 每个GeoHash内根据坐标系象限分散开摄像头icon显示
MarkerOptions markerOption = new MarkerOptions();
LatLng latLng = new LatLng(Double.valueOf(structureList.get(0).getLat()),
Double.valueOf(structureList.get(0).getLon()));
markerOption.position(latLng);
Bitmap bitmap = getBitmap(structureList.size());
markerOption.icon(BitmapDescriptorFactory.fromBitmap(
bitmap
));
markerOption.zIndex(2f);
posInfMap.put(latLng, structureList);
markerOptionsList.add(markerOption);
}
mAMap.addMarkers(markerOptionsList, false);
mAMap.setOnMarkerClickListener(marker -> {
List<Infrastructure> infList = posInfMap.get(marker.getPosition());
// 如果是摄像头
if (infList != null) {
CallerHmiManager.INSTANCE.showVideoDialog(infList);
return true;
}
return false;
});
}
private Bitmap getBitmap(int count) {
MakerWithCount marker = new MakerWithCount(getContext());
marker.setCount(count);
marker.measure(View.MeasureSpec.makeMeasureSpec(116, View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(116, View.MeasureSpec.EXACTLY));
marker.layout(0, 0, marker.getMeasuredWidth(), marker.getMeasuredHeight());
Bitmap bitmap = Bitmap.createBitmap(marker.getWidth(), marker.getHeight(), Bitmap.Config.ARGB_8888);
marker.draw(new Canvas(bitmap));
return bitmap;
}
/**
* 进入自定义全览模式
*/
private void displayCustomOverView() {
ArrayList<LatLng> linePointsLatLng = MarkerDrawerManager.INSTANCE.getPlanningPoints();
if (linePointsLatLng.size() > 1) {
//圈定地图显示范围
//存放经纬度
LatLngBounds.Builder boundsBuilder = new LatLngBounds.Builder();
for (int i = 0; i < linePointsLatLng.size(); i++) {
boundsBuilder.include(linePointsLatLng.get(i));
}
LatLng currentLatLng = new LatLng(mLocation.getLatitude(), mLocation.getLongitude());
boundsBuilder.include(currentLatLng);
CameraPosition cameraPosition = new CameraPosition.Builder().tilt(mTilt).build();
//第二个参数为四周留空宽度
mAMap.moveCamera(CameraUpdateFactory.newLatLngBoundsRect(boundsBuilder.build(), 100, 100, 100, 100));
mAMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
} else {
//设置希望展示的地图缩放级别
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(mCarMarker.getPosition()).tilt(0).zoom(zoomLevel).build();
mAMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
}
/**
* 绘制自车
*
* @param location
*/
private void drawCarMarker(MogoLocation location) {
if (location == null) return;
if (mCarMarker != null) {
LatLng currentLatLng = new LatLng(location.getLatitude(), location.getLongitude());
mCarMarker.setRotateAngle((float) (360 - location.getHeading()));
mCarMarker.setPosition(currentLatLng);
mCarMarker.setToTop();
if (mCompassMarker != null) {
mCompassMarker.setRotateAngle((float) (360 - location.getHeading()));
mCompassMarker.setPosition(currentLatLng);
}
}
}
/**
* 绘制起始点、终点
*/
private void drawStartAndEndMarker(List<LatLng> coordinates) {
if (mStartMarker != null) {
mStartMarker.setVisible(false);
}
if (mEndMarker != null) {
mEndMarker.setVisible(false);
}
if (coordinates.size() > 2) {
// 设置开始结束Marker位置
LatLng startLatLng = coordinates.get(0);
LatLng endLatLng = coordinates.get(coordinates.size() - 1);
mStartMarker.setPosition(startLatLng);
mEndMarker.setPosition(endLatLng);
mStartMarker.setVisible(true);
mEndMarker.setVisible(true);
}
}
/**
* 绘制轨迹线
*
* @param coordinates
* @param locIndex
*/
private void drawPolyline(List<LatLng> coordinates, int locIndex) {
if (textureList.size() > 0) {
textureList.clear();
}
if (texIndexList.size() > 0) {
texIndexList.clear();
}
for (int i = 0; i < coordinates.size(); i++) {
if (i <= locIndex) {
// 已走过的置灰
textureList.add(arrivedBitmap);
} else {
// 未走过的纹理
textureList.add(unArrivedBitmap);
}
texIndexList.add(i);
}
if (mAMap != null && coordinates.size() > 2) {
//设置线段纹理
PolylineOptions polylineOptions = new PolylineOptions();
polylineOptions.addAll(coordinates);
polylineOptions.width(14); //线段宽度
polylineOptions.lineCapType(PolylineOptions.LineCapType.LineCapRound);
polylineOptions.setCustomTextureList(textureList);
polylineOptions.setCustomTextureIndex(texIndexList);
// 绘制线
mBottomPolyline = mCoveredPolyline;
mCoveredPolyline = mAMap.addPolyline(polylineOptions);
if (mBottomPolyline != null) {
mBottomPolyline.remove();
}
}
}
@Override
public void onChassisLocationGCJ02(@Nullable MogoLocation gnssInfo) {
mLocation = gnssInfo;
MarkerDrawerManager.INSTANCE.setLonLat(new Pair(gnssInfo.getLongitude(), gnssInfo.getLatitude()));
drawCarMarker(gnssInfo);
if (isFirstLocation) {
displayCustomOverView();
isFirstLocation = false;
}
}
}

View File

@@ -1,163 +0,0 @@
package com.mogo.eagle.core.function.smp;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.Nullable;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
import com.mogo.commons.mvp.BaseFragment;
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters;
import com.mogo.eagle.core.data.constants.MoGoFragmentPaths;
import com.mogo.eagle.core.data.map.MogoLatLng;
import com.mogo.eagle.core.function.api.map.smp.IMogoSmallMapProvider;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
import com.mogo.eagle.core.function.map.R;
import com.mogo.eagle.core.function.overview.InfStructureManager;
import com.mogo.eagle.core.function.overview.ViewModelExtKt;
import com.mogo.eagle.core.function.overview.vm.OverViewModel;
import java.util.List;
/**
* @author donghongyu
* @date 2021/5/19 10:50 上午
* 全览模式Fragment
*/
@Route(path = MoGoFragmentPaths.PATH_FRAGMENT_OVERVIEW)
public class OverviewMapFragment extends BaseFragment
implements IMogoSmallMapProvider {
private final String TAG = "OverviewMapFragment";
protected AMapCustomView mAMapCustomView;
private OverViewModel mViewModel;
@Override
public void onAttach(Context context) {
super.onAttach(context);
}
@Override
protected int getLayoutId() {
return R.layout.module_overview_map_fragment;
}
@Override
public String getTagName() {
return TAG;
}
@Override
protected void initViews() {
}
@Override
protected void initViews(Bundle savedInstanceState) {
super.initViews(savedInstanceState);
mAMapCustomView = mRootView.findViewById(R.id.smallMapDirectionView);
mAMapCustomView.onCreateView(savedInstanceState);
}
@Override
public void showPanel() {
if (mAMapCustomView != null) {
mAMapCustomView.setVisibility(View.VISIBLE);
}
}
@Override
public void hidePanel() {
if (mAMapCustomView != null) {
mAMapCustomView.setVisibility(View.GONE);
}
}
@Override
public void startQueryV2XEvents() {
if (isAdded()) {
if (mViewModel != null) {
mViewModel.getAllV2XEventsByLineId(MoGoAiCloudClientConfig.getInstance().getSn());
}
}
}
@Override
public void clearV2XMarkers() {
if (isAdded()) {
if (mAMapCustomView != null) {
mAMapCustomView.clearV2XMarkers();
}
if (mViewModel != null) {
mViewModel.stopQueryV2XEvents();
}
}
}
@Override
public void drawablePolyline(List<MogoLatLng> coordinates) {
}
@Override
public void clearPolyline() {
}
@Override
public void onResume() {
super.onResume();
if (mAMapCustomView != null) {
mAMapCustomView.onResume();
}
mAMapCustomView.handlePlanningData(InfStructureManager.INSTANCE.getPlanningData());
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// 主动查一次全局路径规划的数据
CallerAutoPilotControlManager.INSTANCE.getGlobalPath();
queryV2XEvents();
}
private void queryV2XEvents() {
mViewModel = ViewModelExtKt.obtainViewModel(this, OverViewModel.class);
mViewModel.getV2XEventLiveData().observe(this.getViewLifecycleOwner(), v2XEvents -> {
mAMapCustomView.showV2XEventMarkers(v2XEvents);
});
mViewModel.getAllV2XEventsByLineId(MoGoAiCloudClientConfig.getInstance().getSn());
}
/**
* @return Taxi的下发的轨迹id
*/
private long getLineId() {
long lineId = -1;
AutopilotControlParameters parameter = CallerAutoPilotStatusListenerManager.INSTANCE.getAutoPilotStatusInfo()
.getAutopilotControlParameters();
if (parameter != null) {
if (parameter.autoPilotLine != null) {
lineId = parameter.autoPilotLine.getLineId();
}
}
return lineId;
}
@Override
public void onPause() {
super.onPause();
if (mAMapCustomView != null) {
mAMapCustomView.onPause();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mAMapCustomView != null) {
mAMapCustomView.onDestroy();
}
}
}

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mogo.eagle.core.function.smp.AMapCustomView
android:id="@+id/smallMapDirectionView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,22 +1,8 @@
package com.mogo.eagle.core.function.overview.remote
package com.mogo.eagle.core.data.v2x
import androidx.annotation.Keep
import com.google.gson.annotations.SerializedName
import com.mogo.eagle.core.data.BaseData
@Keep
data class V2XEventResult (
@SerializedName("result")
var result: Result?
): BaseData()
@Keep
data class Result(
@SerializedName("eventList")
var v2XEventList: List<V2XEvent>?
)
@Keep
data class V2XEvent(

View File

@@ -1,5 +1,6 @@
package com.mogo.eagle.core.function.api.biz
import android.content.Context
import com.mogo.eagle.core.data.camera.CameraEntity
import com.mogo.eagle.core.function.api.base.IMoGoFunctionServerProvider
@@ -51,4 +52,10 @@ interface IMoGoFuncBizProvider : IMoGoFunctionServerProvider {
*/
fun closeCameraLive()
/*----------------------------------------全览模式----------------------------------------*/
fun fetchInfStructures()
fun getAllV2XEvents()
fun initOverViewDb(context: Context)
}

View File

@@ -0,0 +1,16 @@
package com.mogo.eagle.core.function.api.v2x
import com.mogo.eagle.core.data.map.Infrastructure
import com.mogo.eagle.core.data.v2x.V2XEvent
interface IFuncBizProvider {
/**
* 查询衡阳所有的摄像头数据
*/
fun onInfStructures(map: HashMap<String, ArrayList<Infrastructure>>?) {}
/**
* 根据lineId获取整条道路的V2X事件
*/
fun onV2XEvents(v2xEvents: List<V2XEvent>?) {}
}

View File

@@ -0,0 +1,33 @@
package com.mogo.eagle.core.function.call.biz
import androidx.annotation.MainThread
import com.mogo.eagle.core.data.map.Infrastructure
import com.mogo.eagle.core.data.v2x.V2XEvent
import com.mogo.eagle.core.function.api.v2x.IFuncBizProvider
import com.mogo.eagle.core.function.call.base.CallerBase
object CallerFuncBizListenerManager: CallerBase<IFuncBizProvider>() {
private var map: HashMap<String, java.util.ArrayList<Infrastructure>>? = null
override fun doSomeAfterAddListener(tag: String, listener: IFuncBizProvider) {
listener.onInfStructures(map)
}
@MainThread
fun invokeInfStructures(map: HashMap<String, java.util.ArrayList<Infrastructure>>) {
this.map = map
M_LISTENERS.forEach {
val listener = it.value
listener.onInfStructures(map)
}
}
@MainThread
fun invokeV2XEvents(v2xEvents: List<V2XEvent>?) {
M_LISTENERS.forEach {
val listener = it.value
listener.onV2XEvents(v2xEvents)
}
}
}

View File

@@ -20,9 +20,9 @@ object CallerSmpManager : CallerBase<Any>() {
get() = ARouter.getInstance().build(MoGoFragmentPaths.PATH_FRAGMENT_SMP)
.navigation() as IMogoSmallMapProvider
private val mogoOverViewMapProvider: IMogoSmallMapProvider
get() = ARouter.getInstance().build(MoGoFragmentPaths.PATH_FRAGMENT_OVERVIEW)
.navigation() as IMogoSmallMapProvider
// private val mogoOverViewMapProvider: IMogoSmallMapProvider
// get() = ARouter.getInstance().build(MoGoFragmentPaths.PATH_FRAGMENT_OVERVIEW)
// .navigation() as IMogoSmallMapProvider
private val v2xProvider: IV2XEventProvider
get() = ARouter.getInstance().build(MogoServicePaths.PATH_V2X_MODULE)
@@ -65,22 +65,22 @@ object CallerSmpManager : CallerBase<Any>() {
if (Thread.currentThread() !== Looper.getMainLooper().thread) {
UiThreadHandler.post {
v2xProvider.queryWholeRoadEvents()
mogoOverViewMapProvider.startQueryV2XEvents()
// mogoOverViewMapProvider.startQueryV2XEvents()
}
} else {
v2xProvider.queryWholeRoadEvents()
mogoOverViewMapProvider.startQueryV2XEvents()
// mogoOverViewMapProvider.startQueryV2XEvents()
}
}
@JvmStatic
fun clearV2XMarkers() {
if (Thread.currentThread() !== Looper.getMainLooper().thread) {
UiThreadHandler.post {
mogoOverViewMapProvider.clearV2XMarkers()
}
} else {
mogoOverViewMapProvider.clearV2XMarkers()
}
// if (Thread.currentThread() !== Looper.getMainLooper().thread) {
// UiThreadHandler.post {
// mogoOverViewMapProvider.clearV2XMarkers()
// }
// } else {
// mogoOverViewMapProvider.clearV2XMarkers()
// }
}
}