[6.5.0] feat: 通过公交站点计算逻辑实现;

This commit is contained in:
aibingbing
2024-07-01 19:37:24 +08:00
parent 59acceb7c0
commit db0e9a9349
4 changed files with 216 additions and 66 deletions

View File

@@ -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<LonLatPoint>()
private val busStationListNearBy = LinkedHashMap<String, BusStation>()
private val mCoroutineScope: CoroutineScope =
CoroutineScope(SupervisorJob() + Dispatchers.Default)
// 距离当前车位置 X 米远的点集合用来查询根据点查询roadId, 然后用roadId查询路上的公交站点
private val farthestLocationList = ArrayList<LonLatPoint>()
// 是否在计算附近的公交站点集合
private val isCalculateNearByStation = AtomicBoolean(false)
// 查询出来的符合条件的公交站点集合
private val busStationNearByQueue = LinkedList<List<BusStation>>()
// 需要提醒的公交站点
private val busStationListNeedNotified = HashMap<String, BusStation>()
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<Double, Double>? {
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())
}
}

View File

@@ -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() {