diff --git a/app/build.gradle b/app/build.gradle index 02e2bede7f..0b5f1cb500 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -292,7 +292,6 @@ dependencies { androidTestImplementation rootProject.ext.dependencies.androidx_runner androidTestImplementation rootProject.ext.dependencies.androidx_espresso_core androidTestImplementation rootProject.ext.dependencies.localbroadcastmanager - androidTestImplementation rootProject.ext.dependencies.mogo_v2x // if (isAndroidTestBuild()) { // implementation "com.mogo.thread.opt:lib:${THREAD_OPT_VERSION}" diff --git a/app/src/androidTest/java/com/mogo/functions/test/RoadAITest.kt b/app/src/androidTest/java/com/mogo/functions/test/RoadAITest.kt index 2b282ce620..5c29d76922 100644 --- a/app/src/androidTest/java/com/mogo/functions/test/RoadAITest.kt +++ b/app/src/androidTest/java/com/mogo/functions/test/RoadAITest.kt @@ -7,7 +7,7 @@ import androidx.test.filters.* import com.mogo.eagle.core.function.hmi.ui.* import com.mogo.eagle.core.function.main.* import com.mogo.eagle.core.function.v2x.events.* -import com.mogo.v2x.event.V2XEvent.RoadAI +import com.mogo.eagle.core.function.v2x.internal.event.V2XEvent.RoadAI import kotlinx.coroutines.* import org.junit.* import org.junit.runner.* diff --git a/config.gradle b/config.gradle index f18228dd1c..2899979b86 100644 --- a/config.gradle +++ b/config.gradle @@ -201,8 +201,6 @@ ext { mogo_core_utils : "com.mogo.eagle.core:utils:${MOGO_CORE_UTILS_VERSION}", mogo_core_network : "com.mogo.eagle.core:network:${MOGO_CORE_NETWORK_VERSION}", - //========================= V2X SDK ========================= - mogo_v2x : "com.mogo.v2x:v2x:${MOGO_V2X_SDK_VERSION}", life_cycle_scope : "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0", view_model_scope : "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0", diff --git a/core/function-impl/mogo-core-function-v2x/build.gradle b/core/function-impl/mogo-core-function-v2x/build.gradle index 0549db5dd0..4a75c0e99f 100644 --- a/core/function-impl/mogo-core-function-v2x/build.gradle +++ b/core/function-impl/mogo-core-function-v2x/build.gradle @@ -4,6 +4,7 @@ plugins { id 'kotlin-android-extensions' id 'kotlin-kapt' id 'com.alibaba.arouter' + id 'com.google.protobuf' } android { compileSdkVersion rootProject.ext.android.compileSdkVersion @@ -35,6 +36,19 @@ android { targetCompatibility JavaVersion.VERSION_1_8 } + protobuf { + protoc { + artifact = rootProject.ext.dependencies.protoc + } + generateProtoTasks { + all().each { task -> + task.builtins { + java {} + } + } + } + } + } dependencies { @@ -50,7 +64,8 @@ dependencies { implementation rootProject.ext.dependencies.rxandroid implementation rootProject.ext.dependencies.flexbox kapt rootProject.ext.dependencies.aroutercompiler - implementation rootProject.ext.dependencies.mogo_v2x + implementation rootProject.ext.dependencies.protobuf_java + implementation rootProject.ext.dependencies.protobuf_java_util implementation rootProject.ext.dependencies.mogoaicloudtrafficlive if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { implementation rootProject.ext.dependencies.mogocommons diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/V2XEventManager.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/V2XEventManager.kt index 7605e99bc7..d60cbc18aa 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/V2XEventManager.kt +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/V2XEventManager.kt @@ -5,7 +5,6 @@ import android.content.* import android.os.* import android.provider.Settings.System import android.util.* -import androidx.core.util.Pair import androidx.localbroadcastmanager.content.* import com.mogo.cloud.commons.utils.* import com.mogo.cloud.passport.* @@ -31,11 +30,9 @@ import com.mogo.eagle.core.data.msgbox.MsgBoxType import com.mogo.eagle.core.data.msgbox.V2XMsg import com.mogo.eagle.core.data.traffic.* import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotIdentifyListener -import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotPlanningActionsListener import com.mogo.eagle.core.function.api.hmi.warning.* import com.mogo.eagle.core.function.api.map.listener.* import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager -import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPlanningActionsListenerManager import com.mogo.eagle.core.function.call.hmi.* import com.mogo.eagle.core.function.call.map.* import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager.Scene.Default @@ -53,10 +50,17 @@ import com.mogo.eagle.core.function.v2x.events.observer.* import com.mogo.eagle.core.function.v2x.events.receiver.* import com.mogo.eagle.core.function.v2x.events.scenario.impl.* 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.utils.MapUtils import com.mogo.eagle.core.function.v2x.events.voice.* +import com.mogo.eagle.core.function.v2x.internal.V2XManager +import com.mogo.eagle.core.function.v2x.internal.callback.IV2XCallback +import com.mogo.eagle.core.function.v2x.internal.config.V2XConfig +import com.mogo.eagle.core.function.v2x.internal.data.V2XAdvanceWarning +import com.mogo.eagle.core.function.v2x.internal.data.V2XMarkerCardResult +import com.mogo.eagle.core.function.v2x.internal.data.V2XOptimalRoute +import com.mogo.eagle.core.function.v2x.internal.data.V2XWarningTarget +import com.mogo.eagle.core.function.v2x.internal.event.V2XEvent import com.mogo.eagle.core.network.utils.* import com.mogo.eagle.core.utilcode.mogo.logger.* import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_V2X @@ -66,11 +70,6 @@ import com.mogo.eagle.core.utilcode.util.TimeUtils import com.mogo.eagle.core.utilcode.util.Utils import com.mogo.map.listener.* import com.mogo.map.marker.* -import com.mogo.v2x.* -import com.mogo.v2x.callback.* -import com.mogo.v2x.config.* -import com.mogo.v2x.data.* -import com.mogo.v2x.event.* import com.shuyu.gsyvideoplayer.* import com.shuyu.gsyvideoplayer.cache.* import com.shuyu.gsyvideoplayer.model.* @@ -80,7 +79,6 @@ import com.zhjt.service.chain.* import kotlinx.coroutines.* import kotlinx.coroutines.android.* import mogo.telematics.pad.MessagePad -import roadwork.Road.RW_PB import tv.danmaku.ijk.media.player.* import java.util.concurrent.* import java.util.concurrent.atomic.* diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/IMoGoV2XMarkerManager.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/IMoGoV2XMarkerManager.java index 739c8cdf99..5d795e8cd3 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/IMoGoV2XMarkerManager.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/IMoGoV2XMarkerManager.java @@ -5,7 +5,7 @@ import android.content.Context; import com.alibaba.android.arouter.facade.template.IProvider; import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity; import com.mogo.map.marker.IMogoMarkerClickListener; -import com.mogo.v2x.data.V2XMarkerCardResult; +import com.mogo.eagle.core.function.v2x.internal.data.V2XMarkerCardResult; import java.util.concurrent.CopyOnWriteArrayList; diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/impl/MoGoV2XMarkerManager.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/impl/MoGoV2XMarkerManager.java index 8e8ad1a041..2269ede098 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/impl/MoGoV2XMarkerManager.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/impl/MoGoV2XMarkerManager.java @@ -33,10 +33,10 @@ import com.mogo.map.marker.IMogoMarker; import com.mogo.map.marker.IMogoMarkerClickListener; import com.mogo.map.marker.IMogoMarkerManager; import com.mogo.map.marker.MogoMarkerOptions; -import com.mogo.v2x.V2XManager; -import com.mogo.v2x.data.V2XMarkerCardResult; -import com.mogo.v2x.data.V2XMarkerExploreWay; -import com.mogo.v2x.data.V2XMarkerLocation; +import com.mogo.eagle.core.function.v2x.internal.V2XManager; +import com.mogo.eagle.core.function.v2x.internal.data.V2XMarkerCardResult; +import com.mogo.eagle.core.function.v2x.internal.data.V2XMarkerExploreWay; +import com.mogo.eagle.core.function.v2x.internal.data.V2XMarkerLocation; import java.util.List; import java.util.Objects; diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/airoad/AiRoadMarker.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/airoad/AiRoadMarker.kt index 6755da11f0..36113a7a20 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/airoad/AiRoadMarker.kt +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/airoad/AiRoadMarker.kt @@ -40,10 +40,6 @@ object AiRoadMarker { private const val TAG = "AiRoadMarker" - private val queue by lazy { LinkedBlockingQueue() } - - private val pool by lazy { Executors.newFixedThreadPool(2) } - private val marker by lazy { AtomicReference() } private val carLocation by lazy { AtomicReference>() } @@ -127,49 +123,6 @@ object AiRoadMarker { } } }) - - 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() - if (location == null) { - if (queue.isEmpty()) { - synchronized(markers) { - markers.clear() - } - } - continue - } - val isTrigger = isTriggerEvent(top.poi_lon, top.poi_lat, location.first, location.second, location.third) - Logger.d(TAG, "--- consumer --- 3 ---: isTrigger => $isTrigger") - if (isTrigger) { - marker.set(top) - marker(top, true) - } else { - synchronized(markers) { - markers.remove(top) - } - } - interrupted = Thread.currentThread().isInterrupted - } catch (e: InterruptedException) { - e.printStackTrace() - break - } - } - } - } - - private fun isTriggerEvent(x1: Double, y1: Double, x2: Double, y2: Double, a2: Double): Boolean { - val angle = DrivingDirectionUtils.getDegreeOfCar2Poi2(x2, y2, x1, y1, a2) - if (angle <= 60 && DrivingDirectionUtils.distance(x1, y1, x2, y2) <= 300) { - return true - } - return false } private val onRoadListener = object : OnRoadListener { @@ -219,26 +172,9 @@ object AiRoadMarker { CallerMapRoadListenerManager.unRegisterRoadListener(TAG) CallMarkersClearManager.removeAllMarkersClearListener(TAG) CallerMapLocationListenerManager.removeListener(TAG, true) - pool.shutdownNow() removeLine() } - fun enqueue(marker: Marker) { - Logger.d(TAG, "--- enqueue --- 1 ---") - if (markers.contains(marker)) { - Logger.d(TAG, "--- enqueue --- cache hit ---") - return - } - Logger.d(TAG, "--- enqueue --- 2 ---") - synchronized(markers) { - markers += marker - } - pool.execute { - Logger.d(TAG, "--- enqueue --- 3 ---${Thread.currentThread().name}::${Thread.currentThread().id}") - queue.put(marker) - } - } - fun marker(marker: Marker, drawMarker: Boolean) { handler.removeCallbacks(checkExpiredTask) val location = carLocation.get() ?: return diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/warning/V2XFrontWarningScenario.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/warning/V2XFrontWarningScenario.java index c4d1d6f357..872505f046 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/warning/V2XFrontWarningScenario.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/warning/V2XFrontWarningScenario.java @@ -22,7 +22,7 @@ import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager; import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; import com.mogo.eagle.core.function.v2x.events.scenario.impl.AbsV2XScenario; import com.mogo.eagle.core.function.v2x.events.scenario.view.IV2XMarker; -import com.mogo.v2x.data.V2XWarningTarget; +import com.mogo.eagle.core.function.v2x.internal.data.V2XWarningTarget; import java.math.BigDecimal; import java.util.Locale; import java.util.concurrent.TimeUnit; diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/warning/V2XWarningMarker.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/warning/V2XWarningMarker.java index 934749b42e..468f854c6f 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/warning/V2XWarningMarker.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/warning/V2XWarningMarker.java @@ -25,8 +25,8 @@ import com.mogo.map.MogoMarkerManager; import com.mogo.map.marker.IMogoMarkerManager; import com.mogo.map.overlay.IMogoPolyline; import com.mogo.commons.utils.Trigonometric; -import com.mogo.v2x.data.V2XLocation; -import com.mogo.v2x.data.V2XWarningTarget; +import com.mogo.eagle.core.function.v2x.internal.data.V2XLocation; +import com.mogo.eagle.core.function.v2x.internal.data.V2XWarningTarget; import java.util.ArrayList; import java.util.Arrays; diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/utils/EntityUtils.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/utils/EntityUtils.kt index 08ecd097e8..60ec2f4030 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/utils/EntityUtils.kt +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/utils/EntityUtils.kt @@ -7,8 +7,12 @@ import com.mogo.eagle.core.data.map.entity.MarkerLocation import com.mogo.eagle.core.data.map.entity.MarkerUserInfo import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity import com.mogo.eagle.core.function.v2x.events.scenario.scene.airoad.AiRoadMarker +import com.mogo.eagle.core.function.v2x.internal.data.MarkerExploreWayItem +import com.mogo.eagle.core.function.v2x.internal.data.V2XMarkerCardResult +import com.mogo.eagle.core.function.v2x.internal.data.V2XMarkerExploreWay +import com.mogo.eagle.core.function.v2x.internal.data.V2XMarkerLocation +import com.mogo.eagle.core.function.v2x.internal.data.V2XMarkerUserInfo import com.mogo.map.MogoMap -import com.mogo.v2x.data.* import mogo.telematics.pad.MessagePad import roadwork.Road diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/V2XManager.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/V2XManager.kt new file mode 100755 index 0000000000..3d6f2ec152 --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/V2XManager.kt @@ -0,0 +1,256 @@ +package com.mogo.eagle.core.function.v2x.internal + +import android.os.Handler +import android.os.Looper +import com.mogo.cloud.passport.MoGoAiCloudClientConfig +import com.mogo.cloud.socket.SocketManager +import com.mogo.eagle.core.function.v2x.internal.callback.IV2XCallback +import com.mogo.eagle.core.function.v2x.internal.config.V2XConfig +import com.mogo.eagle.core.function.v2x.internal.data.V2XMarkerResponse +import com.mogo.eagle.core.function.v2x.internal.event.V2XEvent +import com.mogo.eagle.core.function.v2x.internal.http.V2XRefreshModel +import com.mogo.eagle.core.function.v2x.internal.http.callback.IV2XRefreshCallback +import com.mogo.eagle.core.function.v2x.internal.logger.Logger +import com.mogo.eagle.core.function.v2x.internal.socket.V2XMessageListener_401012 +import com.mogo.eagle.core.function.v2x.internal.socket.V2XMessageListener_401018 +import com.mogo.eagle.core.function.v2x.internal.socket.V2XMessageListener_402000 +import com.mogo.eagle.core.function.v2x.internal.socket.V2XMessageListener_404000 +import com.mogo.eagle.core.function.v2x.internal.socket.V2XMessageListener_503000 +import com.mogo.eagle.core.function.v2x.internal.utils.DistanceUtils +import java.util.concurrent.CopyOnWriteArrayList +import java.util.concurrent.atomic.AtomicBoolean +import java.util.concurrent.atomic.AtomicReference + +object V2XManager { + + internal const val TAG = "V2XManager" + + private val config: AtomicReference by lazy { + AtomicReference(null) + } + + private val cbs by lazy { + CopyOnWriteArrayList() + } + + private val lastLongitude by lazy { + AtomicReference(0.0) + } + + private val lastLatitude by lazy { + AtomicReference(0.0) + } + + private val realLongitude by lazy { AtomicReference(0.0) } + + private val realLatitude by lazy { AtomicReference(0.0) } + + + + /** + * 标识此参数是否启动 + */ + private val started by lazy { + AtomicBoolean(false) + } + + private val refreshCallback = object : IV2XRefreshCallback { + + override fun onSuccess(result: V2XMarkerResponse) { + cbs.forEach { + it.onAck(V2XEvent.Marker(result)) + } + } + + override fun onFail(msg: String?) { + cbs.forEach { + it.onFail(msg ?: "") + } + } + } + + + private val refreshTask = object : Runnable { + override fun run() { + V2XRefreshModel.querySnapshot(longitude = realLongitude.get(), latitude = realLatitude.get(), refreshCallback) + handler.postDelayed(this, config.get().durationForTriggerRefresh) + } + } + + private val handler by lazy { + Handler(Looper.getMainLooper()) + } + + /** + * 根据所配置的参数,初始化V2X相关功能(注: 此方法不要重复调用,非首次调用会抛异常) + * @param config 相关配置类 + */ + fun init(config: V2XConfig) { + Logger.d(TAG, "-- init --") + if (V2XManager.config.get() != null) { + throw IllegalStateException("V2XManager has been initialized, don't initialize repeatably.") + } + V2XManager.config.set(config) + Logger.loggable = config.loggable + } + + /** + * - 开启V2X功能, 此方法调用前,要确保满足以下两个条件: + * 1.初始化方法[init]已调用 + * 2.确保[MoGoAiCloudClientConfig.sn]和[MoGoAiCloudClientConfig.token]两个值存在,如果其中有一个值不存在,不会启动相关功能 + * - 此函数的功能如下: + * 1.建立长链接[SocketManager.init] + * 2.位置上报服务[LocationManager.init]和[LocationManager.start] + * 3.短链[V2XRefreshModel.querySnapshot]定时轮循,轮循时长取[V2XConfig.durationForTriggerRefresh] + */ + fun start() { + Logger.d(TAG, "-- start --") + val config = config.get() ?: throw IllegalStateException("V2XManager has not been initialized, please invoke V2XManager#init(config: X2XConfig) firstly.") + if (started.get()) { + Logger.d(TAG, "-- has been started --") + return + } + if (config.aiCloudConfig.sn?.isBlank() == true) { + Logger.e(TAG, "sn is null or blank, please ensure sn exists and then invoke V2XManager#start() again.") + cbs.forEach { + it.onFail("sn is null or blank, please ensure sn exists and then invoke V2XManager#start() again.") + } + return + } + if (config.aiCloudConfig.token?.isBlank() == true) { + Logger.e(TAG, "token is null or blank, please ensure token exists and then invoke V2Manager#start() again.") + cbs.forEach { + it.onFail("token is null or blank, please ensure token exists and then invoke V2Manager#start() again.") + } + return + } + if (started.compareAndSet(false, true)) { + Logger.d(TAG, "-- start real --") + SocketManager.getInstance().init(config.context,0.0,0.0) + SocketManager.getInstance().registerOnMessageListener(401012, V2XMessageListener_401012(cbs)) + SocketManager.getInstance().registerOnMessageListener(401018, V2XMessageListener_401018(cbs)) + SocketManager.getInstance().registerOnMessageListener(402000, V2XMessageListener_402000(cbs)) + SocketManager.getInstance().registerOnMessageListener(404000, V2XMessageListener_404000(cbs)) + SocketManager.getInstance().registerOnMessageListener(503000, V2XMessageListener_503000(cbs)) + handler.post(refreshTask) + } + } + + /** + * @param sn 更新后的sn + * @param token 更新后的token + */ + fun updateSnAndToken(sn: String?, token: String?) { + val config = config.get() ?: throw IllegalStateException("V2XManager has not been initialized, please invoke V2XManager#init(config: X2XConfig) firstly.") + sn ?: return + token ?: return + if (started.get()) { + return + } + config.aiCloudConfig.sn = sn + config.aiCloudConfig.token = token + start() + } + + /** + * 停止V2X功能 + * 1. 断开长链接[SocketManager.release] + * 2. 停止位置上报[LocationManager.stop] + * 3. 取消短链定时轮循任务 + */ + fun stop() { + Logger.d(TAG, "-- stop --") + if (config.get() == null) { + throw IllegalStateException("V2XManager has not been initialized, please invoke V2XManager#init(config: X2XConfig) firstly.") + } + if (started.compareAndSet(true, false)) { + Logger.d(TAG, "-- stop real --") + SocketManager.getInstance().release() + handler.removeCallbacks(refreshTask) + lastLatitude.set(0.0) + lastLongitude.set(0.0) + } + } + + /** + * 添加相关信息接口回调 + * @param cb 要添加的回调接口 + */ + fun addCallback(cb: IV2XCallback) { + Logger.d(TAG, "-- addCallback --") + if (cbs.contains(cb)) { + return + } + cbs += cb + } + + /** + * 移除相关信息接口回调 + * @param cb 要移除的回调接口 + */ + fun removeCallback(cb: IV2XCallback) { + Logger.d(TAG, "-- removeCallback --") + if (!cbs.contains(cb)) { + return + } + cbs.remove(cb) + } + + /** + * 当自车位置变量时调用 + * @param longitude 自车所在精度 + * @param latitude 自车所在纬度 + */ + fun onLocationChanged(longitude: Double, latitude: Double) { + if (config.get() == null) { + throw IllegalStateException("V2XManager has not been initialized, please invoke V2XManager#init(config: X2XConfig) firstly.") + } + if (!started.get()) { + return + } + Logger.d(TAG, "--- onLocationChanged --[longitude: $longitude, latitude: $latitude]") + realLongitude.set(longitude) + realLatitude.set(latitude) + val oldLon = lastLongitude.get() + val oldLat = lastLatitude.get() + var update = false + try { + if (oldLon == 0.0 || oldLat == 0.0) { + Logger.d(TAG, "--- onLocationChanged -- first --[longitude: $longitude, latitude: $latitude]") + handler.removeCallbacks(refreshTask) + handler.post(refreshTask) + update = true + return + } + if (DistanceUtils.calculateLineDistance(oldLon, oldLat, longitude, latitude) >= config.get().distanceForTriggerRefresh) { + Logger.d(TAG, "--- onLocationChanged -- trigger --[longitude: $longitude, latitude: $latitude]") + handler.removeCallbacks(refreshTask) + handler.post(refreshTask) + update = true + } + } finally { + if (update) { + lastLatitude.set(latitude) + lastLongitude.set(longitude) + } + } + } + + /** + * 是否已经初始化 + * @return true: 已初始化过 false: 未初始化 + */ + fun hasInit() = getConfig() != null + + /** + * 强制刷新道路事件 + */ + fun forceRefresh() { + if (hasInit()) { + handler.removeCallbacks(refreshTask) + handler.post(refreshTask) + } + } + + internal fun getConfig() = config.get() +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/callback/IV2XCallback.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/callback/IV2XCallback.kt new file mode 100644 index 0000000000..f755c465e4 --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/callback/IV2XCallback.kt @@ -0,0 +1,24 @@ +package com.mogo.eagle.core.function.v2x.internal.callback + +import com.mogo.eagle.core.function.v2x.internal.event.V2XEvent + +interface IV2XCallback { + + + /** + * 获取到V2X事件成功回调 + * @param event + * - 参数说明:目前此参数支持以下类型 + * - [V2XEvent.ForwardsWarning]: 路口碰撞预警、盲区预警等预警事件, 数据实体取自[V2XEvent.ForwardsWarning.data] + * - [V2XEvent.Road]: 道路事件, 数据实体取自[V2XEvent.Road.data] + * - [V2XEvent.Warning]: 预警目标物事件, 数据实体取自[V2XEvent.Warning.data] + * - [V2XEvent.Marker]: 道路标记事件, 数据实体取自[V2XEvent.Marker.data] + */ + fun onAck(event: V2XEvent) + + /** + * V2X事件获取过程中,出现的异常信息,用于问题排查 + * @param msg 异常信息 + */ + fun onFail(msg: String) +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/config/V2XConfig.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/config/V2XConfig.kt new file mode 100755 index 0000000000..1ab70b67ac --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/config/V2XConfig.kt @@ -0,0 +1,174 @@ +package com.mogo.eagle.core.function.v2x.internal.config + +import android.content.Context +import com.mogo.cloud.passport.MoGoAiCloudClientConfig +import com.mogo.eagle.core.function.v2x.internal.executor.Executors +import java.util.concurrent.Executor +import java.util.concurrent.TimeUnit +import kotlin.IllegalStateException + +/** + * V2X相关配置 + */ +class V2XConfig private constructor(builder: Builder) { + + /** + * - 应用上下文 + * - 必选项 + * - 通过[Builder.context]设置 + */ + val context : Context by lazy { + builder.context?.applicationContext ?: throw IllegalStateException("context must not be null.") + } + + /** + * - 云平台配置参数 + * - 必选项 + * - 通过[Builder.aiCloudConfig]设置 + */ + val aiCloudConfig by lazy { + builder.aiCloudConfig ?: throw IllegalStateException("aiCloudConfig must not be null.") + } + + /** + * - 网络请求使用的线程池,IO类型 + * - 可选项 + * - 通过[Builder.executor]设置 + */ + val executor: Executor by lazy { + builder.executor ?: Executors.IO + } + + /** + * - 是否开启日志 + * - 可选项 + * - 通过[Builder.loggable]设置,开发阶段可以打开,应用发布后记得关闭 + */ + val loggable: Boolean by lazy { + builder.loggable + } + + /** + * - 公共参数, 默认为空 + * - 可选项 + * - 通过[Builder.staticParams]设置 + */ + val staticParams by lazy { + builder.staticParams ?: HashMap() + } + + /** + * - 基础Url, 默认值为`http://dzt-launcherSnapshot.zhidaozhixing.com` + * - 可选项 + * - 通过[Builder.baseUrl]设置 + */ + val baseUrl by lazy { + builder.baseUrl ?: "http://dzt-launcherSnapshot.zhidaozhixing.com" + + } + + /** + * - 多长时间请求一次自车周边信息,单位为毫秒,默认值为`6_000`毫秒 + * - 可选项 + * - 通过[Builder.durationForTriggerRefresh]设置 + */ + val durationForTriggerRefresh by lazy { + val duration = builder.durationForTriggerRefresh + if (duration == null || duration <= 0) TimeUnit.SECONDS.toMillis(60) else duration + } + + /** + * - 自车行驶超过此长度,会刷新自车周边信息,单位为`米` + * - 可选项 + * - 通过[Builder.distanceForTriggerRefresh]设置 + */ + val distanceForTriggerRefresh: Float by lazy { + val distance = builder.distanceForTriggerRefresh + if (distance == null || distance <= 0) 200f else distance + } + + internal fun newBuilder() = Builder(this) + + class Builder { + + internal var context: Context? = null + + internal var executor: Executor? = null + + internal var loggable: Boolean = false + + internal var staticParams: Map? = null + + internal var aiCloudConfig: MoGoAiCloudClientConfig? = null + + internal var durationForTriggerRefresh: Long? = null + + internal var baseUrl: String? = null + + internal var distanceForTriggerRefresh: Float? = null + + constructor() + + internal constructor(config: V2XConfig) { + context = config.context + executor = config.executor + loggable = config.loggable + baseUrl = config.baseUrl + staticParams = config.staticParams + aiCloudConfig = config.aiCloudConfig + durationForTriggerRefresh = config.durationForTriggerRefresh + distanceForTriggerRefresh = config.distanceForTriggerRefresh + } + + /** + * 应用上下文,此参数为必选项,不设置会抛异常 + */ + fun context(context: Context) = apply { this.context = context } + + /** + * 是否开启日志 + */ + fun loggable(loggable: Boolean) = apply { this.loggable = loggable } + + /** + * 公共参数列表 + */ + fun staticParams(params: Map) = apply { this.staticParams = params } + + /** + * 网络请求线程池,如未设置,会使用内置的线程池[Executors.IO] + */ + fun executor(executor: Executor): Builder = apply { + if (this.executor != null) { + throw IllegalArgumentException("io executor has been initialized, don't set repeatedly.") + } + this.executor = executor + } + + /** + * 刷新周边信息的时间间隔 + * @param duration 时长 + * @param unit 时间单位 + */ + fun durationForTriggerRefresh(duration: Long, unit: TimeUnit = TimeUnit.SECONDS) = apply { this.durationForTriggerRefresh = unit.toMillis(duration) } + + /** + * @param distance 超过此距离会触发刷新周边道路信息,单位为米 + */ + fun distanceForTriggerRefresh(distance: Float) = apply { this.distanceForTriggerRefresh = distance } + + /** + * 云平台配置信息,此参数为必选项,不设置会抛异常 + * @param config 云平台配置 + */ + fun aiCloudConfig(config: MoGoAiCloudClientConfig) = apply { this.aiCloudConfig = config } + + /** + * 云平台baseUrl + * @param baseUrl 云平台baseUrl + */ + fun baseUrl(baseUrl: String) = apply { this.baseUrl = baseUrl } + + fun build() : V2XConfig = V2XConfig(this) + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XAdvanceWarning.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XAdvanceWarning.kt new file mode 100644 index 0000000000..df71ca8175 --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XAdvanceWarning.kt @@ -0,0 +1,120 @@ +package com.mogo.eagle.core.function.v2x.internal.data + +import androidx.annotation.Keep +import java.io.Serializable + +/** + * 路口碰撞预警、盲区预警等数据实体 + */ +@Keep +class V2XAdvanceWarning: Serializable { + + companion object { + private const val serialVersionUID = -446395L + } + + /** + * 物体唯一标识 + */ + var objectId: String? = null + + /** + * 物体类型: + * 1-人 + * 2-自行车 + * 3-小轿车 + * 4-摩托车 + * 5-红绿灯 + * 6-公交车 + * 8-卡车 + * 9-路边摄像头 + */ + var objectType: Int? = -1 + + /** + * 1-add + * 2-update + * 3-delete + */ + var status: Int? = -1 + + /** + * 大类标识 + * 1-预警 + * 2-规划 + * 3-拥堵 + * 4-事故 + */ + var typeId: Int? = -1 + + /** + * 预警下发时间 + */ + var time: Long? = 0 + + /** + * 预警等级 + */ + var level: Int? = -1 + + /** + * 危险等级: + * 0-保留 + * 1-模型原始颜色 + * 2-通知--黄 + * 3-警告--红 + */ + var threatLevel: Int? = -1 + + /** + * 目标预警物所在位置 + */ + var position: V2XLocation? = null + + /** + * 目标预警物朝向 + */ + var heading: Double? = 0.0 + + /** + * 目标预警物速度 + */ + var speed: Double? = 0.0 + + /** + * 目标预警物到自车距离 + */ + var distance: Double? = 0.0 + + /** + * 道路ID + */ + var roadId: String? = null + + /** + * 车道ID + */ + var laneId: String? = null + + /** + * 车道号: + * 中心线编号为0, 中心线右侧编号为负数。 + * eg: 3车道通行Road的车道编号,0,-1,-2,-3 + */ + var laneNum: Int? = Integer.MIN_VALUE + + /** + * 线性经纬度轨迹列表(高德) + */ + var gdLocusList: List? = null + + /** + * 轨迹列表(Wgs84坐标系) + */ + var locusList: List? = null + + override fun toString(): String { + return "V2XAdvanceWarning(objectId=$objectId, objectType=$objectType, status=$status, typeId=$typeId, time=$time, level=$level, threatLevel=$threatLevel, position=$position, heading=$heading, speed=$speed, distance=$distance, roadId=$roadId, laneId=$laneId, laneNum=$laneNum, gdLocusList=$gdLocusList, locusList=$locusList)" + } +} + diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XBaseData.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XBaseData.kt new file mode 100644 index 0000000000..d7df5b04f0 --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XBaseData.kt @@ -0,0 +1,9 @@ +package com.mogo.eagle.core.function.v2x.internal.data + +open class V2XBaseData { + + @JvmField + var code = -1 + @JvmField + var msg: String? = null +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XLocation.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XLocation.kt new file mode 100644 index 0000000000..3ce50a38f0 --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XLocation.kt @@ -0,0 +1,26 @@ +package com.mogo.eagle.core.function.v2x.internal.data + +import androidx.annotation.Keep +import java.io.Serializable + +@Keep +class V2XLocation: Serializable { + + companion object { + private const val serialVersionUID = -93L + } + + /** + * 经度 + */ + var lon: Double = 0.0 + + /** + * 纬度 + */ + var lat: Double = 0.0 + + override fun toString(): String { + return "V2XLocation(lon=$lon, lat=$lat)" + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XMarkerCardResult.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XMarkerCardResult.kt new file mode 100644 index 0000000000..61e4928e23 --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XMarkerCardResult.kt @@ -0,0 +1,815 @@ +package com.mogo.eagle.core.function.v2x.internal.data + +import androidx.annotation.Keep +import java.io.Serializable + +@Keep +class V2XMarkerCardResult: V2XBaseData(), Serializable { + + companion object { + private const val serialVersionUID = -92L + } + + /** + * 要查询的数据类型 + * CARD_TYPE_USER_DATA:用户相关数据 + * CARD_TYPE_ROAD_CONDITION:路况数据 + * CARD_TYPE_LIVE:正播相关数据 + */ + var dataType: List? = null + + /** + * 车聊聊数据集合 + */ + var carChat: List? = null + + /** + * 分享的音乐数据集合 + */ + var shareMusic: List? = null + + /** + * 新鲜事分享的数据集合 + */ + var noveltyInfo: List? = null + + /** + * 在线车辆数据集合 + */ + var onlineCar: List? = null + + /** + * 探路数据集合 + */ + var exploreWay: List? = null + + /** + * 服务端下发消息时间 + */ + var messageTime: Long = 0 + + /** + * 额外信息 + */ + var extras: Map? = null + + override fun toString(): String { + return "MarkerCardResult(dataType=$dataType, carChat=$carChat, shareMusic=$shareMusic, noveltyInfo=$noveltyInfo, onlineCar=$onlineCar, exploreWay=$exploreWay, messageTime=$messageTime, extras=$extras)" + } +} + +@Keep +class V2XMarkerCarChat: Serializable { + + companion object { + private const val serialVersionUID = -92L + } + + /** + * 卡片类型 + */ + var type: String? = null + + /** + * 地址信息 + */ + var location: V2XMarkerLocation? = null + + /** + * 用户信息 + */ + var userInfo: V2XMarkerUserInfo? = null + + override fun toString(): String { + return "V2XMarkerCarChat(type=$type, location=$location, userInfo=$userInfo)" + } +} + +@Keep +class V2XMarkerShareMusic: Serializable { + + companion object { + private const val serialVersionUID = -93L + } + + /** + * 事件类型 + */ + var type: String? = null + + /** + * 音乐专辑信息 + */ + var bookInfo: String? = null + + /** + * 歌曲ID + */ + var id = 0 + + /** + * 点赞数 + */ + var likeNumber = 0 + + /** + * 位置信息 + */ + var location: V2XMarkerLocation? = null + + /** + * 已弃用 + */ + var mediaId: String? = null + + /** + * 歌曲封面-已弃用 + */ + var mediaImg: String? = null + + /** + * 歌曲名字 + */ + var mediaName: String? = null + + /** + * 歌手名字 + */ + var mediaSinger: String? = null + + /** + * 播放地址 + */ + var mediaUrl: String? = null + + /** + * 分享文案 + */ + var shareContentText: String? = null + + /** + * 分享类型 + */ + var shareType = 0 + + /** + * 用户信息 + */ + var userInfo: V2XMarkerUserInfo? = null + + override fun toString(): String { + return "V2XMarkerShareMusic(bookInfo=$bookInfo, id=$id, likeNumber=$likeNumber, location=$location, mediaId=$mediaId, mediaImg=$mediaImg, mediaName=$mediaName, mediaSinger=$mediaSinger, mediaUrl=$mediaUrl, shareContentText=$shareContentText, shareType=$shareType, type=$type, userInfo=$userInfo)" + } +} + +/** + * 新鲜事儿Marker数据 + */ +@Keep +class V2XMarkerNoveltyInfo: Serializable { + + companion object { + private const val serialVersionUID = -93L + } + + /** + * 事件类型 + */ + var type: String? = null + + /** + * 车机唯一标识 + */ + var sn: String? = null + + /** + * 标记坐标 + */ + var location: V2XMarkerLocation? = null + + /** + * POI类型 + */ + var poiType: String? = null + + /** + * 新鲜事分享内容 + */ + var contentData: ContentData? = null + + @Keep + class ContentData: Serializable { + + companion object { + private const val serialVersionUID = -93L + } + + /** + * 信息ID + */ + var infoId: String? = null + + /** + * 分享内容 + */ + var content: String? = null + + /** + * 分享内容左上角图标 + */ + var iconUrl: String? = null + + /** + * 分享内容图片 + */ + var imgUrl: String? = null + + /** + * 点赞数 + */ + var likeNum: Long = 0 + + /** + * 标题 + */ + var title: String? = null + + /** + * 加油站油价 + */ + var gasPrices: String? = null + + /** + * 是否显示导航 + */ + var isDisplayNavigation = false + + /** + * 是否显示好友主页 + */ + var isDesplayHost = false + + /** + * 是否是新鲜的 + */ + var isFabulous = false + + /** + * 分享类型 + */ + var styleType: String? = null + + /** + * 上报类型: + * 1-用户上报 + * 2-后台上报 + * 3-三方上报 + */ + var uploadType: String? = null + + override fun toString(): String { + return "ContentData(content=$content, iconUrl=$iconUrl, imgUrl=$imgUrl, infoId=$infoId, likeNum=$likeNum, title=$title, gasPrices=$gasPrices, isDisplayNavigation=$isDisplayNavigation, isDesplayHost=$isDesplayHost, isFabulous=$isFabulous, styleType=$styleType, uploadType=$uploadType)" + } + } + + override fun toString(): String { + return "V2XMarkerNoveltyInfo(type=$type, sn=$sn, location=$location, poiType=$poiType, contentData=$contentData)" + } +} + +@Keep +class V2XMarkerOnlineCar: Serializable { + + companion object { + private const val serialVersionUID = -93L + } + + /** + * 事件类型 + */ + var type: String? = null + + /** + * 车辆位置 + */ + var location: V2XMarkerLocation? = null + + /** + * focus:false-未关注,true-关注 + */ + var focus: Boolean? = null + + /** + * 用户数据 + */ + var userInfo: V2XMarkerUserInfo? = null + + /** + * 车辆数据 + */ + var carInfo: V2XMarkerCarInfo? = null + + /** + * 车辆路线 + */ + var pois: List? = null + + /** + * 动态数据 + */ + var dynamicData: V2XMarkerDynamicData? = null + + /** + * 爱好数据集合 + */ + var hobbyData: V2XMarkerHobbyDatum? = null + + /** + * 活动范围数据集合 + */ + var activitiesScope: List? = null + + /** + * 匹配度 + */ + var compatibility = 0 + + override fun toString(): String { + return "V2XMarkerOnlineCar(type=$type, location=$location, focus=$focus, userInfo=$userInfo, carInfo=$carInfo, pois=$pois, dynamicData=$dynamicData, hobbyData=$hobbyData, activitiesScope=$activitiesScope, compatibility=$compatibility)" + } +} + +@Keep +class V2XMarkerExploreWay: Serializable { + + companion object { + private const val serialVersionUID = -93L + } + + /** + * 事件类型 + */ + var type: String? = null + + /** + * 信息ID + */ + var infoId: String? = null + + /** + * POI类型 + */ + var poiType: String? = null + + /** + * 车辆唯一标识 + */ + var sn: String? = null + + /** + * 位置信息 + */ + var location: V2XMarkerLocation? = null + + /** + * 车辆方位 + */ + var direction = 0 + + /** + * 是否可直播(1为可直播,0不可直播) + */ + var canLive: String? = "0" + + /** + * 是图片还是视频(1视频,0图片) + */ + var fileType = 0 + + /** + * 车辆详细地址 + */ + var addr: String? = null + + /** + * 事件下发的时间 + */ + var generateTime: Long = 0L + + /** + * 城市名称 + */ + var cityName: String? = null + + /** + * 距离 + */ + var distance = 0.0 + + /** + * 用户信息 + */ + var userInfo: V2XMarkerUserInfo? = null + + /** + * 视频地址和图片地址 + */ + var items: List? = null + + /** + * 上报类型: + * 1-用户上报 + * 2-后台上报 + * 3-三方上报 + */ + var uploadType: String? = null + + /** + * 是否是新鲜的 + */ + var isFabulous = false + + /** + * 需要用户判断是否拥堵 进行UGC问答 + */ + var infoCheckNode = 0 + + override fun toString(): String { + return "V2XMarkerExploreWay(infoId=$infoId, type=$type, poiType=$poiType, sn=$sn, location=$location, direction=$direction, canLive=$canLive, fileType=$fileType, addr=$addr, generateTime=$generateTime, cityName=$cityName, distance=$distance, userInfo=$userInfo, items=$items, uploadType=$uploadType, isFabulous=$isFabulous, infoCheckNode=$infoCheckNode)" + } +} + +@Keep +class V2XMarkerUserInfo: Serializable { + + companion object { + private const val serialVersionUID = -93L + } + + /** + * 自车车机唯一标识 + */ + var sn: String? = null + + /** + * 用户ID + */ + var userId: Long = 0 + + /** + * 用户昵称 + */ + var userName: String? = null + + /** + * 用户头像 + */ + var userHead: String? = null + + /** + * gender": "男|女|无(也可以0|1|2根据实际库存返回即可) + */ + var gender: String? = null + + /** + * 年龄段,可以为空,与车聊聊一致 + */ + var age: Int? = null + + /** + * 末次活跃周驾驶行为平均得分 + */ + var lastActiveweekAvgscore: String? = null + + /** + * 车辆安全标签 + */ + var safeLabel: String? = null + + /** + * 1-老司机 + * 2-安全驾驶 + * 3-危险驾驶 + */ + var safeLabelType = 0 + + override fun toString(): String { + return "V2XMarkerUserInfo(sn=$sn, userId=$userId, userName=$userName, userHead=$userHead, gender=$gender, age=$age, lastActiveweekAvgscore=$lastActiveweekAvgscore, safeLabel=$safeLabel, safeLabelType=$safeLabelType)" + } +} + +@Keep +class V2XMarkerCarInfo: Serializable { + + companion object { + private const val serialVersionUID = -93L + } + + /** + * 车品牌Logo资源链接 + */ + var carBrandLogoUrl: String? = null + + /** + * 车型名称 + */ + var carTypeName: String? = null + + /** + * 车类型: + * 0-普通车辆 + * 1-警车 + * 2-救护车 + * 3-失控车 + * 4-道路救援车 + */ + var vehicleType: Int = 0 + + /** + * 车辆直播相关信息 + */ + var carLiveInfo: CarLiveInfo? = null + + @Keep + class CarLiveInfo: Serializable { + + companion object { + private const val serialVersionUID = -93L + } + + /** + * rtmp视频直播地址rtmp:// + */ + var videoUrl: String? = null + + /** + * 直播频道【直播心跳接口参数】C_1 + */ + var videoChannel: String? = null + + /** + * 直播源sn + */ + var videoSn: String? = null + + override fun toString(): String { + return "CarLiveInfo(videoUrl=$videoUrl, videoChannel=$videoChannel, videoSn=$videoSn)" + } + } + + override fun toString(): String { + return "V2XMarkerCarInfo(carBrandLogoUrl=$carBrandLogoUrl, carTypeName=$carTypeName, vehicleType=$vehicleType, carLiveInfo=$carLiveInfo)" + } +} + +@Keep +class V2XMarkerCarPois: Serializable { + + companion object { + private const val serialVersionUID = -93L + } + + /** + * 位置信息,返回的值不为空并且长度为2的倍数 + */ + var coordinates: List<*>? = null + + /** + * 车的朝向角度 + */ + var angle = 0.0 + + /** + * 地区code + */ + var adcode: String? = null + + override fun toString(): String { + return "V2XMarkerCarPois(coordinates=$coordinates, angle=$angle, adcode=$adcode)" + } +} + +@Keep +class V2XMarkerDynamicData: Serializable { + + companion object { + private const val serialVersionUID = -93L + } + + /** + * QQ音乐,懒人听书,乐听头条 2 为书籍听书,3 为新闻,1 为qq音乐 + */ + var type = 0 + + /** + * qq音乐id,书的bookId + */ + var mediaId: String? = null + + /** + * qq音乐url 懒人听书为“” + */ + var mediaUrl: String? = null + + /** + * 歌曲名 ,当前播放书名,新闻标题内容 + */ + var mediaName: String? = null + + /** + * 演唱歌手,当前章节,新闻来源 + */ + var mediaSinger: String? = null + + /** + * 歌曲封面,书籍封面,新闻预览图 + */ + var mediaImg: String? = null + + /** + * 音乐类别,类似经典 ,流行只有qq特有 + */ + var mediaType: String? = null + + /** + * 音频总时长 + */ + var maxTime = 0 + + /** + * 懒人听书json串 + */ + var bookInfo: String? = null + + /** + * 当前播放时长,可以不加,播放进度单独独立出来 + */ + var curTime = 0 + + /** + * 是否是本地音频,只有qq音乐 + */ + var isLocalMedia = false + + /** + * 播放模式,顺序,单曲循环,随机 + */ + var mediaPlayMode = 0 + + /** + * 1 播放 2 缓冲 0 暂停/停止 -1 播放错误 + */ + var playState = 0 + + override fun toString(): String { + return "V2XMarkerDynamicData(type=$type, mediaId=$mediaId, mediaUrl=$mediaUrl, mediaName=$mediaName, mediaSinger=$mediaSinger, mediaImg=$mediaImg, mediaType=$mediaType, maxTime=$maxTime, bookInfo=$bookInfo, curTime=$curTime, isLocalMedia=$isLocalMedia, mediaPlayMode=$mediaPlayMode, playState=$playState)" + } +} + +@Keep +class V2XMarkerHobbyDatum: Serializable { + + companion object { + private const val serialVersionUID = -93L + } + + /** + * 最喜欢的两位歌手 + */ + var singerTop2: List? = null + + /** + * 最喜欢的两种音乐类型 + */ + var songTypeTop2: List? = null + + /** + * 最喜欢的资讯类型 + */ + var newsType: List? = null + + /** + * 最喜欢听的两本书 + */ + var listenBookTop2: List? = null + + /** + * 是否喜爱社交 + */ + var ifSociety: List? = null + + @Keep + class MarkerOnlineTag: Serializable { + + companion object { + private const val serialVersionUID = -93L + } + + /** + * 社交内容 + */ + var content: String? = null + + /** + * 是否选中 + */ + var isCheck: Boolean = false + + override fun toString(): String { + return "MarkerOnlineTag(content=$content, isCheck=$isCheck)" + } + } + + override fun toString(): String { + return "V2XMarkerHobbyDatum(singerTop2=$singerTop2, songTypeTop2=$songTypeTop2, newsType=$newsType, listenBookTop2=$listenBookTop2, ifSociety=$ifSociety)" + } +} + +@Keep +class V2XMarkerActivitiesScope: Serializable { + + companion object { + private const val serialVersionUID = -93L + } + + /** + * 活动范围内容 + */ + var content: String? = null + + /** + * 是否选中 + */ + var isCheck: Boolean = false + + override fun toString(): String { + return "V2XMarkerActivitiesScope(content=$content, isCheck=$isCheck)" + } +} + +/** + * 道路情报,V2X预警,地图道路事件POI,违章停车POI等 + */ +@Keep +class MarkerExploreWayItem: Serializable { + + companion object { + private const val serialVersionUID = -93L + } + + /** + * 缩略图 + */ + var thumbnail: String? = null + + /** + * 正式图 + */ + var url: String? = null + + /** + * 描述字段 + */ + var content: String? = null + + /** + * 违章停车人数 + */ + var illegalCount = 0.0 + + override fun toString(): String { + return "MarkerExploreWayItem(thumbnail=$thumbnail, url=$url, content=$content, illegalCount=$illegalCount)" + } +} + +@Keep +class V2XMarkerLocation: Serializable { + + companion object { + private const val serialVersionUID = -93L + } + + /** + * 纬度 + */ + var lat: Double = 0.0 + + /** + * 纬度 + */ + var lon: Double = 0.0 + + /** + * 车头角度,可以没有 + */ + var angle: Double = 0.0 + + /** + * 具体的位置信息 + */ + var address: String? = null + + override fun toString(): String { + return "V2XMarkerLocation(lat=$lat, lon=$lon, angle=$angle, address=$address)" + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XMarkerResponse.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XMarkerResponse.kt new file mode 100644 index 0000000000..790bd71b0a --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XMarkerResponse.kt @@ -0,0 +1,28 @@ +package com.mogo.eagle.core.function.v2x.internal.data + +import androidx.annotation.Keep +import com.elegant.network.BaseResp +import com.mogo.eagle.core.function.v2x.internal.data.V2XMarkerCardResult +import java.io.Serializable + +@Keep +class V2XMarkerResponse: BaseResp(), Serializable { + + companion object { + private const val serialVersionUID = -93L + } + + /** + * 响应的数据集 + */ + var result: V2XMarkerCardResult? = null + + /** + * TODO 不知道啥含义,可以忽略 + */ + var sign: String? = null + + override fun toString(): String { + return "V2XMarkerResponse(result=$result, sign=$sign)" + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XOptimalRoute.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XOptimalRoute.kt new file mode 100644 index 0000000000..dd27d302af --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XOptimalRoute.kt @@ -0,0 +1,56 @@ +package com.mogo.eagle.core.function.v2x.internal.data + +import androidx.annotation.Keep +import com.mogo.eagle.core.function.v2x.internal.data.V2XLocation +import java.io.Serializable + +/** + * 最优路线推荐 + */ +@Keep +class V2XOptimalRoute: Serializable { + + companion object { + private const val serialVersionUID = -93L + } + + /** + * 自车SN + */ + var sn: String? = null + + /** + * 道路ID + */ + var road_id: String? = null + + /** + * 车道ID-2D路段 + */ + var current_lane_id: String? = null + + /** + * 车道号:中心线编号为0, 中心线右侧编号为负数,3车道通行Road的车道编号,0,-1,-2,-3 + */ + var current_lane_num = 0 + + /** + * 最优车道平均速度 + */ + var most_speed = 0.0 + + /** + * 车道号:中心线编号为0, 中心线右侧编号为负数,3车道通行Road的车道编号,0,-1,-2,-3 + */ + var most_lane_num = 0 + + /** + * Wgs84坐标系,线性经纬度轨迹列表 + */ + var locus_list: List? = null + + /** + * 高德坐标系Gcj,线性经纬度轨迹列表 + */ + var gd_locus_list: List? = null +} diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XWarningTarget.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XWarningTarget.kt new file mode 100644 index 0000000000..8173032600 --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XWarningTarget.kt @@ -0,0 +1,176 @@ +package com.mogo.eagle.core.function.v2x.internal.data + +import androidx.annotation.Keep +import com.mogo.eagle.core.function.v2x.internal.data.V2XLocation +import java.io.Serializable + +/** + * 预警目标物数据模型 + */ +@Keep +class V2XWarningTarget: Serializable { + + companion object { + private const val serialVersionUID = -93L + } + + /** + * 事件类型 + * 行人-1 + * 自行车-2 + * 摩托车-4 + * 骑行车辆-11 + */ + var type = 0 + + /** + * 目标物纬度 + */ + var lat = 0.0 + + /** + * 目标物经度 + */ + var lon = 0.0 + + /** + * 目标物颜色 + */ + var targetColor: String? = null + + /** + * 目标物距自车距离 + */ + var distance = 0.0 + + /** + * 预测碰撞点位置-纬度 + */ + var collisionLat = 0.0 + + /** + * 预测碰撞点位置-经度 + */ + var collisionLon = 0.0 + + /** + * 目标物行驶朝向 + */ + var angle = 0.0 + + /** + * 目标物方位 + * 方位:前 后 左 右 + */ + var direction = 0 + + /** + * 目标物速度 + */ + var speed = 0f + + /** + * 停止线经纬度 + */ + var stopLines: List? = null + + /** + * 自车到停止线距离 + */ + var stopLineDistance = 0.0 + + /** + * 道路唯一标识 + */ + var roadId: String? = null + + /** + * 车道唯一标识 + */ + var laneId: String? = null + + /** + * 识别物体唯一标识 + */ + var uuid: String? = null + + /** + * 红绿灯颜色 + */ + var color: String? = null + + /** + * 车ID 暂不使用 + */ + var carId: String? = null + + /** + * 预警文案 + */ + var warningContent: String? = null + + /** + * 车头朝向 + */ + var heading = 0.0 + + /** + * 系统时间 暂时没用 + */ + var systemTime: Long = 0 + + /** + * 定位卫星时间 暂时没用 + */ + var satelliteTime: Long = 0 + + /** + * 预警蒙层等展示时长 + */ + var showTime: Long = 0 + + /** + * 设计划线宽度与道路同宽 + */ + var roadwidth = 0f + + /** + * 自组字段, tts播报 + */ + var tts: String? = null + + /** + * 自车位置 + */ + var carLocation: V2XLocation? = null + + override fun toString(): String { + return "V2XWarningEntity{" + + "type=" + type + + ", lat=" + lat + + ", lon=" + lon + + ", targetColor='" + targetColor + '\'' + + ", distance=" + distance + + ", collisionLat=" + collisionLat + + ", collisionLon=" + collisionLon + + ", angle=" + angle + + ", direction=" + direction + + ", speed=" + speed + + ", stopLines=" + stopLines + + ", stopLineDistance=" + stopLineDistance + + ", roadId='" + roadId + '\'' + + ", laneId='" + laneId + '\'' + + ", uuid='" + uuid + '\'' + + ", color='" + color + '\'' + + ", carId='" + carId + '\'' + + ", warningContent='" + warningContent + '\'' + + ", heading=" + heading + + ", systemTime=" + systemTime + + ", satelliteTime=" + satelliteTime + + ", showTime=" + showTime + + ", roadwidth=" + roadwidth + + ", tts='" + tts + '\'' + + ", carLocation=" + carLocation + + '}' + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/event/V2XEvent.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/event/V2XEvent.kt new file mode 100644 index 0000000000..5743940cfd --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/event/V2XEvent.kt @@ -0,0 +1,68 @@ +package com.mogo.eagle.core.function.v2x.internal.event + +import com.mogo.eagle.core.function.v2x.internal.data.V2XAdvanceWarning +import com.mogo.eagle.core.function.v2x.internal.data.V2XMarkerCardResult +import com.mogo.eagle.core.function.v2x.internal.data.V2XMarkerResponse +import com.mogo.eagle.core.function.v2x.internal.data.V2XOptimalRoute +import com.mogo.eagle.core.function.v2x.internal.data.V2XWarningTarget +import roadwork.Road.RW_PB + +sealed class V2XEvent { + + /** + * 长链-路口碰撞预警、盲区预警等通用Bean + */ + class ForwardsWarning(val type: Int = 404000, val data: V2XAdvanceWarning): V2XEvent() { + override fun toString(): String { + return "ForwardsWarning(type=$type, data=$data)" + } + } + + /** + * 长链-最优推荐线种 + */ + class OptimalRoute(val type: Int = 402000, val data: V2XOptimalRoute): V2XEvent() { + override fun toString(): String { + return "OptimalRoute(type=$type, data=$data)" + } + } + + /** + * 长链-预警目标物 + */ + class Warning(val type: Int = 401018, val data: V2XWarningTarget): V2XEvent() { + override fun toString(): String { + return "Warning(type=$type, data=$data)" + } + } + + /** + * 长链-道路事件 + */ + class Road(val type: Int = 401012, val data: V2XMarkerCardResult): V2XEvent() { + override fun toString(): String { + return "Road(type=$type, data=$data)" + } + } + + /** + * 长链-道路事件云识别 + */ + class RoadAI(val type: Int = 503000, val data: RW_PB): V2XEvent() { + + override fun toString(): String { + return "RoadAI(type=$type, data=$data)" + } + } + + + /** + * 短链-道路标记事件 + */ + class Marker(val data: V2XMarkerResponse): V2XEvent() { + + override fun toString(): String { + return "Marker(data=$data)" + } + } +} diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/executor/Executors.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/executor/Executors.kt new file mode 100755 index 0000000000..aed7f4549c --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/executor/Executors.kt @@ -0,0 +1,35 @@ +package com.mogo.eagle.core.function.v2x.internal.executor + +import java.util.concurrent.* +import java.util.concurrent.atomic.AtomicLong +import kotlin.math.max +import kotlin.math.min + + +internal object Executors { + + private val group: ThreadGroup by lazy { + ThreadGroup("v2x-group") + } + + private val CPU_CORE_COUNT by lazy { + Runtime.getRuntime().availableProcessors() + } + + private val DEFAULT_CORE_COUNT by lazy { + (max(2, min(CPU_CORE_COUNT - 1, 6)) * 3) + 1 + } + + private const val DEFAULT_MAX_COUNT_4_IO = 128 + + val IO by lazy { + val idGenerator = AtomicLong(0) + ThreadPoolExecutor( + DEFAULT_CORE_COUNT, DEFAULT_MAX_COUNT_4_IO, 30, TimeUnit.SECONDS, LinkedBlockingDeque() + ) { r -> + Thread(group, r).apply { + name = "io-thread-${idGenerator.getAndIncrement()}" + } + } + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/http/V2XRefreshModel.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/http/V2XRefreshModel.kt new file mode 100644 index 0000000000..2b57db3ab8 --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/http/V2XRefreshModel.kt @@ -0,0 +1,84 @@ +package com.mogo.eagle.core.function.v2x.internal.http + +import com.elegant.network.utils.GsonUtil +import com.elegant.network.utils.SignUtil +import com.elegant.utils.CommonUtils +import com.mogo.cloud.network.RetrofitFactory +import com.mogo.eagle.core.function.v2x.internal.V2XManager +import com.mogo.eagle.core.function.v2x.internal.config.V2XConfig +import com.mogo.eagle.core.function.v2x.internal.data.V2XLocation +import com.mogo.eagle.core.function.v2x.internal.data.V2XMarkerResponse +import com.mogo.eagle.core.function.v2x.internal.http.api.V2XApiService +import com.mogo.eagle.core.function.v2x.internal.http.body.V2XRefreshEntity +import com.mogo.eagle.core.function.v2x.internal.http.callback.IV2XRefreshCallback +import com.mogo.eagle.core.function.v2x.internal.utils.DeviceUtils +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.Disposable +import io.reactivex.schedulers.Schedulers + +internal class V2XRefreshModel { + + companion object { + + fun querySnapshot( + longitude: Double, + latitude: Double, + callback: IV2XRefreshCallback? + ): Disposable? { + val config = V2XManager.getConfig() + val retrofit = RetrofitFactory.getInstance(config.baseUrl) ?: return null + return retrofit + .create(V2XApiService::class.java) + .querySnapshotSync(buildParams(longitude, latitude, config)) + .subscribeOn(Schedulers.from(config.executor)) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ data -> + if (data == null) { + callback?.onFail("returned data is null.") + return@subscribe + } + if (data.code != 0 && data.code != 200) { + callback?.onFail("code:${data.code}, msg: ${data.msg}") + } else { + callback?.onSuccess(data) + } + }, { + callback?.onFail(it.message) + }) + } + + private fun buildParams( + longitude: Double, + latitude: Double, + config: V2XConfig + ): Map = mutableMapOf().apply { + putAll(config.staticParams.let { + val handled = mutableMapOf() + it.asIterable().forEach { itx -> + val value = itx.value + if (value != null) { + handled[itx.key] = value + } + } + handled + }) + this["netType"] = CommonUtils.getNetworkType(config.context) + this["cellId"] = DeviceUtils.getCellId(config.context) ?: "" + this["sn"] = config.aiCloudConfig.sn + this["ticket"] = config.aiCloudConfig.token + this["sig"] = SignUtil.createSign(this, "JGjZx6") + this["data"] = GsonUtil.jsonFromObject(V2XRefreshEntity().apply { + limit = 999 + location = V2XLocation().also { + it.lat = latitude + it.lon = longitude + } + radius = 1000 + dataType.add("CARD_TYPE_ROAD_CONDITION") + viewPush = true + }) + } + } + + +} diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/http/api/V2XApiService.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/http/api/V2XApiService.kt new file mode 100644 index 0000000000..a8f3266337 --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/http/api/V2XApiService.kt @@ -0,0 +1,14 @@ +package com.mogo.eagle.core.function.v2x.internal.http.api + +import com.mogo.eagle.core.function.v2x.internal.data.V2XMarkerResponse +import io.reactivex.Maybe +import retrofit2.http.FieldMap +import retrofit2.http.FormUrlEncoded +import retrofit2.http.POST + +internal interface V2XApiService { + + @FormUrlEncoded + @POST("/yycp-launcherSnapshot/launcherSnapshot/querySnapshotSync") + fun querySnapshotSync(@FieldMap parameters: Map): Maybe +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/http/body/V2XRefreshEntity.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/http/body/V2XRefreshEntity.kt new file mode 100644 index 0000000000..82d5661ab5 --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/http/body/V2XRefreshEntity.kt @@ -0,0 +1,39 @@ +package com.mogo.eagle.core.function.v2x.internal.http.body + +import androidx.annotation.Keep +import com.mogo.eagle.core.function.v2x.internal.data.V2XLocation + +/** + * 刷新地图信息接口 + */ +@Keep +internal class V2XRefreshEntity { + + @JvmField + var dataType: MutableList = mutableListOf() // 要查询的类型 + + @JvmField + var limit = 50 // 请求数量 + + @JvmField + var radius = 2000 // 地理围栏半径(米) + + @JvmField + var location // 坐标 + : V2XLocation? = null + @JvmField + var sn: String? = null + + @JvmField + var onlyFocus // 是否仅查询已关注的好友 + = false + @JvmField + var onlySameCity // 是否仅查询注册城市相同的同城用户 + = false + @JvmField + var viewPush // 是否走V2X通道 ,true-401011,false -401001 + = false + @JvmField + var onlyRealUser = false + +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/http/callback/IV2XRefreshCallback.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/http/callback/IV2XRefreshCallback.kt new file mode 100644 index 0000000000..3fb17ffef7 --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/http/callback/IV2XRefreshCallback.kt @@ -0,0 +1,11 @@ +package com.mogo.eagle.core.function.v2x.internal.http.callback + +/** + * 刷新回调 + */ +internal interface IV2XRefreshCallback { + + fun onSuccess(result: T) + + fun onFail(msg: String?) +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/logger/Logger.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/logger/Logger.kt new file mode 100644 index 0000000000..c230c13abf --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/logger/Logger.kt @@ -0,0 +1,24 @@ +package com.mogo.eagle.core.function.v2x.internal.logger + +import android.util.Log + +internal object Logger { + + var loggable: Boolean = false + + fun v(tag: String, msg: String) = if (loggable) Log.v(tag, msg) else 0 + + fun d(tag: String, msg: String) = if (loggable) Log.d(tag, msg) else 0 + + fun i(tag: String, msg: String) = if (loggable) Log.i(tag, msg) else 0 + + fun w(tag: String, msg: String) = if (loggable) Log.w(tag, msg) else 0 + + fun e(tag: String, msg: String, t: Throwable? = null) = if (loggable) { + if (t == null) { + Log.e(tag, msg) + } else { + Log.e(tag, msg, t) + } + } else 0 +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_401012.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_401012.kt new file mode 100644 index 0000000000..94fa71b532 --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_401012.kt @@ -0,0 +1,27 @@ +package com.mogo.eagle.core.function.v2x.internal.socket + +import com.mogo.cloud.socket.IMogoCloudSocketOnMessageListener +import com.mogo.eagle.core.function.v2x.internal.V2XManager +import com.mogo.eagle.core.function.v2x.internal.callback.IV2XCallback +import com.mogo.eagle.core.function.v2x.internal.data.V2XMarkerCardResult +import com.mogo.eagle.core.function.v2x.internal.event.V2XEvent +import com.mogo.eagle.core.function.v2x.internal.logger.Logger + +internal class V2XMessageListener_401012(val cbs: Iterable?): IMogoCloudSocketOnMessageListener { + + override fun target(msgType: Int): Class = V2XMarkerCardResult::class.java + + override fun onMsgReceived(msgType: Int, data: V2XMarkerCardResult?) { + if (msgType != 401012) { + return + } + if (data == null) { + Logger.i(V2XManager.TAG, "V2XMessageListener_401012:message is null!") + return + } + Logger.i(V2XManager.TAG, "V2XMessageListener_401012:$data") + cbs?.forEach { + it.onAck(V2XEvent.Road(data = data)) + } + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_401018.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_401018.kt new file mode 100644 index 0000000000..b9f8c8747d --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_401018.kt @@ -0,0 +1,27 @@ +package com.mogo.eagle.core.function.v2x.internal.socket + +import com.mogo.cloud.socket.IMogoCloudSocketOnMessageListener +import com.mogo.eagle.core.function.v2x.internal.V2XManager +import com.mogo.eagle.core.function.v2x.internal.callback.IV2XCallback +import com.mogo.eagle.core.function.v2x.internal.event.V2XEvent +import com.mogo.eagle.core.function.v2x.internal.data.V2XWarningTarget +import com.mogo.eagle.core.function.v2x.internal.logger.Logger + +internal class V2XMessageListener_401018(val cbs: Iterable?): IMogoCloudSocketOnMessageListener { + + override fun target(msgType: Int): Class = V2XWarningTarget::class.java + + override fun onMsgReceived(msgType: Int, data: V2XWarningTarget?) { + if (msgType != 401018) { + return + } + if (data == null) { + Logger.i(V2XManager.TAG, "V2XMessageListener_401018:message is null!") + return + } + Logger.i(V2XManager.TAG, "V2XMessageListener_401018:$data") + cbs?.forEach { + it.onAck(V2XEvent.Warning(data = data)) + } + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_402000.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_402000.kt new file mode 100644 index 0000000000..c968eb1e5a --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_402000.kt @@ -0,0 +1,27 @@ +package com.mogo.eagle.core.function.v2x.internal.socket + +import com.mogo.cloud.socket.IMogoCloudSocketOnMessageListener +import com.mogo.eagle.core.function.v2x.internal.V2XManager +import com.mogo.eagle.core.function.v2x.internal.callback.IV2XCallback +import com.mogo.eagle.core.function.v2x.internal.data.V2XOptimalRoute +import com.mogo.eagle.core.function.v2x.internal.event.V2XEvent +import com.mogo.eagle.core.function.v2x.internal.logger.Logger + +internal class V2XMessageListener_402000(val cbs: Iterable?): IMogoCloudSocketOnMessageListener { + + override fun target(msgType: Int): Class = V2XOptimalRoute::class.java + + override fun onMsgReceived(msgType: Int, data: V2XOptimalRoute?) { + if (msgType != 402000) { + return + } + if (data == null) { + Logger.i(V2XManager.TAG, "V2XMessageListener_402000:message is null!") + return + } + Logger.i(V2XManager.TAG, "V2XMessageListener_402000:$data") + cbs?.forEach { + it.onAck(V2XEvent.OptimalRoute(data = data)) + } + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_404000.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_404000.kt new file mode 100644 index 0000000000..4d9c046429 --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_404000.kt @@ -0,0 +1,27 @@ +package com.mogo.eagle.core.function.v2x.internal.socket + +import com.mogo.cloud.socket.IMogoCloudSocketOnMessageListener +import com.mogo.eagle.core.function.v2x.internal.V2XManager +import com.mogo.eagle.core.function.v2x.internal.callback.IV2XCallback +import com.mogo.eagle.core.function.v2x.internal.data.V2XAdvanceWarning +import com.mogo.eagle.core.function.v2x.internal.event.V2XEvent +import com.mogo.eagle.core.function.v2x.internal.logger.Logger + +internal class V2XMessageListener_404000(val cbs: Iterable?): IMogoCloudSocketOnMessageListener { + + override fun target(msgType: Int): Class = V2XAdvanceWarning::class.java + + override fun onMsgReceived(msgType: Int, data: V2XAdvanceWarning?) { + if (msgType != 404000) { + return + } + if (data == null) { + Logger.i(V2XManager.TAG, "V2XMessageListener_404000:message is null!") + return + } + Logger.i(V2XManager.TAG, "V2XMessageListener_404000:$data") + cbs?.forEach { + it.onAck(V2XEvent.ForwardsWarning(data = data)) + } + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_503000.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_503000.kt new file mode 100644 index 0000000000..cbfeca79df --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_503000.kt @@ -0,0 +1,27 @@ +package com.mogo.eagle.core.function.v2x.internal.socket + +import com.mogo.cloud.socket.IMogoCloudSocketOnMessageListener +import com.mogo.eagle.core.function.v2x.internal.V2XManager +import com.mogo.eagle.core.function.v2x.internal.callback.IV2XCallback +import com.mogo.eagle.core.function.v2x.internal.event.V2XEvent.RoadAI +import com.mogo.eagle.core.function.v2x.internal.logger.Logger +import roadwork.Road.RW_PB + +internal class V2XMessageListener_503000(val cbs: Iterable?): IMogoCloudSocketOnMessageListener { + + override fun target(msgType: Int): Class = RW_PB::class.java + + override fun onMsgReceived(msgType: Int, data: RW_PB?) { + if (msgType != 503000) { + return + } + if (data == null) { + Logger.i(V2XManager.TAG, "V2XMessageListener_503000:message is null!") + return + } + Logger.i(V2XManager.TAG, "V2XMessageListener_503000:$data") + cbs?.forEach { + it.onAck(RoadAI(data = data)) + } + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/utils/DeviceUtils.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/utils/DeviceUtils.kt new file mode 100644 index 0000000000..b7c6dc3312 --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/utils/DeviceUtils.kt @@ -0,0 +1,46 @@ +package com.mogo.eagle.core.function.v2x.internal.utils + +import android.Manifest +import android.annotation.SuppressLint +import android.content.Context +import android.content.pm.PackageManager +import android.telephony.CellLocation +import android.telephony.TelephonyManager +import android.telephony.cdma.CdmaCellLocation +import android.telephony.gsm.GsmCellLocation +import java.lang.Exception + +internal class DeviceUtils { + + companion object { + + @SuppressLint("MissingPermission") + @JvmStatic + fun getCellId(context: Context): String? { + val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager + val pm = context.packageManager + val accessCoarseLocationPermission = PackageManager.PERMISSION_GRANTED == + pm.checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION, context.packageName) + val accessFineLocationPermission = PackageManager.PERMISSION_GRANTED == + pm.checkPermission(Manifest.permission.ACCESS_FINE_LOCATION, context.packageName) + if (!accessCoarseLocationPermission || !accessFineLocationPermission) return "noPermission" + var location: CellLocation? = null + try { + location = tm.cellLocation + } catch (e: Exception) { + e.printStackTrace() + } + if (location != null) { + // Gsm网络 , 联通移动的网络属于这一套 + if (location is GsmCellLocation) { + val cellid = location.cid + return cellid.toString() + // Cdma网络 , 电信网络属于这一种 + } else if (location is CdmaCellLocation) { + return location.baseStationId.toString() + } + } + return null + } + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/utils/DistanceUtils.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/utils/DistanceUtils.kt new file mode 100644 index 0000000000..43f59ca92c --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/utils/DistanceUtils.kt @@ -0,0 +1,52 @@ +package com.mogo.eagle.core.function.v2x.internal.utils + +import kotlin.math.asin +import kotlin.math.cos +import kotlin.math.sin +import kotlin.math.sqrt + +internal class DistanceUtils { + + companion object { + + /** + * @param lon1 + * @param lat1 + * @param lon2 + * @param lat2 + * @return 两坐标的距离 单位:米(M) + */ + fun calculateLineDistance(lon1: Double, lat1: Double, lon2: Double, lat2: Double): Float { + return try { + var var2 = lon1 + var var4 = lat1 + var var6 = lon2 + var var8 = lat2 + var2 *= 0.01745329251994329 + var4 *= 0.01745329251994329 + var6 *= 0.01745329251994329 + var8 *= 0.01745329251994329 + val var10 = sin(var2) + val var12 = sin(var4) + val var14 = cos(var2) + val var16 = cos(var4) + val var18 = sin(var6) + val var20 = sin(var8) + val var22 = cos(var6) + val var24 = cos(var8) + val var28 = DoubleArray(3) + val var29 = DoubleArray(3) + var28[0] = var16 * var14 + var28[1] = var16 * var10 + var28[2] = var12 + var29[0] = var24 * var22 + var29[1] = var24 * var18 + var29[2] = var20 + (asin(sqrt((var28[0] - var29[0]) * (var28[0] - var29[0]) + (var28[1] - var29[1]) * (var28[1] - var29[1]) + (var28[2] - var29[2]) * (var28[2] - var29[2])) / 2.0) * 1.27420015798544E7).toFloat() + } catch (var26: Throwable) { + var26.printStackTrace() + 0.0f + } + } + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-v2x/src/main/proto/road.proto b/core/function-impl/mogo-core-function-v2x/src/main/proto/road.proto new file mode 100644 index 0000000000..71c087aa5b --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/proto/road.proto @@ -0,0 +1,59 @@ +syntax = "proto2"; + +package roadwork; + +message RW_PB { + required Roadwork_PB roadwork =1; + optional Header header = 2; +} + +message Roadwork_PB{ + optional string id = 1; // 对应id + required int32 score = 2; // 置信度 + required int64 detect_time = 3; // 发送时间 + required int32 poi_type = 4; // poi 类型 + optional int32 type = 5; // 事件类型 + required Center_PB center = 6; // 中心点坐标 + repeated GPSPoint_PB polygon = 7; // 多边形范围 + repeated Road_PB road = 8; // 车道集合信息 +} + +message GPSPoint_PB { + required double lat = 1; // 纬度 + required double lon = 2; // 经度 + optional double hgt = 3; // 高程 +} + +message Road_PB{ + required string road_id = 1; // 路段id + required string lane_no = 2; // 车道号 + required string tile_id = 3; // 瓦片id + required int32 bearing = 4; // 方向角,正北是0度 顺时针 +} + +message Center_PB{ + required Road_PB road = 1; // 道路信息 + required GPSPoint_PB point = 2; // 坐标 +} + +// header + +message Time { + optional uint32 sec = 1; // 秒 + optional uint32 nsec = 2; // 纳秒 +} + +message Header { + // Sequence number for each message. Each module maintains its own counter for + // sequence_num, always starting from 1 on boot. + optional uint32 seq = 1; + + // Message publishing time in seconds. + optional Time stamp = 2; + + // frame id + optional string frame_id = 3; + + // Module name. + optional string module_name = 4; +} diff --git a/gradle.properties b/gradle.properties index 6b7dbc5b19..6cc519e950 100644 --- a/gradle.properties +++ b/gradle.properties @@ -157,8 +157,7 @@ MOGO_OCH_NOOP_VERSION=2.0.66 MOGO_OCH_TAXI_VERSION=2.0.66 # mogoAiCloud sdk services MOGO_AICLOUD_SERVICES_SDK_VERSION=2.1.16.10 -# v2x-sdk -MOGO_V2X_SDK_VERSION=1.4.3.20 + ################# 旧版本架构模块版本 #################