diff --git a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/FuncBizProvider.kt b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/FuncBizProvider.kt index 4d64f929f1..1d59a9f9b0 100644 --- a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/FuncBizProvider.kt +++ b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/FuncBizProvider.kt @@ -14,7 +14,7 @@ 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.busstation.BusStationEventManager +import com.mogo.eagle.function.biz.v2x.busstation.PassBusStationEventManager import com.mogo.eagle.function.biz.v2x.obu.V2xObuEventManager import com.mogo.eagle.function.biz.v2x.overview.OverViewDataManager import com.mogo.eagle.function.biz.v2x.overview.db.OverviewDb @@ -55,7 +55,7 @@ class FuncBizProvider : IMoGoFuncBizProvider { V2NIdentifyDrawer.init() // RedLightWarningManager.INSTANCE.listenTrafficLight() V2XEventAnalyticsManager.init() - BusStationEventManager.init() + PassBusStationEventManager.init() } override fun feedBackNoticeTraffic(infoId: String, sn: String, accept: Int) { @@ -128,7 +128,7 @@ class FuncBizProvider : IMoGoFuncBizProvider { dispatchAutoPilotManager.release() cronTaskManager.release() - BusStationEventManager.unInit() + PassBusStationEventManager.unInit() VipCarManager.INSTANCE.destroy() if(!(AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode) diff --git a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/busstation/BusStationEventManager.kt b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/busstation/PassBusStationEventManager.kt similarity index 98% rename from core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/busstation/BusStationEventManager.kt rename to core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/busstation/PassBusStationEventManager.kt index d2503a0d34..3a658b1456 100644 --- a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/busstation/BusStationEventManager.kt +++ b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/busstation/PassBusStationEventManager.kt @@ -32,12 +32,12 @@ import java.util.concurrent.atomic.AtomicBoolean /** * 计算通过公交站点 管理类 */ -object BusStationEventManager : IMoGoChassisLocationWGS84Listener { +object PassBusStationEventManager : IMoGoChassisLocationWGS84Listener { - const val TAG = "BusStationEventManager" + const val TAG = "PassBusStationEventManager" private val mCoroutineScope: CoroutineScope = - CoroutineScope(SupervisorJob() + Dispatchers.Default) + CoroutineScope(SupervisorJob() + Dispatchers.IO) // 距离当前车位置 X 米远的点集合(用来查询根据点查询roadId, 然后用roadId查询路上的公交站点) private val farthestLocationList = ArrayList() diff --git a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/v2n/pnc/V2NIdentifyDrawer.kt b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/v2n/pnc/V2NIdentifyDrawer.kt index 146c4d6bb3..c4c3ac1eee 100644 --- a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/v2n/pnc/V2NIdentifyDrawer.kt +++ b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/v2n/pnc/V2NIdentifyDrawer.kt @@ -3,6 +3,7 @@ package com.mogo.eagle.function.biz.v2x.v2n.pnc import android.os.Handler import android.os.HandlerThread import android.os.Message +import android.text.TextUtils import android.util.Log import androidx.core.util.Pair import com.mogo.eagle.core.data.config.FunctionBuildConfig @@ -32,13 +33,17 @@ import com.mogo.eagle.core.function.call.hmi.CallerRoadV2NEventWindowListenerMan import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager.saveMsgBox import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils -import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger +import com.mogo.eagle.core.utilcode.mogo.logger.Logger import com.mogo.eagle.core.utilcode.util.CoordinateTransform import com.mogo.eagle.core.utilcode.util.CoordinateUtils import com.mogo.eagle.core.utilcode.util.DrivingDirectionUtils +import com.mogo.eagle.core.utilcode.util.GsonUtils import com.mogo.eagle.function.biz.v2x.V2XBizTrace import com.mogo.eagle.function.biz.v2x.v2n.scenario.scene.airoad.AiRoadMarker import com.mogo.eagle.function.biz.v2x.v2n.scenario.scene.airoad.AiRoadMarker.Marker +import com.mogo.eagle.function.biz.v2x.v2n.utils.EventDismissBean +import com.mogo.eagle.function.biz.v2x.v2n.utils.EventDismissManager +import com.mogo.eagle.function.biz.v2x.v2n.utils.IEventDismissListener import com.mogo.eagle.function.biz.v2x.v2n.utils.V2NUtils import com.mogo.eagle.function.biz.v2x.v2n.utils.V2XEventAnalyticsManager import com.mogo.map.entities.Lane @@ -53,13 +58,14 @@ import java.util.concurrent.TimeUnit.SECONDS /** * V2N上车相关事件绘制 */ -internal object V2NIdentifyDrawer { +internal object V2NIdentifyDrawer: IEventDismissListener { private const val TAG = "V2NIdentifyDataSubscriber" private const val MSG_WHAT_DRAW_SHIGONE = 0x1010 // 道路施工 private const val MSG_WHAT_DRAW_SHIGU = 0x1011 // 交通事故 private const val MSG_WHAT_DRAW_YONGDU = 0x1012 // 交通拥堵 + private const val MSG_WHAT_DRAW_OTHER_RETROGRADE_VEHICLE = 0x1013 // 他车倒车/逆行 private val callback = Handler.Callback { msg -> if (msg.what == MSG_WHAT_DRAW_SHIGONE || msg.what == MSG_WHAT_DRAW_SHIGU) { @@ -320,6 +326,56 @@ internal object V2NIdentifyDrawer { } }.receive() } + } else if (msg.what == MSG_WHAT_DRAW_OTHER_RETROGRADE_VEHICLE) { + val event = msg.obj as? MessagePad.Event + if (event == null) { + Logger.i(TAG, "other_retrograde_vehicle --> event == null") + V2XBizTrace.onAck(TAG, mapOf("other_retrograde_vehicle" to "event == null"), true) + return@Callback true + } + val eventLocation = when (event.gnssType) { + 0 -> CoordinateTransform.GCJ02ToWGS84(event.longitude, event.latitude) + else -> arrayOf(event.longitude, event.latitude) + } + val carLocation = CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84() + val distance = CoordinateUtils.calculateLineDistance(carLocation.longitude, carLocation.latitude, eventLocation[0], eventLocation[1]) + if (distance > 150) { + Logger.i(TAG, "other_retrograde_vehicle --> distance > 150") + V2XBizTrace.onAck(TAG, mapOf("other_retrograde_vehicle" to "distance > 150"), true) + return@Callback true + } + val isDriver = AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode) + + val newEventId = "other_retrograde_vehicle_${event.eventId}_${event.timestamp}_${event.longitude}_${event.latitude}" + val cameraIp = if(TextUtils.isEmpty(event.exts)) + "" + else + (GsonUtils.fromJson(event.exts, Map::class.java)["cameraIp"])?:"" + // 弹事件框 + CallerRoadV2NEventWindowListenerManager.showLiveVideo( + newEventId, + event.timestamp, + EventTypeEnumNew.getUpdateIconRes(EventTypeEnumNew.TYPE_SOCKET_ROAD_OTHER_RETROGRADE_VEHICLE.poiType), + String.format(EventTypeEnumNew.getAlarmContent(EventTypeEnumNew.TYPE_SOCKET_ROAD_OTHER_RETROGRADE_VEHICLE.poiType), distance), + isDriver, + cameraIp.toString(), + event.longitude, + event.latitude) + // 高精地图绘制-添加 + //TODO + EventDismissManager.addEvent( + TAG, + EventDismissBean( + newEventId, + event.longitude, + event.latitude, + 150, + 10, + -1, + event.targetIdsList.joinToString(separator = ",") + ) + ) + } true } @@ -474,6 +530,14 @@ internal object V2NIdentifyDrawer { } } + private fun drawOtherRetrogradeVehicle(event: MessagePad.Event) { + Log.d("V2NIdentifyDrawer", "---drawOtherRetrogradeVehicle --- :${event.toString()}, [${FunctionBuildConfig.v2nMainSwitch}, ${FunctionBuildConfig.isNewV2NData}]") + if (V2NCarTypeCheck.verifyCarType() && FunctionBuildConfig.v2nMainSwitch && FunctionBuildConfig.isNewV2NData) { + handler.removeMessages(MSG_WHAT_DRAW_OTHER_RETROGRADE_VEHICLE) + handler.sendMessage(Message.obtain(handler, MSG_WHAT_DRAW_OTHER_RETROGRADE_VEHICLE, event)) + } + } + private val nioEventListener = object : IMoGoV2nNioEventListener { override fun onV2nNioCongestionEvent(congestion: MessagePad.V2nCongestion) { super.onV2nNioCongestionEvent(congestion) @@ -489,18 +553,38 @@ internal object V2NIdentifyDrawer { override fun onV2nNioOtherRetrogradeEvent(event: MessagePad.Event) { super.onV2nNioOtherRetrogradeEvent(event) - CallerLogger.i(TAG, "onV2nNioOtherRetrogradeEvent --> ${event.toString()}") - + Logger.i(TAG, "onV2nNioOtherRetrogradeEvent --> ${event.toString()}") + drawOtherRetrogradeVehicle(event) } } fun init() { CallerAutopilotIdentifyListenerManager.addListener(TAG, listener) CallerV2nNioEventListenerManager.addListener(TAG, nioEventListener) + EventDismissManager.addDismissListener(TAG, this) } fun unInit() { CallerAutopilotIdentifyListenerManager.removeListener(TAG) CallerV2nNioEventListenerManager.removeListener(TAG) + EventDismissManager.removeDismissListener(TAG) + } + + override fun onEventDismissByDistance(event: EventDismissBean) { + Logger.i(TAG, "onEventDismissByDistance --> ${event.toString()}") + if (event.eventId.startsWith("other_retrograde_vehicle")) { + V2XBizTrace.onAck(TAG, mapOf("other_retrograde_vehicle" to "onEventDismissByDistance"), true) + val targetIds = event.exts.split(",") + //TODO 高精地图绘制 移除 + } + } + + override fun onEventDismissByExpired(event: EventDismissBean) { + Logger.i(TAG, "onEventDismissByExpired --> ${event.toString()}") + if (event.eventId.startsWith("other_retrograde_vehicle")) { + V2XBizTrace.onAck(TAG, mapOf("other_retrograde_vehicle" to "onEventDismissByExpired"), true) + val targetIds = event.exts.split(",") + //TODO 高精地图绘制 移除 + } } } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/v2n/utils/EventDismissManager.kt b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/v2n/utils/EventDismissManager.kt new file mode 100644 index 0000000000..3e70a229cd --- /dev/null +++ b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/v2n/utils/EventDismissManager.kt @@ -0,0 +1,145 @@ +package com.mogo.eagle.function.biz.v2x.v2n.utils + +import android.os.Handler +import android.os.HandlerThread +import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager +import com.mogo.eagle.core.utilcode.mogo.logger.Logger +import com.mogo.eagle.core.utilcode.util.CoordinateUtils +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.atomic.AtomicBoolean + +object EventDismissManager { + + private val TAG = "EventDismissManager" + + private val M_LISTENERS: ConcurrentHashMap = ConcurrentHashMap() + private val observableEventList = ConcurrentHashMap() + private val isStart = AtomicBoolean(false) + + private val handler by lazy { + val thread = HandlerThread("road_v2n_event_dismiss_manager") + thread.start() + Handler(thread.looper) + } + + private val checkRunnable = object : Runnable { + override fun run() { + Logger.d( + TAG, + "checkRunnable --> run" + ) + isStart.set(true) + synchronized(observableEventList) { + if (observableEventList.isNotEmpty()) { + val carLocation = + CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84() + observableEventList.forEach { eventList -> + val tag = eventList.key.split("_")[0] + val event = eventList.value + val distance = CoordinateUtils.calculateLineDistance( + carLocation.longitude, + carLocation.latitude, + event.lon, + event.lat + ) + val isExpired = + event.lastExpiredTime != -1L && System.currentTimeMillis() >= event.lastExpiredTime + if (distance >= event.dismissDistance) { + M_LISTENERS.forEach { + if (tag == it.key) { + it.value.onEventDismissByDistance(event) + } + } + observableEventList.remove(eventList.key) + Logger.d( + TAG, + "removeEvent --> byDistance, event=${event.toString()}" + ) + } else if (isExpired) { + M_LISTENERS.forEach { + if (tag == it.key) { + it.value.onEventDismissByExpired(event) + } + } + observableEventList.remove(eventList.key) + Logger.d( + TAG, + "removeEvent --> byExpired, event=${event.toString()}" + ) + } + } + } + if (observableEventList.isNotEmpty()) { + handler.postDelayed(this, 1000L) + isStart.set(true) + Logger.d( + TAG, + "checkRunnable --> end, schedule delay" + ) + } else { + isStart.set(false) + Logger.d( + TAG, + "checkRunnable --> end, not schedule delay" + ) + } + } + } + } + + + fun addDismissListener( + tag: String, listener: IEventDismissListener + ) { + if (M_LISTENERS.containsKey(tag)) { + return + } + M_LISTENERS[tag] = listener + } + + fun removeDismissListener(tag: String) { + if (!M_LISTENERS.containsKey(tag)) { + return + } + M_LISTENERS.remove(tag) + } + + fun addEvent(tag: String, event: EventDismissBean) { + Logger.d( + TAG, + "addEvent --> ${event.toString()}" + ) + val key = "${tag}_${event.eventId}" + if (observableEventList.containsKey(key)) { + observableEventList[key]?.lastExpiredTime = + System.currentTimeMillis() + event.expiredSeconds * 1000L + } else { + observableEventList[key] = event + observableEventList[key]?.lastExpiredTime = + System.currentTimeMillis() + event.expiredSeconds * 1000L + } + if (!isStart.get()) { + handler.removeCallbacks(checkRunnable) + handler.post(checkRunnable) + Logger.d( + TAG, + "addEvent --> postRunnable" + ) + } + } +} + +interface IEventDismissListener { + fun onEventDismissByDistance(event: EventDismissBean) + fun onEventDismissByExpired(event: EventDismissBean) +} + +data class EventDismissBean( + val eventId: String, //事件唯一 ID + val lon: Double, //事件经度 + val lat: Double, //事件维度 + val dismissDistance: Int, // 消散围栏距离 + val expiredSeconds: Int, // 事件最长展示事件(秒) + var lastExpiredTime: Long = -1L, // 最后一次增加事件的时间戳(用来计算超时) + var exts: String = "" // 各类型事件附件的信息,以便回调后判断使用 +) \ No newline at end of file