[V2X][Road]施工占道事件触发后,标记道路颜色
This commit is contained in:
@@ -45,6 +45,8 @@ import com.mogo.eagle.core.function.v2x.events.network.V2XRefreshCallback
|
||||
import com.mogo.eagle.core.function.v2x.events.observer.V2XOptimalRouteObserver
|
||||
import com.mogo.eagle.core.function.v2x.events.receiver.SceneBroadcastReceiver
|
||||
import com.mogo.eagle.core.function.v2x.events.scenario.impl.V2XScenarioManager
|
||||
import com.mogo.eagle.core.function.v2x.events.scenario.scene.airoad.*
|
||||
import com.mogo.eagle.core.function.v2x.events.scenario.scene.airoad.AiRoadMarker.Marker
|
||||
import com.mogo.eagle.core.function.v2x.events.utils.*
|
||||
import com.mogo.eagle.core.function.v2x.events.voice.V2XVoiceManager
|
||||
import com.mogo.eagle.core.network.utils.GsonUtil
|
||||
@@ -62,7 +64,6 @@ import com.mogo.module.common.drawer.TrafficMarkerDrawer
|
||||
import com.mogo.module.common.entity.*
|
||||
import com.mogo.module.common.entity.V2XMessageEntity.V2XTypeEnum
|
||||
import com.mogo.module.common.enums.EventTypeEnum
|
||||
import com.mogo.module.common.enums.EventTypeEnum.FOURS_BLOCK_UP
|
||||
import com.mogo.module.common.enums.EventTypeHelper
|
||||
import com.mogo.service.statusmanager.IMogoStatusChangedListener
|
||||
import com.mogo.service.statusmanager.StatusDescriptor
|
||||
@@ -108,6 +109,7 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb
|
||||
BridgeApi.init(context)
|
||||
if (hasInit.compareAndSet(false, true)) {
|
||||
if (!V2XManager.hasInit()) {
|
||||
AiRoadMarker.init(context)
|
||||
V2XManager.init(V2XConfig.Builder().also {
|
||||
it.aiCloudConfig(MoGoAiCloudClientConfig.getInstance())
|
||||
it.context(context)
|
||||
@@ -483,6 +485,9 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb
|
||||
val p = CoordinateUtils.transformWgsToGcj(this.roadwork?.center?.point?.lat ?: 0.0, this.roadwork?.center?.point?.lon ?: 0.0)
|
||||
l4.lon = p[0]
|
||||
l4.lat = p[1]
|
||||
AiRoadMarker.enqueue(Marker(this.roadwork?.center?.point?.lat ?: 0.0, this.roadwork?.center?.point?.lon ?: 0.0, this.roadwork?.polygonList?.takeIf { it.isNotEmpty() }?.map { d ->
|
||||
android.util.Pair(d.lon, d.lat)
|
||||
}))
|
||||
l4.angle = this.roadwork?.center?.road?.bearing?.toDouble() ?: 0.0
|
||||
}
|
||||
})
|
||||
|
||||
@@ -0,0 +1,324 @@
|
||||
package com.mogo.eagle.core.function.v2x.events.scenario.scene.airoad
|
||||
|
||||
import android.content.*
|
||||
import android.graphics.*
|
||||
import android.util.*
|
||||
import androidx.lifecycle.*
|
||||
import androidx.lifecycle.Lifecycle.Event
|
||||
import androidx.lifecycle.Lifecycle.Event.ON_CREATE
|
||||
import androidx.lifecycle.Lifecycle.Event.ON_DESTROY
|
||||
import com.mogo.cloud.commons.utils.*
|
||||
import com.mogo.eagle.core.data.map.*
|
||||
import com.mogo.eagle.core.data.map.MapRoadInfo.StopLine
|
||||
import com.mogo.eagle.core.function.api.map.listener.*
|
||||
import com.mogo.eagle.core.function.call.map.*
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapRoadListenerManager.OnRoadListener
|
||||
import com.mogo.eagle.core.utilcode.kotlin.*
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.*
|
||||
import com.mogo.map.*
|
||||
import com.mogo.map.overlay.*
|
||||
import com.mogo.module.common.utils.*
|
||||
import io.netty.util.internal.*
|
||||
import java.util.*
|
||||
import java.util.concurrent.*
|
||||
import java.util.concurrent.atomic.*
|
||||
|
||||
/**
|
||||
* Ai云道路施工事件,道路颜色标记类
|
||||
*/
|
||||
object AiRoadMarker {
|
||||
|
||||
private const val TAG = "AiRoadMarker"
|
||||
|
||||
private val queue by lazy { LinkedBlockingQueue<Marker>() }
|
||||
|
||||
private val pool by lazy { Executors.newFixedThreadPool(2) }
|
||||
|
||||
private val marker by lazy { AtomicReference<Marker>() }
|
||||
|
||||
private val curStopLine by lazy { AtomicReference<StopLine>() }
|
||||
|
||||
private val lastStopLine by lazy { AtomicReference<StopLine>() }
|
||||
|
||||
private val carLocation by lazy { AtomicReference<Triple<Double, Double, Double>>() }
|
||||
|
||||
private val overlayManager by lazy { MogoOverlayManager.getInstance() }
|
||||
|
||||
private val redLine by lazy { AtomicReference<IMogoPolyline>() }
|
||||
|
||||
private val redLineColors = arrayListOf(Color.parseColor("#002ABAD9"), Color.parseColor("#FF7A30"))
|
||||
|
||||
// private val blueLine by lazy { AtomicReference<IMogoPolyline>() }
|
||||
//
|
||||
// private val blueLineColors = arrayListOf(Color.parseColor("#002ABAD9"), Color.parseColor("#30A3FF"))
|
||||
|
||||
private val markerCache = ConcurrentSet<Marker>()
|
||||
|
||||
private val redLineOptions by lazy {
|
||||
MogoPolylineOptions().apply {
|
||||
zIndex(40000f)
|
||||
setGps(true)
|
||||
width(30f)
|
||||
useGradient(true)
|
||||
colorValues(redLineColors)
|
||||
}
|
||||
}
|
||||
|
||||
// private val blueLineOptions by lazy {
|
||||
// MogoPolylineOptions().apply {
|
||||
// zIndex(30000f)
|
||||
// setGps(true)
|
||||
// width(40f)
|
||||
// useGradient(true)
|
||||
// colorValues(blueLineColors)
|
||||
// }
|
||||
// }
|
||||
|
||||
fun init(ctx: Context) {
|
||||
ctx.lifeCycleOwner.lifecycle.addObserver(object : LifecycleEventObserver {
|
||||
override fun onStateChanged(source: LifecycleOwner, event: Event) {
|
||||
if (event == ON_CREATE) {
|
||||
onCreate()
|
||||
}
|
||||
if (event == ON_DESTROY) {
|
||||
onDestroy()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
pool.execute {
|
||||
var interrupted = false
|
||||
Logger.d(TAG, "--- consumer --- 0 ---")
|
||||
while (!interrupted) {
|
||||
try {
|
||||
Logger.d(TAG, "--- consumer --- 1 ---")
|
||||
val top = queue.take() ?: continue
|
||||
Logger.d(TAG, "--- consumer --- 2 ---")
|
||||
val location = carLocation.get() ?: continue
|
||||
val isFrontOfCar = isFrontOfCar(top.poi_lon, top.poi_lat, location.first, location.second, location.third)
|
||||
val isSameRoad = isSameRoad(top.poi_lon, top.poi_lat, location.first, location.second, location.third)
|
||||
Logger.d(TAG, "--- consumer --- 3 ---isFrontOfCar: $isFrontOfCar, isSameRoad: $isSameRoad")
|
||||
if (isFrontOfCar && isSameRoad) {
|
||||
marker.set(top)
|
||||
marker(top)
|
||||
} else {
|
||||
markerCache.remove(top)
|
||||
}
|
||||
interrupted = Thread.currentThread().isInterrupted
|
||||
} catch (e: InterruptedException) {
|
||||
e.printStackTrace()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun isSameRoad(x1: Double, y1: Double, x2: Double, y2: Double, angle: Double): Boolean {
|
||||
val c1 = MogoMap.getInstance().mogoMap.getCenterLineRangeInfo(x1, y1, angle.toFloat(), 10f)
|
||||
val c2 = MogoMap.getInstance().mogoMap.getCenterLineRangeInfo(x2, y2, angle.toFloat(), 10f)
|
||||
Logger.d(TAG, "isSameRoad--: $c1 ==> $c2")
|
||||
return c1 != null && c2 != null && c1.road_id.isNotEmpty() && c1.road_id == c2.road_id
|
||||
}
|
||||
|
||||
private val onRoadListener = object : OnRoadListener {
|
||||
private var roadId = ""
|
||||
private var hasCrossRoad = false
|
||||
|
||||
override fun onRoadIdInfo(roadId: String) {
|
||||
Logger.d(TAG, "--- onRoadInfo --- roadId: $roadId")
|
||||
val oldRoadId = this.roadId
|
||||
if (oldRoadId != roadId) {
|
||||
if (hasCrossRoad) {
|
||||
hasCrossRoad = false
|
||||
lastStopLine.set(curStopLine.get())
|
||||
}
|
||||
}
|
||||
this.roadId = roadId
|
||||
}
|
||||
override fun onStopLineInfo(info: StopLine) {
|
||||
Logger.d(TAG, "--- onStopLineInfo --- info: $info")
|
||||
curStopLine.set(info)
|
||||
if (!hasCrossRoad) {
|
||||
hasCrossRoad = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val onLocationListener = object : IMoGoMapLocationListener {
|
||||
|
||||
|
||||
override fun onLocationChanged(location: MogoLocation?, from: Int) {
|
||||
if (location == null) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
val loc = CoordinateUtils.transformGcj02toWgs84(location.latitude, location.longitude)
|
||||
Logger.d(TAG, "x:${loc[0]}, y:${loc[1]}, angle: ${location.bearing}")
|
||||
carLocation.set(Triple(loc[0], loc[1], location.bearing.toDouble()))
|
||||
val marker = marker.get() ?: return
|
||||
val isOutOfRange = isOutOfRange(marker.poi_lon, marker.poi_lat, carLocation.get().first, carLocation.get().second, carLocation.get().third)
|
||||
Logger.d(TAG, "--- onLocationChanged: isOutOfRange: $isOutOfRange")
|
||||
if (isOutOfRange) {
|
||||
unMarker(marker)
|
||||
}
|
||||
} catch (t: Throwable) {
|
||||
Logger.e(TAG, "error: ${t.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// private fun drawBlueLine(points: List<Pair<Double, Double>>, location: MogoLocation) {
|
||||
// val line = blueLine.get()
|
||||
// blueLineOptions.points(points.filter {
|
||||
// DrivingDirectionUtils.getDegreeOfCar2Poi2(location.longitude, location.latitude, it.first, it.second, location.bearing.toDouble()) < 90L
|
||||
// }.map {
|
||||
// MogoLatLng(it.second, it.first)
|
||||
// })
|
||||
// if (line == null || line.isDestroyed) {
|
||||
// overlayManager.addPolyline(blueLineOptions)
|
||||
// } else {
|
||||
// line.setOption(blueLineOptions)
|
||||
// }
|
||||
// }
|
||||
|
||||
private fun onCreate() {
|
||||
CallerMapRoadListenerManager.registerRoadListener(TAG, onRoadListener)
|
||||
CallerMapLocationListenerManager.addListener(TAG, onLocationListener)
|
||||
}
|
||||
|
||||
private fun onDestroy() {
|
||||
CallerMapRoadListenerManager.unRegisterRoadListener(TAG)
|
||||
CallerMapLocationListenerManager.removeListener(TAG)
|
||||
pool.shutdownNow()
|
||||
}
|
||||
|
||||
|
||||
fun enqueue(marker: Marker) {
|
||||
Logger.d(TAG, "--- enqueue --- 1 ---")
|
||||
if (markerCache.contains(marker)) {
|
||||
Logger.d(TAG, "--- enqueue --- cache hit ---")
|
||||
return
|
||||
}
|
||||
Logger.d(TAG, "--- enqueue --- 2 ---")
|
||||
markerCache += marker
|
||||
pool.execute {
|
||||
Logger.d(TAG, "--- enqueue --- 3 ---${Thread.currentThread().name}::${Thread.currentThread().id}")
|
||||
queue.put(marker)
|
||||
}
|
||||
}
|
||||
|
||||
private fun marker(marker: Marker) {
|
||||
Logger.d(TAG, "--- marker --- 1 ---")
|
||||
val location = carLocation.get() ?: return
|
||||
Logger.d(TAG, "--- marker --- 2 ---")
|
||||
removeRedLine()
|
||||
//施工中心点前方的自车行驶方向上300米距离
|
||||
val l1 = MogoMap.getInstance().mogoMap.getCenterLineRangeInfo(marker.poi_lon, marker.poi_lat, location.third.toFloat(), 300f)
|
||||
//施工中心点后方的自车行驶方向上300米距离
|
||||
Logger.d(TAG, "--- marker --- 3 --- l1: $l1")
|
||||
val l2 = MogoMap.getInstance().mogoMap.getCenterLineRangeInfo(marker.poi_lon, marker.poi_lat, location.third.toFloat(), -300f)
|
||||
Logger.d(TAG, "--- marker --- 4 --- l2: $l2")
|
||||
val points = LinkedList<MogoLatLng>()
|
||||
if (l2 != null && l2.points.isNotEmpty()) {
|
||||
points.addAll(l2.points.map {
|
||||
MogoLatLng(it.second, it.first)
|
||||
})
|
||||
}
|
||||
val centerX= marker.poi_lon
|
||||
val centerY = marker.poi_lat
|
||||
Logger.d(TAG, "--- marker --- 5 --- marker: $marker")
|
||||
val farthestPoint = marker.polygon?.let {
|
||||
var find: Pair<Double, Double> = Pair(centerX, centerY)
|
||||
var min = Long.MAX_VALUE
|
||||
for (p in it) {
|
||||
val angle = DrivingDirectionUtils.getDegreeOfCar2Poi2(centerX, centerY, p.first, p.second, location.third)
|
||||
if (angle < min) {
|
||||
min = angle
|
||||
find = p
|
||||
}
|
||||
}
|
||||
MogoLatLng(find.second, find.second)
|
||||
} ?: MogoLatLng(centerY, centerX)
|
||||
marker.farthestPoint = Pair(farthestPoint.lon, farthestPoint.lat)
|
||||
Logger.d(TAG, "--- marker --- 6 --- marker: $marker")
|
||||
if (l1 != null && l1.points.isNotEmpty()) {
|
||||
for (l in l1.points) {
|
||||
if (DrivingDirectionUtils.getDegreeOfCar2Poi2(farthestPoint.lon, farthestPoint.lat, l.first, l.second, location.third) < 90L) {
|
||||
points.add(l.let { MogoLatLng(it.second, it.first) })
|
||||
}
|
||||
}
|
||||
}
|
||||
var line = redLine.get()
|
||||
redLineOptions.points(points)
|
||||
Logger.d(TAG, "--- marker --- 7 --- points: ${points.size}")
|
||||
if (line == null || line.isDestroyed) {
|
||||
val l = overlayManager.addPolyline(redLineOptions)
|
||||
this.redLine.set(l)
|
||||
line = l
|
||||
} else {
|
||||
line.setOption(redLineOptions)
|
||||
}
|
||||
if (!line.isVisible) {
|
||||
line.isVisible = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeRedLine() {
|
||||
val old = redLine.get()
|
||||
Logger.d(TAG, "--- removeRedLine --- 1 ---")
|
||||
if (old != null) {
|
||||
Logger.d(TAG, "--- removeRedLine --- 2 ---")
|
||||
redLine.set(null)
|
||||
old.isVisible = false
|
||||
old.remove()
|
||||
}
|
||||
}
|
||||
|
||||
// private fun removeBlueLine() {
|
||||
// val old = blueLine.get()
|
||||
// Logger.d(TAG, "--- removeBlueLine --- 1 ---")
|
||||
// if (old != null) {
|
||||
// Logger.d(TAG, "--- removeBlueLine --- 2 ---")
|
||||
// blueLine.set(null)
|
||||
// old.isVisible = false
|
||||
// old.remove()
|
||||
// }
|
||||
// }
|
||||
|
||||
private fun unMarker(marker: Marker) {
|
||||
markerCache -= marker
|
||||
removeRedLine()
|
||||
}
|
||||
|
||||
private fun isOutOfRange(markerLon: Double, markerLat: Double, carLon: Double, carLat: Double, carAngle: Double): Boolean {
|
||||
return !isFrontOfCar(markerLon, markerLat, carLon, carLat, carAngle)
|
||||
}
|
||||
|
||||
private fun isFrontOfCar(markerLon: Double, markerLat: Double, carLon: Double, carLat: Double, carAngle: Double): Boolean {
|
||||
val degree = DrivingDirectionUtils.getDegreeOfCar2Poi2(carLon, carLat, markerLon, markerLat, carAngle)
|
||||
return degree < 90
|
||||
}
|
||||
|
||||
data class Marker(
|
||||
val poi_lat: Double,
|
||||
val poi_lon: Double,
|
||||
val polygon: List<Pair<Double, Double>>?,
|
||||
var farthestPoint: Pair<Double, Double>? = null
|
||||
) {
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
other as Marker
|
||||
if (poi_lat != other.poi_lat) return false
|
||||
if (poi_lon != other.poi_lon) return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = poi_lat.hashCode()
|
||||
result = 31 * result + poi_lon.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,34 +91,6 @@ public class V2XRoadEventMarker implements IV2XMarker<V2XRoadEventEntity> {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// if (polygons.size() > 1) {
|
||||
// if (overlayManager == null) {
|
||||
// overlayManager = MogoOverlayManager.getInstance();
|
||||
// }
|
||||
// MogoPolylineOptions options = new MogoPolylineOptions();
|
||||
// List<Integer> colors = new ArrayList<>();
|
||||
// colors.add(Color.argb(204, 237, 172, 21));
|
||||
// colors.add(Color.argb(0, 255, 255, 255));
|
||||
// options.colorValues(colors);
|
||||
// List<MogoLatLng> points = new ArrayList<>();
|
||||
// for (int i = 0; i < polygons.size(); i++) {
|
||||
// Pair<Double, Double> p = polygons.get(i);
|
||||
// points.add(new MogoLatLng(p.second, p.first));
|
||||
// }
|
||||
// if (points.size() > 2) {
|
||||
// points.add(points.get(0));
|
||||
// }
|
||||
// options.points(points);
|
||||
// options.useGradient(true);
|
||||
// options.useFacade(true);
|
||||
// options.setGps(false);
|
||||
// options.width(5f);
|
||||
// options.zIndex(75000f);
|
||||
// options.maxIndex(800000f);
|
||||
// polyline = overlayManager.addPolyline(options);
|
||||
// polyline.setVisible(true);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user