From db0e9a9349589c165b477c69d8d5998c245336e9 Mon Sep 17 00:00:00 2001 From: aibingbing Date: Mon, 1 Jul 2024 19:37:24 +0800 Subject: [PATCH] =?UTF-8?q?[6.5.0]=20feat:=20=E9=80=9A=E8=BF=87=E5=85=AC?= =?UTF-8?q?=E4=BA=A4=E7=AB=99=E7=82=B9=E8=AE=A1=E7=AE=97=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../v2x/busstation/BusStationEventManager.kt | 228 +++++++++++++++--- .../hmi/ui/v2n/RoadV2NEventWindowView.kt | 27 --- .../java/com/mogo/map/entities/BusStation.kt | 25 +- .../main/java/com/mogo/map/MapDataWrapper.kt | 2 +- 4 files changed, 216 insertions(+), 66 deletions(-) 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/BusStationEventManager.kt index 1c978f29d5..ea937db60e 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/BusStationEventManager.kt @@ -1,20 +1,32 @@ package com.mogo.eagle.function.biz.v2x.busstation -import android.util.Pair +import android.os.Handler +import android.os.HandlerThread +import com.mogo.commons.debug.DebugConfig +import com.mogo.eagle.core.data.config.FunctionBuildConfig +import com.mogo.eagle.core.data.enums.EventTypeEnumNew import com.mogo.eagle.core.data.map.MogoLocation import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationWGS84Listener import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager +import com.mogo.eagle.core.function.call.hmi.CallerRoadV2NEventWindowListenerManager +import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager +import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils import com.mogo.eagle.core.utilcode.mogo.logger.Logger +import com.mogo.eagle.core.utilcode.util.CoordinateUtils +import com.mogo.eagle.core.utilcode.util.DrivingDirectionUtils import com.mogo.map.MogoData import com.mogo.map.entities.BusStation +import com.mogo.map.overlay.core.Level +import com.mogo.map.overlay.point.Point import com.zhidaoauto.map.data.point.LonLatPoint import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel import kotlinx.coroutines.launch +import java.util.LinkedList +import java.util.UUID import java.util.concurrent.atomic.AtomicBoolean -import kotlin.math.sin /** * 计算通过公交站点 管理类 @@ -23,19 +35,154 @@ object BusStationEventManager : IMoGoChassisLocationWGS84Listener { const val TAG = "BusStationEventManager" - private val mScope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default) - private val isCalculateNearByStation = AtomicBoolean(false) - private val farthestLocationList = ArrayList() - private val busStationListNearBy = LinkedHashMap() + private val mCoroutineScope: CoroutineScope = + CoroutineScope(SupervisorJob() + Dispatchers.Default) + // 距离当前车位置 X 米远的点集合(用来查询根据点查询roadId, 然后用roadId查询路上的公交站点) + private val farthestLocationList = ArrayList() + + // 是否在计算附近的公交站点集合 + private val isCalculateNearByStation = AtomicBoolean(false) + + // 查询出来的符合条件的公交站点集合 + private val busStationNearByQueue = LinkedList>() + + // 需要提醒的公交站点 + private val busStationListNeedNotified = HashMap() + + private val isDriverScreen by lazy { + AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode) + } + + private val checkDistanceRunnable = object : Runnable { + override fun run() { + try { + synchronized(busStationNearByQueue) { + if (busStationNearByQueue.isNotEmpty()) { + val list = busStationNearByQueue.pollLast() + val currentLocation = + CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84() + list.forEach { + if (!busStationListNeedNotified.containsKey(it.getBusStationId())) { + val distance = CoordinateUtils.calculateLineDistance( + currentLocation.longitude, + currentLocation.latitude, + it.getBusStationPoint().longitude, + it.getBusStationPoint().latitude, + ).toInt() + val angle = DrivingDirectionUtils.getDegreeOfCar2Poi( + currentLocation.longitude, + currentLocation.latitude, + it.getBusStationPoint().longitude, + it.getBusStationPoint().latitude, + currentLocation.heading.toInt() + ) + if (distance <= 150 && angle < 90) { + it.notifyDistance = distance + busStationListNeedNotified[it.getBusStationId()] = it + Logger.d( + TAG, "addNeedNotifiedBusStation --> ${it.toString()}" + ) + } + } + } + } + } + + // 对已经展示过的做移除 消散操作 + if (busStationListNeedNotified.isNotEmpty()) { + val currentLocation = + CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84() + busStationListNeedNotified.values.forEach { + val distance = CoordinateUtils.calculateLineDistance( + currentLocation.longitude, + currentLocation.latitude, + it.getBusStationPoint().longitude, + it.getBusStationPoint().latitude, + ).toInt() + val angle = DrivingDirectionUtils.getDegreeOfCar2Poi( + currentLocation.longitude, + currentLocation.latitude, + it.getBusStationPoint().longitude, + it.getBusStationPoint().latitude, + currentLocation.heading.toInt() + ) + if (distance<=5 && angle >= 90) { + CallerRoadV2NEventWindowListenerManager.dismiss(it.getBusStationId()) + busStationListNeedNotified.remove(it.getBusStationId()) + Logger.d( + TAG, + "removeNeedNotifiedBusStation --> ${it.toString()}" + ) + } + } + } + + // 开始提醒 + if (busStationListNeedNotified.isNotEmpty()) { + handler.removeCallbacks(notificationCheckRunnable) + handler.post(notificationCheckRunnable) + } + } catch (e: Exception) { + e.printStackTrace() + } finally { + handler?.postDelayed(this, 1000L) + } + } + } + + private val notificationCheckRunnable = object : Runnable { + override fun run() { + if (busStationListNeedNotified.isNotEmpty()) { + val list = busStationListNeedNotified.values.toList() + .filter { it.notifyTime <= 0 && it.notifyDistance > 0 } + .sortedBy { it.notifyDistance } + if (list.isNotEmpty()) { + list.first().also { + //TODO 调整调用方式 + it.notifyTime = System.currentTimeMillis() + CallerRoadV2NEventWindowListenerManager.show( + it.getBusStationId(), + it.notifyTime, + EventTypeEnumNew.getUpdateIconRes(""), + "前方${it.notifyDistance}米有公交站,蘑菇提醒您小心右侧行人及来车", + isDriverScreen, + "192.168.1.1", + 0.0, 0.0 + ) + Logger.d( + TAG, + "showBusStationNotification --> ${it.toString()}" + ) + } + if (list.size >= 2) { + handler.postDelayed(this, 4000L) + } + } + } + } + } + + + private val handler by lazy { + val thread = HandlerThread("road_v2n_bus_station_calculate") + thread.start() + Handler(thread.looper) + } fun init() { CallerChassisLocationWGS84ListenerManager.addListener(TAG, 1, this) + handler?.post(checkDistanceRunnable) } fun unInit() { CallerChassisLocationWGS84ListenerManager.removeListener(TAG) - mScope?.cancel() + mCoroutineScope?.cancel() + busStationNearByQueue?.clear() + busStationListNeedNotified?.clear() + handler?.removeCallbacks(checkDistanceRunnable) + handler?.removeCallbacks(notificationCheckRunnable) + handler?.looper?.quit() } override fun onChassisLocationWGS84(gnssInfo: MogoLocation) { @@ -52,16 +199,14 @@ object BusStationEventManager : IMoGoChassisLocationWGS84Listener { * @param metersPreSegment 每段多少米 */ private fun calculateNearByStation( - gnssInfo: MogoLocation, - segmentSum: Int, - metersPreSegment: Int + gnssInfo: MogoLocation, segmentSum: Int, metersPreSegment: Int ) { - mScope.launch { + mCoroutineScope.launch { farthestLocationList.clear() val heading = gnssInfo.heading - //每10米一个点,获取150米范围内的坐标点 + //每metersPreSegment 米一个点,获取 segmentSum * metersPreSegment 米范围内的坐标点 for (index in 1..segmentSum) { - val newPoint = calculateNewPoint( + val newPoint = DrivingDirectionUtils.calculateNewPoint( gnssInfo.longitude, gnssInfo.latitude, heading, @@ -70,37 +215,54 @@ object BusStationEventManager : IMoGoChassisLocationWGS84Listener { newPoint?.also { farthestLocationList.add(LonLatPoint(it.first, it.second)) } + if (DebugConfig.isDebug()) { + farthestLocationList.last().also { + showHDMarker(it.longitude, it.latitude) + } + } } MogoData.mogoMapData.get()?.also { iMogoData -> val busStationList = iMogoData.getBusStation(farthestLocationList) + val filteredBusStationList = busStationList.filter { + it.busStationPoints.isNotEmpty() && + DrivingDirectionUtils.getDegreeOfCar2Poi( + gnssInfo.longitude, + gnssInfo.latitude, + it.getBusStationPoint().longitude, + it.getBusStationPoint().latitude, + gnssInfo.heading.toInt() + ) < 90 && CoordinateUtils.calculateLineDistance( + gnssInfo.longitude, + gnssInfo.latitude, + it.getBusStationPoint().longitude, + it.getBusStationPoint().latitude, + ) <= (segmentSum * metersPreSegment) + } Logger.d( TAG, - "calculateNearByStation --> 查询出附近公交站点 ${busStationList.size} 个" + "calculateNearByStation --> 本次查询出:${busStationList.size}个,本次符合条件:${filteredBusStationList.size}个,当前待提醒:${busStationListNeedNotified.size}个" ) - busStationList.forEach { - busStationListNearBy[it.getBusStationId()] = it + synchronized(busStationNearByQueue) { + busStationNearByQueue.clear() + busStationNearByQueue.add(busStationList) } } } } - /** - * 根据当前经纬度和方向,计算距离 distance 米处的坐标 - */ - private fun calculateNewPoint( - x: Double, - y: Double, - angle: Double, - distance: Double - ): Pair? { - if (distance == 0.0) { - return null - } - val radian = Math.toRadians(angle) - val radianCandle = Math.toRadians(angle) - val nX = x + distance * sin(radian) / 100000.0 - val nY = y + distance * sin(radianCandle) / 100000.0 - return Pair.create(nX, nY) + private fun showHDMarker(lon: Double, lat: Double) { + val builder = Point.Options.Builder( + "TYPE_MARKER_BUS_STATION", Level.MAP_MARKER + ).setId(UUID.randomUUID().toString()).anchor(0.2f, 0.2f) + .set3DMode(true) + .isUseGps(true) + .controlAngle(true) + .icon3DRes(EventTypeEnumNew.getMarker3DRes(EventTypeEnumNew.TYPE_SOCKET_ROAD_SHIGONG.poiType)) + .longitude(lon) + .latitude(lat) + val overlayManager = CallerMapUIServiceManager.getOverlayManager() + overlayManager?.removeAllPointsInOwner("TYPE_MARKER_BUS_STATION") + overlayManager?.showOrUpdatePoint(builder.build()) } } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/v2n/RoadV2NEventWindowView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/v2n/RoadV2NEventWindowView.kt index ce01fd6058..7f2a7a94a5 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/v2n/RoadV2NEventWindowView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/v2n/RoadV2NEventWindowView.kt @@ -33,7 +33,6 @@ import kotlinx.android.synthetic.main.hmi_view_road_v2n_event_window.view.tvV2XT import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import me.jessyan.autosize.utils.AutoSizeUtils -import java.util.UUID /** * 路侧V2N事件通用弹框 @@ -248,32 +247,6 @@ class RoadV2NEventWindowView @JvmOverloads constructor( super.onAttachedToWindow() CallerRoadV2NEventWindowListenerManager.addListener(TAG, this) initView() - //TODO - val eventId = UUID.randomUUID().toString() - CallerRoadV2NEventWindowListenerManager.show( - eventId, - System.currentTimeMillis(), - R.drawable.v2x_icon_shigong_zhandao, - "前方 200米 道路积水", - true, - "172.168.1.20", - 0.0, - 0.0 - ) - UiThreadHandler.postDelayed({ - CallerRoadV2NEventWindowListenerManager.dismiss(eventId) - - val eventId1 = CallerRoadV2NEventWindowListenerManager.show( - UUID.randomUUID().toString(), - System.currentTimeMillis(), - R.drawable.v2x_icon_jiaotongshigu_vr, - "前方 300米 发生交通事故", - true, - "172.168.1.20", - 0.0, - 0.0 - ) - }, 20 * 1000L) } override fun onDetachedFromWindow() { diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/entities/BusStation.kt b/libraries/mogo-map-api/src/main/java/com/mogo/map/entities/BusStation.kt index edfb3f6bc8..3d72dd27ab 100644 --- a/libraries/mogo-map-api/src/main/java/com/mogo/map/entities/BusStation.kt +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/entities/BusStation.kt @@ -1,16 +1,31 @@ package com.mogo.map.entities +import com.zhidaoauto.map.data.point.LonLatPoint + data class BusStation( var busStationPoints: List, var id: Int, var roadId: Int, - var type: Int + var type: Int, + var notifyTime: Long = -1, + var notifyDistance: Int ) { - override fun toString(): String { - return "BusStation(busStationPoints=$busStationPoints, id=$id, roadId=$roadId, type=$type)" - } fun getBusStationId(): String { - return "${id}_${roadId}" + return "bus_station_${id}_${roadId}" + } + + /** + * 返回的公交站点是一个坐标集合,从右上角->左上角->左下角->右下角->右上角 + */ + fun getBusStationPoint(): LonLatPoint { + if (busStationPoints.size >= 4) { + return busStationPoints[3] + } + return busStationPoints[0] + } + + override fun toString(): String { + return "BusStation(id=$id, roadId=$roadId, type=$type, notifyTime=$notifyTime, notifyDistance=$notifyDistance, busStationPoints=$busStationPoints)" } } \ No newline at end of file diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/MapDataWrapper.kt b/libraries/mogo-map/src/main/java/com/mogo/map/MapDataWrapper.kt index 8a4c49667d..c6bd7e2ac9 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/MapDataWrapper.kt +++ b/libraries/mogo-map/src/main/java/com/mogo/map/MapDataWrapper.kt @@ -293,7 +293,7 @@ object MapDataWrapper : IMogoData { override fun result(code: Int, result: RoutePath?) { result?.steps?.forEach { it?.busStations?.forEach { - val busStation = BusStation(it.busStationPoints, it.id, it.roadId, it.type) + val busStation = BusStation(it.busStationPoints, it.id, it.roadId, it.type, -1, -1) resultList.add(busStation) } }