From a95c45869b7a8a121f5b6b6072bd92948737b385 Mon Sep 17 00:00:00 2001 From: EmArrow Date: Mon, 4 Nov 2024 11:46:11 +0800 Subject: [PATCH] =?UTF-8?q?[6.7.4]=20=E4=B8=8A=E6=B5=B7=E6=BC=94=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../roadcross/RoadCrossCameraManager.kt | 160 +++++++++++++++--- .../core/function/view/RoadCrossRoamView.kt | 27 +-- .../core/data/deva/chain/ChainConstant.kt | 1 + .../api/map/road/IMoGoMapRoadListener.kt | 3 + .../call/map/CallerMapRoadListenerManager.kt | 24 ++- 5 files changed, 167 insertions(+), 48 deletions(-) diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/roadcross/RoadCrossCameraManager.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/roadcross/RoadCrossCameraManager.kt index c72c110fd8..eec14c4f54 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/roadcross/RoadCrossCameraManager.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/roadcross/RoadCrossCameraManager.kt @@ -2,7 +2,6 @@ package com.mogo.eagle.core.function.business.roadcross import android.annotation.SuppressLint import android.content.Context -import android.graphics.BitmapFactory import android.os.Handler import android.os.Looper import android.os.Message @@ -21,7 +20,9 @@ import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager import com.mogo.eagle.core.function.map.R 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.mogo.logger.scene.SceneConstant.Companion.M_MAP +import com.mogo.eagle.core.utilcode.util.CoordinateUtils import com.mogo.eagle.core.utilcode.util.ThreadUtils import com.mogo.eagle.core.utilcode.util.ToastUtils import com.mogo.map.overlay.core.Level @@ -38,6 +39,8 @@ class RoadCrossCameraManager : IMoGoMapRoadListener, IGaoDeMapLocationListener { private const val TAG = "RoadCrossCameraManager" private const val REQUEST_CAMERA_MSG = 0 private const val REMOVE_MARKER_MSG = 1 + private const val REQUEST_CAL_ROAD_DISTANCE = 2 + private const val REQUEST_CAL_ROAD_DELAY_TIME = 1000L private const val REQUEST_CAMERA_DELAY_TIME = 20000L private const val REMOVE_MARKER_DELAY_TIME = 10000L @@ -64,6 +67,11 @@ class RoadCrossCameraManager : IMoGoMapRoadListener, IGaoDeMapLocationListener { getAllRoadCross() } + REQUEST_CAL_ROAD_DISTANCE -> { + CallerLogger.d("$M_MAP$TAG", "cal roam road distance") + calRoamRoadDistance() + } + REMOVE_MARKER_MSG -> { CallerLogger.d("$M_MAP$TAG", "remove marker") overlayManager?.removeAllPointsInOwner(TAG) @@ -208,44 +216,60 @@ class RoadCrossCameraManager : IMoGoMapRoadListener, IGaoDeMapLocationListener { } } - fun hasCrossCamera(): Boolean { - if(CallerMapUIServiceManager.getCityCode() == "010"){ + private fun hasCrossCamera(camera: ((Boolean, CameraDeviceInfo?) -> Unit)) { + if (CallerMapUIServiceManager.getCityCode() == "010") { roadCrossTrace( TAG, mapOf("errorMsg" to "cityCode限制 - 北京无路口设备") ) - return false + camera.invoke(false, null) } val roadCrossEnd = CallerMapRoadListenerManager.getCrossEndInfo() - if(roadCrossEnd == null){ + if (roadCrossEnd == null) { roadCrossTrace( TAG, mapOf("errorMsg" to "hasCrossCamera - 未获取到地图crossEnd数据") ) - return false + camera.invoke(false, null) } if (roadCrossCameraList == null) { roadCrossTrace( TAG, mapOf("errorMsg" to "hasCrossCamera - 未获取到全市路口设备信息") ) - return false + camera.invoke(false, null) } - - roadCrossCameraList?.forEach { - val result = (!it.roadUniqueId.isNullOrEmpty() + var result = false + roadCrossCameraList?.forEach { it -> + result = (!it.roadUniqueId.isNullOrEmpty() && it.roadUniqueId == roadCrossEnd) - if(result){ + if (result) { roadCrossTrace( - TAG, mapOf("errorMsg" to "hasCrossCamera - 遍历匹配路口数据命中 - $roadCrossEnd") + TAG, + mapOf("errorMsg" to "hasCrossCamera - 遍历匹配路口数据命中 - $roadCrossEnd") ) - return true + val loc = CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84() + val cameraInfo = it.deviceInfoList.minByOrNull { info -> + CoordinateUtils.calculateLineDistance( + info.lon, + info.lat, + loc.longitude, + loc.latitude + ) + } + if (cameraInfo != null) { + camera.invoke(true, cameraInfo) + return@forEach + } } } - roadCrossTrace( - TAG, mapOf("errorMsg" to "hasCrossCamera - 均不匹配上述条件") - ) - return false + if(!result){ + roadCrossTrace( + TAG, mapOf("errorMsg" to "hasCrossCamera - 未匹配到路口信息 - $roadCrossEnd") + ) + camera.invoke(false, null) + } + } @SuppressLint("NewApi") @@ -270,20 +294,102 @@ class RoadCrossCameraManager : IMoGoMapRoadListener, IGaoDeMapLocationListener { override fun onRoadChange(cross: Boolean, roadCross: RoadCross?) { super.onRoadChange(cross, roadCross) // 出路口 + if (!cross) { + handleRoadCrossRoam(false) + handleCameraMarker() + CallerLogger.d("$M_MAP$TAG", "经过路口,释放控制") + } else { + handleRoadCrossRoam(true) + } + } + + private var cameraDis: CameraDeviceInfo? = null + private fun handleRoadCrossRoam(isCross: Boolean) { + CallerLogger.d("$M_MAP$TAG", "handleRoadCrossRoam , isCross:$isCross") + if (isCross) { + //停止handler,remove + cameraDis = null + handler.removeMessages(REQUEST_CAL_ROAD_DISTANCE) + CallerMapRoadListenerManager.invokeCrossDevice(false) + CallerLogger.d("$M_MAP$TAG", "emArrow 已过路口,清除判断") + } else { + //开启handler计算,每隔一秒 + handler.sendEmptyMessageDelayed(REQUEST_CAL_ROAD_DISTANCE, REQUEST_CAL_ROAD_DELAY_TIME) + CallerLogger.d("$M_MAP$TAG", "emArrow 路口内,开始计算") + } + } + + private fun calRoamRoadDistance() { + //计算前方路口与marker最小距离 < 200 ,触发业务,回调 + //到达触发距离,可一直发,如果业务方已经展示业务,invoke取消handler + handler.removeMessages(REQUEST_CAL_ROAD_DISTANCE) + if (cameraDis != null) { + calDisInRange { b, dis -> + if(b){ + CallerLogger.d("$M_MAP$TAG", "emArrow 距离内,多次计算,命中") + CallerMapRoadListenerManager.invokeCrossDevice(true) + }else{ + //没有命中距离,继续计算 + handler.sendEmptyMessageDelayed(REQUEST_CAL_ROAD_DISTANCE, REQUEST_CAL_ROAD_DELAY_TIME) + CallerLogger.d("$M_MAP$TAG", "emArrow 继续计算, dis:$dis") + } + } + return + } + + hasCrossCamera { hasCamera, cameraDeviceInfo -> + if (hasCamera && cameraDeviceInfo != null) { + CallerLogger.d("$M_MAP$TAG", "emArrow 首次命中设备") + cameraDis = cameraDeviceInfo + calDisInRange { b, dis -> + if(b){ + CallerLogger.d("$M_MAP$TAG", "emArrow 距离内,首次即命中") + CallerMapRoadListenerManager.invokeCrossDevice(true) + }else{ + //没有命中距离,继续计算 + handler.sendEmptyMessageDelayed(REQUEST_CAL_ROAD_DISTANCE, REQUEST_CAL_ROAD_DELAY_TIME) + CallerLogger.d("$M_MAP$TAG", "emArrow 继续计算, 首次 dis:$dis") + } + } + }else{ + //没有命中设备,继续计算 + handler.sendEmptyMessageDelayed(REQUEST_CAL_ROAD_DISTANCE, REQUEST_CAL_ROAD_DELAY_TIME) + CallerLogger.d("$M_MAP$TAG", "emArrow 没有命中设备${cameraDeviceInfo?:"空"}/路口${CallerMapRoadListenerManager.getCrossEndInfo()},继续计算") + } + } + } + + private fun calDisInRange(range: ((Boolean, Float) -> Unit)) { + if (cameraDis == null) { + range.invoke(false, 0f) + return + } + val loc = CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84() + val dis = CoordinateUtils.calculateLineDistance( + cameraDis!!.lon, + cameraDis!!.lat, + loc.longitude, + loc.latitude + ) + if (dis < 220 && dis >= 5) { + range.invoke(true, dis) + }else{ + range.invoke(false,dis) + } + } + + private fun handleCameraMarker() { if (!isCameraRequest) { CallerLogger.d("$M_MAP$TAG", "未触发路口获取marker") return } - if (!cross) { - // 停止请求摄像头数据 - ndeRoadCameraNetWorkModel.cancelRequest("roadCross") - // 清除marker - CallerLogger.d("$M_MAP$TAG", "remove marker handler") - handler.sendEmptyMessageDelayed(REMOVE_MARKER_MSG, REMOVE_MARKER_DELAY_TIME) - // 释放控制 - isCameraRequest = false - CallerLogger.d("$M_MAP$TAG", "经过路口,释放控制") - } + // 停止请求摄像头数据 + ndeRoadCameraNetWorkModel.cancelRequest("roadCross") + // 清除marker + CallerLogger.d("$M_MAP$TAG", "handleCameraMarker remove marker handler") + handler.sendEmptyMessageDelayed(REMOVE_MARKER_MSG, REMOVE_MARKER_DELAY_TIME) + // 释放控制 + isCameraRequest = false } private fun traceError(msg: String) { diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/RoadCrossRoamView.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/RoadCrossRoamView.kt index 0ab1959506..c8179001ee 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/RoadCrossRoamView.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/RoadCrossRoamView.kt @@ -188,18 +188,9 @@ class RoadCrossRoamView @JvmOverloads constructor( } } - override fun onStopLineInfo(info: StopLine) { - super.onStopLineInfo(info) - val cross = CallerMapRoadListenerManager.getCrossEndInfo() - if (info.distance == 0.0 || info.distance > 200) { - if (cross != null && cross != "0") { - CallerLogger.d("$M_MAP$TAG", "未触发,路口ID:$cross , 距离超出:${info.distance}") - } - return - } - CallerLogger.d("$M_MAP$TAG", "命中 before:$showState") - showState = info.distance in 100.0..200.0 - CallerLogger.d("$M_MAP$TAG", "命中 after:$showState,路口ID:$cross , dis:${info.distance}") + override fun onCrossDevice(trigger: Boolean) { + super.onCrossDevice(trigger) + showState = trigger } private fun attachView() { @@ -234,17 +225,17 @@ class RoadCrossRoamView @JvmOverloads constructor( CallerLogger.d("$M_MAP$TAG", "未触发,路口ID:$cross") return } - if (!instance.hasCrossCamera()) { - CallerLogger.d("$M_MAP$TAG", "没有路侧设备,不做处理") - return - } isShow = true //播放语音 val dis = CallerMapRoadListenerManager.getStopLineDistance()?.toInt() ?: 0 if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) { - var disStr = "前方即将通过路口,${SkinResources.getInstance().getString(R.string.operation_platform_name)}为您提供路口全息影像,助力出行" + var disStr = "前方即将通过路口,${ + SkinResources.getInstance().getString(R.string.operation_platform_name) + }为您提供路口全息影像,助力出行" if (dis >= 80) { - disStr = "前方${dis}米将通过路口,${SkinResources.getInstance().getString(R.string.operation_platform_name)}为您提供路口全息影像,助力出行" + disStr = "前方${dis}米将通过路口,${ + SkinResources.getInstance().getString(R.string.operation_platform_name) + }为您提供路口全息影像,助力出行" } AIAssist.getInstance(context).speakTTSVoice(disStr) } diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/deva/chain/ChainConstant.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/deva/chain/ChainConstant.kt index ceb4614e52..60714df309 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/deva/chain/ChainConstant.kt +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/deva/chain/ChainConstant.kt @@ -116,6 +116,7 @@ class ChainConstant { const val CHAIN_CODE_HD_MAP_CALL = "CHAIN_CODE_HD_MAP_CALL" const val CHAIN_CODE_HD_MAP_ROAD_CROSS = "CHAIN_CODE_HD_MAP_ROAD_CROSS" const val CHAIN_CODE_HD_MAP_ROAD_LIVE = "CHAIN_CODE_HD_MAP_ROAD_LIVE" + const val CHAIN_CODE_HD_MAP_ROAD_DEVICE_TRIGGER = "CHAIN_CODE_HD_MAP_ROAD_DEVICE_TRIGGER" const val CHAIN_CODE_HD_MAP_ICON_SET = "CHAIN_CODE_HD_MAP_ICON_SET" const val CHAIN_CODE_HMI_ACTIONS = "CHAIN_CODE_HMI_ACTIONS" const val CHAIN_CODE_CERT_REQUEST = "CHAIN_CODE_CERT_REQUEST" diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/map/road/IMoGoMapRoadListener.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/map/road/IMoGoMapRoadListener.kt index 43f8394d74..ba0f36b3a5 100644 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/map/road/IMoGoMapRoadListener.kt +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/map/road/IMoGoMapRoadListener.kt @@ -19,4 +19,7 @@ interface IMoGoMapRoadListener { fun onRoadCrossClick() {} + fun onCrossDevice(trigger:Boolean){} + + } \ No newline at end of file diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerMapRoadListenerManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerMapRoadListenerManager.kt index 90ef5abbfb..c27ebaa86f 100644 --- a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerMapRoadListenerManager.kt +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerMapRoadListenerManager.kt @@ -15,11 +15,16 @@ object CallerMapRoadListenerManager : CallerBase() { private var mRoadId: String? = null private var mStopLine: StopLine? = null + @Volatile private var mRoadChange = false + @Volatile private var mRoadCross: RoadCross? = null + @Volatile + private var mTrigger = false + private var mCross: Int by Delegates.observable(-1) { _, oldValue, newValue -> if (oldValue != newValue) { CallerLogger.d("$M_MAP onRoadChange observable", newValue) @@ -40,9 +45,9 @@ object CallerMapRoadListenerManager : CallerBase() { mStopLine?.let { listener.onStopLineInfo(it) } - if (mCross != -1 && mRoadCross != null) { - listener.onRoadChange(mRoadChange, mRoadCross) - } + // 启动默认false + listener.onRoadChange(mRoadChange, mRoadCross) + listener.onCrossDevice(mTrigger) } fun invokeListenersOnRoadIdGet(roadId: String) { @@ -116,4 +121,17 @@ object CallerMapRoadListenerManager : CallerBase() { entry.value.onCrossLiveInfo(info) } } + + @ChainLog( + linkChainLog = ChainConstant.CHAIN_TYPE_STATUS, + linkCode = ChainConstant.CHAIN_SOURCE_MAP, + nodeAliasCode = ChainConstant.CHAIN_CODE_HD_MAP_ROAD_DEVICE_TRIGGER, + paramIndexes = [0] + ) + fun invokeCrossDevice(trigger:Boolean){ + mTrigger = trigger + M_LISTENERS.forEach { entry -> + entry.value.onCrossDevice(trigger) + } + } } \ No newline at end of file